From 1ea65f0285d7022ce20ef84d4e35e3c94bcb3fbd Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 27 Mar 2012 22:56:02 -0700
Subject: CHUI-51 WIP notifications routig code cleanup phase 1, removal of
 most of llnotificationhandler

---
 indra/llui/llnotifications.cpp                     |  50 +++---
 indra/llui/llnotifications.h                       |  21 +--
 indra/llui/llnotificationtemplate.h                |  10 +-
 indra/newview/llbrowsernotification.cpp            |   5 +-
 indra/newview/llchiclet.cpp                        |   9 +-
 indra/newview/llfloaternotificationsconsole.cpp    |   2 +-
 indra/newview/llfloateroutbox.cpp                  |  51 +-----
 indra/newview/llfloateroutbox.h                    |   2 +-
 indra/newview/llimhandler.cpp                      |  82 +++++-----
 indra/newview/llnearbychathandler.cpp              |   8 +-
 indra/newview/llnearbychathandler.h                |   3 +-
 indra/newview/llnotificationalerthandler.cpp       |  99 +++++-------
 indra/newview/llnotificationgrouphandler.cpp       |  50 +++---
 indra/newview/llnotificationhandler.h              | 143 ++++++-----------
 indra/newview/llnotificationhandlerutil.cpp        | 126 ++-------------
 indra/newview/llnotificationhinthandler.cpp        |  26 +---
 indra/newview/llnotificationmanager.cpp            |  90 ++---------
 indra/newview/llnotificationmanager.h              |  11 +-
 indra/newview/llnotificationofferhandler.cpp       | 172 ++++++++++-----------
 indra/newview/llnotificationscripthandler.cpp      |  89 +++++------
 indra/newview/llnotificationtiphandler.cpp         | 117 ++++++--------
 indra/newview/llscreenchannel.h                    |  14 +-
 indra/newview/llsyswellwindow.cpp                  |  11 +-
 indra/newview/lltoastgroupnotifypanel.cpp          |   2 +-
 indra/newview/lltoastgroupnotifypanel.h            |   2 +-
 indra/newview/lltoastnotifypanel.cpp               |   4 +-
 indra/newview/lltoastnotifypanel.h                 |   4 +-
 indra/newview/llviewermessage.cpp                  |   2 -
 indra/newview/llviewerwindow.cpp                   |   8 +-
 .../newview/skins/default/xui/en/notifications.xml |  22 +++
 30 files changed, 435 insertions(+), 800 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index d232e27ef2..038a86d20a 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -409,7 +409,9 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 	mUnique(p.unique.isProvided()),
 	mPriority(p.priority),
 	mPersist(p.persist),
-	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name())
+	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()),
+	mLogToChat(p.log_to_chat),
+	mLogToIM(p.log_to_im)
 {
 	if (p.sound.isProvided()
 		&& LLUI::sSettingGroups["config"]->controlExists(p.sound))
@@ -886,6 +888,24 @@ std::string LLNotification::getURL() const
 	return (mTemplatep ? url : "");
 }
 
+bool LLNotification::canLogToChat() const
+{
+	return mTemplatep->mLogToChat;
+}
+
+bool LLNotification::canLogToIM() const
+{
+	return mTemplatep->mLogToIM;
+}
+
+bool LLNotification::hasFormElements() const
+{
+	return mTemplatep->mForm->getNumElements() != 0;
+}
+
+
+
+
 // =========================================================
 // LLNotificationChannel implementation
 // ---
@@ -1051,20 +1071,6 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 	return abortProcessing;
 }
 
-/* static */
-LLNotificationChannelPtr LLNotificationChannel::buildChannel(const std::string& name, 
-															 const std::string& parent,
-															 LLNotificationFilter filter, 
-															 LLNotificationComparator comparator)
-{
-	// note: this is not a leak; notifications are self-registering.
-	// This factory helps to prevent excess deletions by making sure all smart
-	// pointers to notification channels come from the same source
-	new LLNotificationChannel(name, parent, filter, comparator);
-	return LLNotifications::instance().getChannel(name);
-}
-
-
 LLNotificationChannel::LLNotificationChannel(const std::string& name, 
 											 const std::string& parent,
 											 LLNotificationFilter filter, 
@@ -1272,19 +1278,19 @@ void LLNotifications::createDefaultChannels()
 {
 	// now construct the various channels AFTER loading the notifications,
 	// because the history channel is going to rewrite the stored notifications file
-	LLNotificationChannel::buildChannel("Enabled", "",
+	new LLNotificationChannel("Enabled", "",
 		!boost::bind(&LLNotifications::getIgnoreAllNotifications, this));
-	LLNotificationChannel::buildChannel("Expiration", "Enabled",
+	new LLNotificationChannel("Expiration", "Enabled",
 		boost::bind(&LLNotifications::expirationFilter, this, _1));
-	LLNotificationChannel::buildChannel("Unexpired", "Enabled",
+	new LLNotificationChannel("Unexpired", "Enabled",
 		!boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
-	LLNotificationChannel::buildChannel("Unique", "Unexpired",
+	new LLNotificationChannel("Unique", "Unexpired",
 		boost::bind(&LLNotifications::uniqueFilter, this, _1));
-	LLNotificationChannel::buildChannel("Ignore", "Unique",
+	new LLNotificationChannel("Ignore", "Unique",
 		filterIgnoredNotifications);
-	LLNotificationChannel::buildChannel("VisibilityRules", "Ignore",
+	new LLNotificationChannel("VisibilityRules", "Ignore",
 		boost::bind(&LLNotifications::isVisibleByRules, this, _1));
-	LLNotificationChannel::buildChannel("Visible", "VisibilityRules",
+	new LLNotificationChannel("Visible", "VisibilityRules",
 		&LLNotificationFilters::includeEverything);
 
 	// create special persistent notification channel
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 462d69be2e..f83365a97d 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -513,7 +513,10 @@ public:
 	std::string getURL() const;
 	S32 getURLOption() const;
     S32 getURLOpenExternally() const;
-	
+	bool canLogToChat() const;
+	bool canLogToIM() const;
+	bool hasFormElements() const;
+
 	const LLNotificationFormPtr getForm();
 
 	const LLDate getExpiration() const
@@ -791,13 +794,6 @@ typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr;
 // of a queue with notifications being added to different nonequivalent copies. So we 
 // make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it.
 // 
-// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to 
-// do something like:
-//		LLNotificationChannel::buildChannel("name", "parent"...);
-// This returns an LLNotificationChannelPtr, which you can store, or
-// you can then retrieve the channel by using the registry:
-//		LLNotifications::instance().getChannel("name")...
-//
 class LLNotificationChannel : 
 	boost::noncopyable, 
 	public LLNotificationChannelBase
@@ -822,20 +818,13 @@ public:
 	
 	std::string summarize();
 
-	// factory method for constructing these channels; since they're self-registering,
-	// we want to make sure that you can't use new to make them
-	static LLNotificationChannelPtr buildChannel(const std::string& name, const std::string& parent,
-						LLNotificationFilter filter=LLNotificationFilters::includeEverything, 
-						LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
-	
-protected:
     // Notification Channels have a filter, which determines which notifications
 	// will be added to this channel. 
 	// Channel filters cannot change.
 	// Channels have a protected constructor so you can't make smart pointers that don't 
 	// come from our internal reference; call NotificationChannel::build(args)
 	LLNotificationChannel(const std::string& name, const std::string& parent,
-						  LLNotificationFilter filter, LLNotificationComparator comparator);
+						  LLNotificationFilter filter, LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
 
 private:
 	std::string mName;
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index fb50c9c123..1df7205b23 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -170,7 +170,9 @@ struct LLNotificationTemplate
 	struct Params : public LLInitParam::Block<Params>
 	{
 		Mandatory<std::string>			name;
-		Optional<bool>					persist;
+		Optional<bool>					persist,
+										log_to_im,
+										log_to_chat;
 		Optional<std::string>			functor,
 										icon,
 										label,
@@ -190,6 +192,8 @@ struct LLNotificationTemplate
 		Params()
 		:	name("name"),
 			persist("persist", false),
+			log_to_im("log_to_im", false),
+			log_to_chat("log_to_chat", false),
 			functor("functor"),
 			icon("icon"),
 			label("label"),
@@ -291,6 +295,10 @@ struct LLNotificationTemplate
 	LLUUID mSoundEffect;
 	// List of tags that rules can match against.
 	std::list<std::string> mTags;
+
+	// inject these notifications into chat/IM streams
+	bool mLogToChat;
+	bool mLogToIM;
 };
 
 #endif //LL_LLNOTIFICATION_TEMPLATE_H
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index 6e77d1e336..9e608d2c8b 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -35,11 +35,8 @@
 
 using namespace LLNotificationsUI;
 
-bool LLBrowserNotification::processNotification(const LLSD& notify)
+bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
 {
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-	if (!notification) return false;
-
 	LLUUID media_id = notification->getPayload()["media_id"].asUUID();
 	LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);
 	if (media_instance)
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index aabab0ccb9..9f19f8dd1c 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -339,9 +339,9 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
 , mUreadSystemNotifications(0)
 {
 	// connect counter handlers to the signals
-	connectCounterUpdatersToSignal("notify");
-	connectCounterUpdatersToSignal("groupnotify");
-	connectCounterUpdatersToSignal("offer");
+	connectCounterUpdatersToSignal("Notify");
+	connectCounterUpdatersToSignal("Group Notify");
+	connectCounterUpdatersToSignal("Offer");
 
 	// ensure that notification well window exists, to synchronously
 	// handle toast add/delete events.
@@ -350,8 +350,7 @@ LLNotificationChiclet::LLNotificationChiclet(const Params& p)
 
 void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type)
 {
-	LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
-	LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
+	LLNotificationsUI::LLEventHandler* n_handler = dynamic_cast<LLNotificationsUI::LLEventHandler*>(LLNotifications::instance().getChannel(notification_type).get());
 	if(n_handler)
 	{
 		n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index 2681d4b34d..90dbabebfb 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -57,7 +57,7 @@ LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChann
 {
 	mChannelPtr = LLNotifications::instance().getChannel(p.name);
 	mChannelRejectsPtr = LLNotificationChannelPtr(
-		LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(),
+		new LLNotificationChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(),
 											!boost::bind(mChannelPtr->getFilter(), _1)));
 	buildFromFile( "panel_notifications_channel.xml");
 }
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 540f977305..2a2b231b53 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -44,14 +44,12 @@
 #include "llviewernetwork.h"
 #include "llwindowshade.h"
 
-#define USE_WINDOWSHADE_DIALOGS	0
-
 
 ///----------------------------------------------------------------------------
 /// LLOutboxNotification class
 ///----------------------------------------------------------------------------
 
-bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& notify)
+bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify)
 {
 	LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox");
 	
@@ -516,52 +514,11 @@ void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
 	updateView();
 }
 
-void LLFloaterOutbox::showNotification(const LLSD& notify)
+void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
 {
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-	
-	if (!notification)
-	{
-		llerrs << "Unable to find outbox notification!" << notify.asString() << llendl;
-		
-		return;
-	}
-
-#if USE_WINDOWSHADE_DIALOGS
-
-	if (mWindowShade)
-	{
-		delete mWindowShade;
-	}
-	
-	LLRect floater_rect = getLocalRect();
-	floater_rect.mTop -= getHeaderHeight();
-	floater_rect.stretch(-5, 0);
-	
-	LLWindowShade::Params params;
-	params.name = "notification_shade";
-	params.rect = floater_rect;
-	params.follows.flags = FOLLOWS_ALL;
-	params.modal = true;
-	params.can_close = false;
-	params.shade_color = LLColor4::white % 0.25f;
-	params.text_color = LLColor4::white;
-	
-	mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
-	
-	addChild(mWindowShade);
-	mWindowShade->show(notification);
-	
-#else
-	
-	LLNotificationsUI::LLEventHandler * handler =
-		LLNotificationsUI::LLNotificationManager::instance().getHandlerForNotification("alertmodal");
-	
-	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler *>(handler);
+	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
 	llassert(sys_handler);
 	
-	sys_handler->processNotification(notify);
-	
-#endif
+	sys_handler->processNotification(notification);
 }
 
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index 18baccf1c9..a91d8c1139 100644
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -64,7 +64,7 @@ public:
 						   EAcceptance* accept,
 						   std::string& tooltip_msg);
 	
-	void showNotification(const LLSD& notify);
+	void showNotification(const LLNotificationPtr& notification);
 
 	BOOL handleHover(S32 x, S32 y, MASK mask);
 	void onMouseLeave(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index cd71da7393..a92c4fa387 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -37,10 +37,9 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLIMHandler::LLIMHandler(e_notification_type type, const LLSD& id)
+LLIMHandler::LLIMHandler()
+:	LLSysHandler("IM Notifications", "notifytoast")
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel();
 }
@@ -59,62 +58,51 @@ void LLIMHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLIMHandler::processNotification(const LLSD& notify)
+bool LLIMHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(!mChannel)
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel->getVisible())
 	{
 		initChannel();
 	}
 
-	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
-	{
-		LLSD substitutions = notification->getSubstitutions();
-
-		// According to comments in LLIMMgr::addMessage(), if we get message
-		// from ourselves, the sender id is set to null. This fixes EXT-875.
-		LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
-		if (avatar_id.isNull())
-			avatar_id = gAgentID;
-
-		LLToastIMPanel::Params im_p;
-		im_p.notification = notification;
-		im_p.avatar_id = avatar_id;
-		im_p.from = substitutions["FROM"].asString();
-		im_p.time = substitutions["TIME"].asString();
-		im_p.message = substitutions["MESSAGE"].asString();
-		im_p.session_id = substitutions["SESSION_ID"].asUUID();
-
-		LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
-
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.session_id = im_p.session_id;
-		p.notification = notification;
-		p.panel = im_box;
-		p.can_be_stored = false;
-		p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
-		if(channel)
-			channel->addToast(p);
-
-		// send a signal to the counter manager;
-		mNewNotificationSignal();
-	}
-	else if (notify["sigtype"].asString() == "delete")
-	{
-		mChannel->killToastByNotificationID(notification->getID());
-	}
+	LLSD substitutions = notification->getSubstitutions();
+
+	// According to comments in LLIMMgr::addMessage(), if we get message
+	// from ourselves, the sender id is set to null. This fixes EXT-875.
+	LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
+	if (avatar_id.isNull())
+		avatar_id = gAgentID;
+
+	LLToastIMPanel::Params im_p;
+	im_p.notification = notification;
+	im_p.avatar_id = avatar_id;
+	im_p.from = substitutions["FROM"].asString();
+	im_p.time = substitutions["TIME"].asString();
+	im_p.message = substitutions["MESSAGE"].asString();
+	im_p.session_id = substitutions["SESSION_ID"].asUUID();
+
+	LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
+
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.session_id = im_p.session_id;
+	p.notification = notification;
+	p.panel = im_box;
+	p.can_be_stored = false;
+	p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+	if(channel)
+		channel->addToast(p);
+
+	// send a signal to the counter manager;
+	mNewNotificationSignal();
+	
 	return false;
 }
 
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 240a7c7a35..269b42bbe9 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -445,10 +445,8 @@ void LLNearbyChatScreenChannel::arrangeToasts()
 //-----------------------------------------------------------------------------------------------
 boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat"));
 
-LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
+LLNearbyChatHandler::LLNearbyChatHandler()
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	LLNearbyChatScreenChannel::Params p;
 	p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
@@ -614,10 +612,6 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	}
 }
 
-void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
-{
-}
-
 
 //-----------------------------------------------------------------------------------------------
 // LLNearbyChatToast
diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h
index b0e4f62d51..a5034ac1cb 100644
--- a/indra/newview/llnearbychathandler.h
+++ b/indra/newview/llnearbychathandler.h
@@ -37,14 +37,13 @@ namespace LLNotificationsUI{
 class LLNearbyChatHandler : public LLChatHandler
 {
 public:
-	LLNearbyChatHandler(e_notification_type type,const LLSD& id);
+	LLNearbyChatHandler();
 	virtual ~LLNearbyChatHandler();
 
 
 	virtual void processChat(const LLChat& chat_msg, const LLSD &args);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 
 	static boost::scoped_ptr<LLEventPump> sChatWatcher;
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index cae7d02fed..e6239534f7 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -40,10 +40,10 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false)
+LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal) 
+:	LLSysHandler(name, notification_type),
+	mIsModal(is_modal)
 {
-	mType = type;
-
 	LLScreenChannelBase::Params p;
 	p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));
 	p.display_toasts_always = true;
@@ -68,79 +68,58 @@ void LLAlertHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLAlertHandler::processNotification(const LLSD& notify)
+bool LLAlertHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(!mChannel)
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel->getVisible())
 	{
 		initChannel();
 	}
 
-	if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load")
+	if (notification->canLogToIM() && notification->hasFormElements())
 	{
-		if (LLHandlerUtil::canSpawnSessionAndLogToIM(notification))
-		{
-			const std::string name = LLHandlerUtil::getSubstitutionName(notification);
-
-			LLUUID from_id = notification->getPayload()["from_id"];
-
-			// firstly create session...
-			LLHandlerUtil::spawnIMSession(name, from_id);
-
-			// ...then log message to have IM Well notified about new message
-			LLHandlerUtil::logToIMP2P(notification);
-		}
-
-		LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.notification = notification;
-		p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
-		p.enable_hide_btn = false;
-		p.can_fade = false;
-		p.is_modal = mIsModal;
-		p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
-
-		// Show alert in middle of progress view (during teleport) (EXT-1093)
-		LLProgressView* progress = gViewerWindow->getProgressView();
-		LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
-		mChannel->updatePositionAndSize(rc);
-
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
-		if(channel)
-			channel->addToast(p);
-	}
-	else if (notify["sigtype"].asString() == "change")
-	{
-		LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
-		if(channel)
-			channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
-	}
-	else
-	{
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
-		if(channel)
-			channel->killToastByNotificationID(notification->getID());
+		const std::string name = LLHandlerUtil::getSubstitutionName(notification);
+
+		LLUUID from_id = notification->getPayload()["from_id"];
+
+		// firstly create session...
+		LLHandlerUtil::spawnIMSession(name, from_id);
+
+		// ...then log message to have IM Well notified about new message
+		LLHandlerUtil::logToIMP2P(notification);
 	}
+
+	LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.notification = notification;
+	p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
+	p.enable_hide_btn = false;
+	p.can_fade = false;
+	p.is_modal = mIsModal;
+	p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
+
+	// Show alert in middle of progress view (during teleport) (EXT-1093)
+	LLProgressView* progress = gViewerWindow->getProgressView();
+	LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
+	mChannel->updatePositionAndSize(rc);
+
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+	if(channel)
+		channel->addToast(p);
+	
 	return false;
 }
 
-//--------------------------------------------------------------------------
-
-void LLAlertHandler::onDeleteToast(LLToast* toast)
+void LLAlertHandler::onChange( LLNotificationPtr notification )
 {
+	LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+	if(channel)
+		channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
 }
-
-//--------------------------------------------------------------------------
-
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 9b7fdaef82..2ce51fa094 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -37,15 +37,14 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
+LLGroupHandler::LLGroupHandler()
+:	LLSysHandler("Group Notifications", "groupnotify")
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel();
 	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
 	if(channel)
-		channel->setOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));
+		channel->addOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));
 }
 
 //--------------------------------------------------------------------------
@@ -62,48 +61,37 @@ void LLGroupHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLGroupHandler::processNotification(const LLSD& notify)
+bool LLGroupHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(!mChannel)
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel->getVisible())
 	{
 		initChannel();
 	}
 	
-	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
-	{
-		LLHandlerUtil::logGroupNoticeToIMGroup(notification);
+	LLHandlerUtil::logGroupNoticeToIMGroup(notification);
+
+	LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.notification = notification;
+	p.panel = notify_box;
+	p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
 
-		LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.notification = notification;
-		p.panel = notify_box;
-		p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+	if(channel)
+		channel->addToast(p);
 
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
-		if(channel)
-			channel->addToast(p);
+	// send a signal to the counter manager
+	mNewNotificationSignal();
 
-		// send a signal to the counter manager
-		mNewNotificationSignal();
+	LLGroupActions::refresh_notices();
 
-		LLGroupActions::refresh_notices();
-	}
-	else if (notify["sigtype"].asString() == "delete")
-	{
-		mChannel->killToastByNotificationID(notification->getID());
-	}
 	return false;
 }
 
@@ -123,7 +111,7 @@ void LLGroupHandler::onRejectToast(LLUUID& id)
 {
 	LLNotificationPtr notification = LLNotifications::instance().find(id);
 
-	if (notification && LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this)
+	if (notification && mItems.find(notification) != mItems.end())
 	{
 		LLNotifications::instance().cancel(notification);
 	}
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 23dbb6b047..ff9371f7df 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -30,7 +30,7 @@
 
 #include "llwindow.h"
 
-//#include "llnotificationsutil.h"
+#include "llnotifications.h"
 #include "llchannelmanager.h"
 #include "llchat.h"
 #include "llinstantmessage.h"
@@ -40,20 +40,6 @@ class LLIMFloater;
 
 namespace LLNotificationsUI
 {
-// ENotificationType enumerates all possible types of notifications that could be met
-// 
-typedef enum e_notification_type
-{
-	NT_NOTIFY, 
-	NT_NOTIFYTIP,
-	NT_GROUPNOTIFY,
-	NT_IMCHAT, 
-	NT_GROUPCHAT, 
-	NT_NEARBYCHAT, 
-	NT_ALERT,
-	NT_ALERTMODAL,
-	NT_OFFER
-} ENotificationType;
 
 /**
  * Handler of notification events.
@@ -95,7 +81,7 @@ public:
 	boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); }
 
 protected:
-	virtual void onDeleteToast(LLToast* toast)=0;
+	virtual void onDeleteToast(LLToast* toast) {}
 
 	// arrange handler's channel on a screen
 	// is necessary to unbind a moment of creation of a channel and a moment of positioning of it
@@ -104,8 +90,6 @@ protected:
 	virtual void initChannel()=0;
 
 	LLScreenChannelBase*	mChannel;
-	e_notification_type		mType;
-
 };
 
 // LLSysHandler and LLChatHandler are more specific base classes
@@ -115,13 +99,18 @@ protected:
 /**
  * Handler for system notifications.
  */
-class LLSysHandler : public LLEventHandler
+class LLSysHandler : public LLEventHandler, public LLNotificationChannel
 {
 public:
-	LLSysHandler();
+	LLSysHandler(const std::string& name, const std::string& notification_type);
 	virtual ~LLSysHandler() {};
 
-	virtual bool processNotification(const LLSD& notify)=0;
+	// base interface functions
+	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel) mChannel->killToastByNotificationID(p->getID());}
+
+	virtual bool processNotification(const LLNotificationPtr& notify)=0;
 
 protected :
 	static void init();
@@ -149,13 +138,11 @@ public:
 class LLIMHandler : public LLSysHandler
 {
 public:
-	LLIMHandler(e_notification_type type, const LLSD& id);
+	LLIMHandler();
 	virtual ~LLIMHandler();
 
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
-
 protected:
+	bool processNotification(const LLNotificationPtr& p);
 	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 };
@@ -167,14 +154,13 @@ protected:
 class LLTipHandler : public LLSysHandler
 {
 public:
-	LLTipHandler(e_notification_type type, const LLSD& id);
+	LLTipHandler();
 	virtual ~LLTipHandler();
 
 	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void onRejectToast(const LLUUID& id);
 	virtual void initChannel();
 };
@@ -186,11 +172,12 @@ protected:
 class LLScriptHandler : public LLSysHandler
 {
 public:
-	LLScriptHandler(e_notification_type type, const LLSD& id);
+	LLScriptHandler();
 	virtual ~LLScriptHandler();
 
+	virtual void onDelete(LLNotificationPtr p);
 	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void onDeleteToast(LLToast* toast);
@@ -207,11 +194,11 @@ protected:
 class LLGroupHandler : public LLSysHandler
 {
 public:
-	LLGroupHandler(e_notification_type type, const LLSD& id);
+	LLGroupHandler();
 	virtual ~LLGroupHandler();
 	
 	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void onDeleteToast(LLToast* toast);
@@ -227,16 +214,16 @@ protected:
 class LLAlertHandler : public LLSysHandler
 {
 public:
-	LLAlertHandler(e_notification_type type, const LLSD& id);
+	LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);
 	virtual ~LLAlertHandler();
 
-	void setAlertMode(bool is_modal) { mIsModal = is_modal; }
+	/*virtual*/ void onChange(LLNotificationPtr p);
+	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
 
 	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 
 	bool	mIsModal;
@@ -249,11 +236,12 @@ protected:
 class LLOfferHandler : public LLSysHandler
 {
 public:
-	LLOfferHandler(e_notification_type type, const LLSD& id);
+	LLOfferHandler();
 	virtual ~LLOfferHandler();
 
 	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	/*virtual*/ void onDelete(LLNotificationPtr notification);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void onDeleteToast(LLToast* toast);
@@ -266,84 +254,54 @@ protected:
 /**
  * Handler for UI hints.
  */
-class LLHintHandler : public LLSingleton<LLHintHandler>
+class LLHintHandler : public LLNotificationChannel
 {
 public:
-	LLHintHandler();
-	virtual ~LLHintHandler();
+	LLHintHandler() : LLNotificationChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"))
+	{}
+	virtual ~LLHintHandler() {}
 
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	/*virtual*/ void onAdd(LLNotificationPtr p);
+	/*virtual*/ void onChange(LLNotificationPtr p);
+	/*virtual*/ void onDelete(LLNotificationPtr p);
 };
 
 /**
  * Handler for browser notifications
  */
-class LLBrowserNotification : public LLSingleton<LLBrowserNotification>
+class LLBrowserNotification : public LLNotificationChannel
 {
 public:
-	virtual bool processNotification(const LLSD& notify);
+	LLBrowserNotification()
+	: LLNotificationChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"))
+	{}
+	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	bool processNotification(const LLNotificationPtr& p);
 };
 	
 /**
  * Handler for outbox notifications
  */
-class LLOutboxNotification : public LLSingleton<LLOutboxNotification>
+class LLOutboxNotification : public LLNotificationChannel
 {
 public:
-	virtual bool processNotification(const LLSD& notify);
+	LLOutboxNotification()
+	:	LLNotificationChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"))
+	{}
+	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	bool processNotification(const LLNotificationPtr& p);
 };
 	
 class LLHandlerUtil
 {
 public:
-	/**
-	 * Checks sufficient conditions to log notification message to IM session.
-	 */
-	static bool canLogToIM(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks sufficient conditions to log notification message to nearby chat session.
-	 */
-	static bool canLogToNearbyChat(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks sufficient conditions to spawn IM session.
-	 */
-	static bool canSpawnIMSession(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks sufficient conditions to add notification toast panel IM floater.
-	 */
-	static bool canAddNotifPanelToIM(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks whether notification can be used multiple times or not.
-	 */
-	static bool isNotificationReusable(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks if passed notification can create IM session and be written into it.
-	 *
-	 * This method uses canLogToIM() & canSpawnIMSession().
-	 */
-	static bool canSpawnSessionAndLogToIM(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks if passed notification can create toast.
-	 */
-	static bool canSpawnToast(const LLNotificationPtr& notification);
-
 	/**
 	 * Determines whether IM floater is opened.
 	 */
 	static bool isIMFloaterOpened(const LLNotificationPtr& notification);
 
-	/**
-	* Determines whether IM floater is focused.
-	*/
-	static bool isIMFloaterFocused(const LLNotificationPtr& notification);
-
 	/**
 	 * Writes notification message to IM session.
 	 */
@@ -406,13 +364,6 @@ public:
 	 */
 	static void decIMMesageCounter(const LLNotificationPtr& notification);
 
-private:
-
-	/**
-	 * Find IM floater based on "from_id"
-	 */
-	static LLIMFloater* findIMFloater(const LLNotificationPtr& notification);
-
 };
 
 }
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 1b767e80d4..dca7fda151 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -54,7 +54,8 @@ void LLSysHandler::init()
 	sExclusiveNotificationGroups.push_back(online_offline_group);
 }
 
-LLSysHandler::LLSysHandler()
+LLSysHandler::LLSysHandler(const std::string& name, const std::string& notification_type)
+:	LLNotificationChannel(name, "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
 {
 	if(sExclusiveNotificationGroups.empty())
 	{
@@ -110,119 +111,9 @@ void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)
 	}
 }
 
-const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
-		REVOKED_MODIFY_RIGHTS("RevokedModifyRights"),
-		OBJECT_GIVE_ITEM("ObjectGiveItem"),
-		OBJECT_GIVE_ITEM_UNKNOWN_USER("ObjectGiveItemUnknownUser"),
-						PAYMENT_RECEIVED("PaymentReceived"),
-						PAYMENT_SENT("PaymentSent"),
-						ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),
-						USER_GIVE_ITEM("UserGiveItem"),
-						INVENTORY_ACCEPTED("InventoryAccepted"),
-						INVENTORY_DECLINED("InventoryDeclined"),
-						OFFER_FRIENDSHIP("OfferFriendship"),
-						FRIENDSHIP_ACCEPTED("FriendshipAccepted"),
-						FRIENDSHIP_OFFERED("FriendshipOffered"),
-						FRIENDSHIP_ACCEPTED_BYME("FriendshipAcceptedByMe"),
-						FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"),
-						FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
-						SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
-						TELEPORT_OFFERED("TeleportOffered"),
-						TELEPORT_OFFER_SENT("TeleportOfferSent"),
-						IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip");
+const static std::string	OBJECT_GIVE_ITEM("ObjectGiveItem");
 
-
-// static
-bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
-{
-	return GRANTED_MODIFY_RIGHTS == notification->getName()
-			|| REVOKED_MODIFY_RIGHTS == notification->getName()
-			|| PAYMENT_RECEIVED == notification->getName()
-			|| PAYMENT_SENT == notification->getName()
-			|| OFFER_FRIENDSHIP == notification->getName()
-			|| FRIENDSHIP_OFFERED == notification->getName()
-			|| FRIENDSHIP_ACCEPTED == notification->getName()
-			|| FRIENDSHIP_ACCEPTED_BYME == notification->getName()
-			|| FRIENDSHIP_DECLINED_BYME == notification->getName()
-			|| SERVER_OBJECT_MESSAGE == notification->getName()
-			|| INVENTORY_ACCEPTED == notification->getName()
-			|| INVENTORY_DECLINED == notification->getName()
-			|| USER_GIVE_ITEM == notification->getName()
-			|| TELEPORT_OFFERED == notification->getName()
-			|| TELEPORT_OFFER_SENT == notification->getName()
-			|| IM_SYSTEM_MESSAGE_TIP == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
-{
-	return notification->getType() == "notifytip"
-			&&  FRIEND_ONLINE != notification->getName()
-			&& FRIEND_OFFLINE != notification->getName()
-			&& INVENTORY_ACCEPTED != notification->getName()
-			&& INVENTORY_DECLINED != notification->getName()
-			&& IM_SYSTEM_MESSAGE_TIP != notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
-{
-	return OFFER_FRIENDSHIP == notification->getName()
-			|| USER_GIVE_ITEM == notification->getName()
-			|| TELEPORT_OFFERED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
-{
-	return OFFER_FRIENDSHIP == notification->getName()
-					|| USER_GIVE_ITEM == notification->getName()
-					|| TELEPORT_OFFERED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification)
-{
-	return OFFER_FRIENDSHIP == notification->getName()
-		|| USER_GIVE_ITEM == notification->getName()
-		|| TELEPORT_OFFERED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification)
-{
-	return canLogToIM(notification) && canSpawnIMSession(notification);
-}
-
-// static
-bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification)
-{
-	if(INVENTORY_DECLINED == notification->getName() 
-		|| INVENTORY_ACCEPTED == notification->getName())
-	{
-		// return false for inventory accepted/declined notifications if respective IM window is open (EXT-5909)
-		return ! isIMFloaterOpened(notification);
-	}
-
-	if(FRIENDSHIP_ACCEPTED == notification->getName())
-	{
-		// don't show FRIENDSHIP_ACCEPTED if IM window is opened and focused - EXT-6441
-		return ! isIMFloaterFocused(notification);
-	}
-
-	if(OFFER_FRIENDSHIP == notification->getName()
-		|| USER_GIVE_ITEM == notification->getName()
-		|| TELEPORT_OFFERED == notification->getName())
-	{
-		// When ANY offer arrives, show toast, unless IM window is already open - EXT-5904
-		return ! isIMFloaterOpened(notification);
-	}
-
-	return true;
-}
-
-// static
-LLIMFloater* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification)
+static LLIMFloater* find_im_floater(const LLNotificationPtr& notification)
 {
 	LLUUID from_id = notification->getPayload()["from_id"];
 	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
@@ -234,7 +125,7 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
 {
 	bool res = false;
 
-	LLIMFloater* im_floater = findIMFloater(notification);
+	LLIMFloater* im_floater = find_im_floater(notification);
 	if (im_floater != NULL)
 	{
 		res = im_floater->getVisible() == TRUE;
@@ -243,11 +134,11 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
 	return res;
 }
 
-bool LLHandlerUtil::isIMFloaterFocused(const LLNotificationPtr& notification)
+static bool is_IM_floater_focused(const LLNotificationPtr& notification)
 {
 	bool res = false;
 
-	LLIMFloater* im_floater = findIMFloater(notification);
+	LLIMFloater* im_floater = find_im_floater(notification);
 	if (im_floater != NULL)
 	{
 		res = im_floater->hasFocus() == TRUE;
@@ -335,7 +226,7 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam
 void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
 {
 	// don't create IM p2p session with objects, it's necessary condition to log
-	if (notification->getName() != OBJECT_GIVE_ITEM)
+	//if (notification->getName() != OBJECT_GIVE_ITEM)
 	{
 		LLUUID from_id = notification->getPayload()["from_id"];
 
@@ -505,3 +396,4 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
 	arg["participant_unread"] = session->mParticipantUnreadMessageCount;
 	LLIMModel::getInstance()->mNewMsgSignal(arg);
 }
+
diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp
index f7163cb04f..47156a3915 100644
--- a/indra/newview/llnotificationhinthandler.cpp
+++ b/indra/newview/llnotificationhinthandler.cpp
@@ -33,26 +33,6 @@
 
 using namespace LLNotificationsUI;
 
-LLHintHandler::LLHintHandler()
-{
-}
-
-LLHintHandler::~LLHintHandler()
-{
-}
-
-bool LLHintHandler::processNotification(const LLSD& notify)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	std::string sigtype = notify["sigtype"].asString();
-	if (sigtype == "add" || sigtype == "load")
-	{
-		LLHints::show(notification);
-	}
-	else if (sigtype == "delete")
-	{
-		LLHints::hide(notification);
-	}
-	return false;
-}
+void LLHintHandler::onAdd(LLNotificationPtr p) { LLHints::show(p); }
+void LLHintHandler::onChange(LLNotificationPtr p) { LLHints::show(p); }
+void LLHintHandler::onDelete(LLNotificationPtr p) { LLHints::hide(p); }
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index 6105eff8ea..394ae2ac21 100644
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -41,7 +41,6 @@ using namespace LLNotificationsUI;
 //--------------------------------------------------------------------------
 LLNotificationManager::LLNotificationManager()
 {
-	mNotifyHandlers.clear();
 	init();
 }
 
@@ -53,88 +52,23 @@ LLNotificationManager::~LLNotificationManager()
 //--------------------------------------------------------------------------
 void LLNotificationManager::init()
 {
-	LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify"));
-	LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip"));
-	LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "groupnotify"));
-	LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
-	LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
-	LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast"));
-	LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer"));
-	LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"));
-	LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"));
-	LLNotificationChannel::buildChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"));
-  
-	LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1));
-	LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1));
-	LLNotifications::instance().getChannel("Outbox")->connectChanged(boost::bind(&LLOutboxNotification::processNotification, LLOutboxNotification::getInstance(), _1));
-
-	mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD()));
-	mNotifyHandlers["notifytip"] =  boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD()));
-	mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD()));
-	mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
-	mNotifyHandlers["alertmodal"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
-	static_cast<LLAlertHandler*>(mNotifyHandlers["alertmodal"].get())->setAlertMode(true);
-	mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler(NT_IMCHAT, LLSD()));
-	
-	mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD()));
-	mNotifyHandlers["offer"] = boost::shared_ptr<LLEventHandler>(new LLOfferHandler(NT_OFFER, LLSD()));
-}
-
-//--------------------------------------------------------------------------
-bool LLNotificationManager::onNotification(const LLSD& notify)
-{
-	LLSysHandler* handle = NULL;
-
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-	
-	if (!notification) 
-		return false;
-
-	std::string notification_type = notification->getType();
-	handle = static_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());
-
-	if(!handle)
-		return false;
+	new LLScriptHandler();
+	new LLTipHandler();
+	new LLGroupHandler();
+	new LLAlertHandler("Alerts", "alert", false);
+	new LLAlertHandler("AlertModal", "alertmodal", true);
+	new LLOfferHandler();
+	new LLHintHandler();
+	new LLBrowserNotification();
+	new LLOutboxNotification();
 	
-	return handle->processNotification(notify);
+	mChatHandler = boost::shared_ptr<LLNearbyChatHandler>(new LLNearbyChatHandler());
 }
 
 //--------------------------------------------------------------------------
 void LLNotificationManager::onChat(const LLChat& msg, const LLSD &args)
 {
-	// check ENotificationType argument
-	switch(args["type"].asInteger())
-	{
-	case NT_NEARBYCHAT:
-		{
-			LLNearbyChatHandler* handle = dynamic_cast<LLNearbyChatHandler*>(mNotifyHandlers["nearbychat"].get());
-
-			if(handle)
-				handle->processChat(msg, args);
-		}
-		break;
-	default: 	//no need to handle all enum types
-		break;
-	}
+	if(mChatHandler)
+		mChatHandler->processChat(msg, args);
 }
 
-//--------------------------------------------------------------------------
-LLEventHandler* LLNotificationManager::getHandlerForNotification(std::string notification_type) 
-{ 
-	std::map<std::string, boost::shared_ptr<LLEventHandler> >::iterator it = mNotifyHandlers.find(notification_type);
-
-	if(it != mNotifyHandlers.end())
-		return (*it).second.get();
-
-	return NULL;
-}
-
-//--------------------------------------------------------------------------
-
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
index 16e82e4cce..4d124e1379 100644
--- a/indra/newview/llnotificationmanager.h
+++ b/indra/newview/llnotificationmanager.h
@@ -56,20 +56,11 @@ public:
 	void init(void);
 	//TODO: combine processing and storage (*)
 	
-	// this method reacts on system notifications and calls an appropriate handler
-	bool onNotification(const LLSD& notification);
-
 	// this method reacts on chat notifications and calls an appropriate handler
 	void onChat(const LLChat& msg, const LLSD &args);
 
-	// get a handler for a certain type of notification
-	LLEventHandler* getHandlerForNotification(std::string notification_type);
-
-
 private:
-	//TODO (*)
-	std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers;
-	// cruft std::map<std::string, LLChatHandler*> mChatHandlers;
+	boost::shared_ptr<class LLNearbyChatHandler> mChatHandler;
 };
 
 }
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 68fd65be0f..8010417d43 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -40,17 +40,16 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLOfferHandler::LLOfferHandler(e_notification_type type, const LLSD& id)
+LLOfferHandler::LLOfferHandler()
+:	LLSysHandler("Offer", "offer")
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel();
 	mChannel->setControlHovering(true);
 
 	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
 	if(channel)
-		channel->setOnRejectToastCallback(boost::bind(&LLOfferHandler::onRejectToast, this, _1));
+		channel->addOnRejectToastCallback(boost::bind(&LLOfferHandler::onRejectToast, this, _1));
 }
 
 //--------------------------------------------------------------------------
@@ -67,126 +66,118 @@ void LLOfferHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLOfferHandler::processNotification(const LLSD& notify)
+bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(!mChannel)
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel->getVisible())
 	{
 		initChannel();
 	}
 
-	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
-	{
+	bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements();
 
+	if( notification->getPayload().has("give_inventory_notification")
+		&& !notification->getPayload()["give_inventory_notification"] )
+	{
+		// This is an original inventory offer, so add a script floater
+		LLScriptFloaterManager::instance().onAddNotification(notification->getID());
+	}
+	else
+	{
+		notification->setReusable(add_notif_to_im);
 
-		if( notification->getPayload().has("give_inventory_notification")
-			&& !notification->getPayload()["give_inventory_notification"] )
-		{
-			// This is an original inventory offer, so add a script floater
-			LLScriptFloaterManager::instance().onAddNotification(notification->getID());
-		}
-		else
+		LLUUID session_id;
+		if (add_notif_to_im)
 		{
-			notification->setReusable(LLHandlerUtil::isNotificationReusable(notification));
+			const std::string name = LLHandlerUtil::getSubstitutionName(notification);
 
-			LLUUID session_id;
-			if (LLHandlerUtil::canSpawnIMSession(notification))
-			{
-				const std::string name = LLHandlerUtil::getSubstitutionName(notification);
+			LLUUID from_id = notification->getPayload()["from_id"];
 
-				LLUUID from_id = notification->getPayload()["from_id"];
+			session_id = LLHandlerUtil::spawnIMSession(name, from_id);
+		}
 
-				session_id = LLHandlerUtil::spawnIMSession(name, from_id);
-			}
+		if (add_notif_to_im)
+		{
+			LLHandlerUtil::addNotifPanelToIM(notification);
+		}
 
-			bool show_toast = LLHandlerUtil::canSpawnToast(notification);
-			bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification);
-			if (add_notid_to_im)
+		if (notification->getPayload().has("SUPPRESS_TOAST")
+					&& notification->getPayload()["SUPPRESS_TOAST"])
+		{
+			LLNotificationsUtil::cancel(notification);
+		}
+		else if(!notification->canLogToIM() || !LLHandlerUtil::isIMFloaterOpened(notification))
+		{
+			LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+			// don't close notification on panel destroy since it will be used by IM floater
+			notify_box->setCloseNotificationOnDestroy(!add_notif_to_im);
+			LLToast::Params p;
+			p.notif_id = notification->getID();
+			p.notification = notification;
+			p.panel = notify_box;
+			p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
+			// we not save offer notifications to the syswell floater that should be added to the IM floater
+			p.can_be_stored = !add_notif_to_im;
+
+			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+			if(channel)
+				channel->addToast(p);
+
+			// if we not add notification to IM - add it to notification well
+			if (!add_notif_to_im)
 			{
-				LLHandlerUtil::addNotifPanelToIM(notification);
+				// send a signal to the counter manager
+				mNewNotificationSignal();
 			}
+		}
 
-			if (notification->getPayload().has("SUPPRESS_TOAST")
-						&& notification->getPayload()["SUPPRESS_TOAST"])
-			{
-				LLNotificationsUtil::cancel(notification);
-			}
-			else if(show_toast)
+		if (notification->canLogToIM())
+		{
+			// log only to file if notif panel can be embedded to IM and IM is opened
+			if (add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification))
 			{
-				LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
-				// don't close notification on panel destroy since it will be used by IM floater
-				notify_box->setCloseNotificationOnDestroy(!add_notid_to_im);
-				LLToast::Params p;
-				p.notif_id = notification->getID();
-				p.notification = notification;
-				p.panel = notify_box;
-				p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
-				// we not save offer notifications to the syswell floater that should be added to the IM floater
-				p.can_be_stored = !add_notid_to_im;
-
-				LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
-				if(channel)
-					channel->addToast(p);
-
-				// if we not add notification to IM - add it to notification well
-				if (!add_notid_to_im)
-				{
-					// send a signal to the counter manager
-					mNewNotificationSignal();
-				}
+				LLHandlerUtil::logToIMP2P(notification, true);
 			}
-
-			if (LLHandlerUtil::canLogToIM(notification))
+			else
 			{
-				// log only to file if notif panel can be embedded to IM and IM is opened
-				if (add_notid_to_im && LLHandlerUtil::isIMFloaterOpened(notification))
-				{
-					LLHandlerUtil::logToIMP2P(notification, true);
-				}
-				else
-				{
-					LLHandlerUtil::logToIMP2P(notification);
-				}
+				LLHandlerUtil::logToIMP2P(notification);
 			}
 		}
 	}
-	else if (notify["sigtype"].asString() == "delete")
+
+	return false;
+}
+
+/*virtual*/ void LLOfferHandler::onDelete(LLNotificationPtr notification)
+{
+	if( notification->getPayload().has("give_inventory_notification")
+		&& !notification->getPayload()["give_inventory_notification"] )
+	{
+		// Remove original inventory offer script floater
+		LLScriptFloaterManager::instance().onRemoveNotification(notification->getID());
+	}
+	else
 	{
-		if( notification->getPayload().has("give_inventory_notification")
-			&& !notification->getPayload()["give_inventory_notification"] )
+		if (notification->canLogToIM() 
+			&& notification->hasFormElements()
+			&& !LLHandlerUtil::isIMFloaterOpened(notification))
 		{
-			// Remove original inventory offer script floater
-			LLScriptFloaterManager::instance().onRemoveNotification(notification->getID());
-		}
-		else
-		{
-			if (LLHandlerUtil::canAddNotifPanelToIM(notification)
-					&& !LLHandlerUtil::isIMFloaterOpened(notification))
-			{
-				LLHandlerUtil::decIMMesageCounter(notification);
-			}
-			mChannel->killToastByNotificationID(notification->getID());
+			LLHandlerUtil::decIMMesageCounter(notification);
 		}
+		mChannel->killToastByNotificationID(notification->getID());
 	}
-
-	return false;
 }
 
 //--------------------------------------------------------------------------
 
 void LLOfferHandler::onDeleteToast(LLToast* toast)
 {
-	if (!LLHandlerUtil::canAddNotifPanelToIM(toast->getNotification()))
+	if (!toast->getNotification()->canLogToIM() || !toast->getNotification()->hasFormElements())
 	{
 		// send a signal to the counter manager
 		mDelNotificationSignal();
@@ -202,11 +193,10 @@ void LLOfferHandler::onRejectToast(LLUUID& id)
 {
 	LLNotificationPtr notification = LLNotifications::instance().find(id);
 
-	if (notification
-			&& LLNotificationManager::getInstance()->getHandlerForNotification(
-					notification->getType()) == this
-					// don't delete notification since it may be used by IM floater
-					&& !LLHandlerUtil::canAddNotifPanelToIM(notification))
+	if (notification 
+		&& mItems.find(notification) != mItems.end()
+		// don't delete notification since it may be used by IM floater
+		&& (!notification->canLogToIM() || !notification->hasFormElements()))
 	{
 		LLNotifications::instance().cancel(notification);
 	}
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index bbb4d03768..714f14963c 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -42,17 +42,16 @@ static const std::string SCRIPT_DIALOG_GROUP		("ScriptDialogGroup");
 static const std::string SCRIPT_LOAD_URL			("LoadWebPage");
 
 //--------------------------------------------------------------------------
-LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
+LLScriptHandler::LLScriptHandler()
+:	LLSysHandler("Notifications", "notify")
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel();
 	mChannel->setControlHovering(true);
 	
 	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
 	if(channel)
-		channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+		channel->addOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
 
 }
 
@@ -70,69 +69,65 @@ void LLScriptHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLScriptHandler::processNotification(const LLSD& notify)
+bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(!mChannel)
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel->getVisible())
 	{
 		initChannel();
 	}
 	
-	if(notify["sigtype"].asString() == "add")
+	if (notification->canLogToIM())
 	{
-		if (LLHandlerUtil::canLogToIM(notification))
-		{
-			LLHandlerUtil::logToIMP2P(notification);
-		}
+		LLHandlerUtil::logToIMP2P(notification);
+	}
 
-		if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
-		{
-			LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
-		}
-		else
-		{
-			LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
-
-			LLToast::Params p;
-			p.notif_id = notification->getID();
-			p.notification = notification;
-			p.panel = notify_box;	
-			p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
-
-			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
-			if(channel)
-			{
-				channel->addToast(p);
-			}
-
-			// send a signal to the counter manager
-			mNewNotificationSignal();
-		}
+	if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
+	{
+		LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
 	}
-	else if (notify["sigtype"].asString() == "delete")
+	else
 	{
-		if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
-		{
-			LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
-		}
-		else
+		LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+
+		LLToast::Params p;
+		p.notif_id = notification->getID();
+		p.notification = notification;
+		p.panel = notify_box;	
+		p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
 		{
-			mChannel->killToastByNotificationID(notification->getID());
+			channel->addToast(p);
 		}
+
+		// send a signal to the counter manager
+		mNewNotificationSignal();
 	}
+	
 	return false;
 }
 
+
+void LLScriptHandler::onDelete( LLNotificationPtr notification )
+{
+	if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
+	{
+		LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
+	}
+	else
+	{
+		mChannel->killToastByNotificationID(notification->getID());
+	}
+}
+
+
 //--------------------------------------------------------------------------
 
 void LLScriptHandler::onDeleteToast(LLToast* toast)
@@ -158,9 +153,7 @@ void LLScriptHandler::onRejectToast(LLUUID& id)
 {
 	LLNotificationPtr notification = LLNotifications::instance().find(id);
 
-	if (notification
-			&& LLNotificationManager::getInstance()->getHandlerForNotification(
-					notification->getType()) == this)
+	if (notification && mItems.find(notification) != mItems.end())
 	{
 		LLNotifications::instance().cancel(notification);
 	}
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index fb0891c4c5..0b0ac040cb 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -41,16 +41,15 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id)
+LLTipHandler::LLTipHandler()
+:	LLSysHandler("NotificationTips", "notifytip")
 {
-	mType = type;	
-
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel();
 
 	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
 	if(channel)
-		channel->setOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
+		channel->addOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
 }
 
 //--------------------------------------------------------------------------
@@ -67,90 +66,74 @@ void LLTipHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLTipHandler::processNotification(const LLSD& notify)
+bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(!mChannel)
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;	
-
 	// arrange a channel on a screen
 	if(!mChannel->getVisible())
 	{
 		initChannel();
 	}
 
-	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
+	// archive message in nearby chat
+	if (notification->canLogToChat())
 	{
-		// archive message in nearby chat
-		if (LLHandlerUtil::canLogToNearbyChat(notification))
-		{
-			LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
-
-			// don't show toast if Nearby Chat is opened
-			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-			LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
-			if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible())
-			{
-				return false;
-			}
-		}
+		LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
 
-		std::string session_name = notification->getPayload()["SESSION_NAME"];
-		const std::string name = notification->getSubstitutions()["NAME"];
-		if (session_name.empty())
-		{
-			session_name = name;
-		}
-		LLUUID from_id = notification->getPayload()["from_id"];
-		if (LLHandlerUtil::canLogToIM(notification))
-		{
-			LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
-					notification->getMessage(), from_id, from_id);
-		}
-
-		if (LLHandlerUtil::canSpawnIMSession(notification))
-		{
-			LLHandlerUtil::spawnIMSession(name, from_id);
-		}
-
-		// don't spawn toast for inventory accepted/declined offers if respective IM window is open (EXT-5909)
-		if (!LLHandlerUtil::canSpawnToast(notification))
+		// don't show toast if Nearby Chat is opened
+		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
+		LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
+		if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible())
 		{
 			return false;
 		}
+	}
 
-		LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
-
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.notification = notification;
-		p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
-		p.panel = notify_box;
-		p.is_tip = true;
-		p.can_be_stored = false;
-		
-		removeExclusiveNotifications(notification);
+	std::string session_name = notification->getPayload()["SESSION_NAME"];
+	const std::string name = notification->getSubstitutions()["NAME"];
+	if (session_name.empty())
+	{
+		session_name = name;
+	}
+	LLUUID from_id = notification->getPayload()["from_id"];
+	if (notification->canLogToIM())
+	{
+		LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
+				notification->getMessage(), from_id, from_id);
+	}
 
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
-		if(channel)
-			channel->addToast(p);
+	if (notification->canLogToIM() && notification->hasFormElements())
+	{
+		LLHandlerUtil::spawnIMSession(name, from_id);
 	}
-	else if (notify["sigtype"].asString() == "delete")
+
+	if (notification->canLogToIM() && LLHandlerUtil::isIMFloaterOpened(notification))
 	{
-		mChannel->killToastByNotificationID(notification->getID());
+		return false;
 	}
-	return false;
-}
 
-//--------------------------------------------------------------------------
-void LLTipHandler::onDeleteToast(LLToast* toast)
-{
+	LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
+
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.notification = notification;
+	p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
+	p.panel = notify_box;
+	p.is_tip = true;
+	p.can_be_stored = false;
+		
+	removeExclusiveNotifications(notification);
+
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+	if(channel)
+		channel->addToast(p);
+	
+
+	return false;
 }
 
 //--------------------------------------------------------------------------
@@ -159,9 +142,7 @@ void LLTipHandler::onRejectToast(const LLUUID& id)
 {
 	LLNotificationPtr notification = LLNotifications::instance().find(id);
 
-	if (notification
-			&& LLNotificationManager::getInstance()->getHandlerForNotification(
-					notification->getType()) == this)
+	if (notification && mItems.find(notification) != mItems.end())
 	{
 		LLNotifications::instance().cancel(notification);
 	}
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index c9f8855fe6..2ea5b8e546 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -228,16 +228,16 @@ public:
 
 	// Channel's signals
 	// signal on storing of faded toasts event
-	typedef boost::function<void (LLPanel* info_panel, const LLUUID id)> store_tost_callback_t;
-	typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_tost_signal_t;
-	store_tost_signal_t mOnStoreToast;	
-	boost::signals2::connection setOnStoreToastCallback(store_tost_callback_t cb) { return mOnStoreToast.connect(cb); }
+	typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_toast_signal_t;
+	boost::signals2::connection addOnStoreToastCallback(store_toast_signal_t::slot_type cb) { return mOnStoreToast.connect(cb); }
 	// signal on rejecting of a toast event
-	typedef boost::function<void (LLUUID id)> reject_tost_callback_t;
-	typedef boost::signals2::signal<void (LLUUID id)> reject_tost_signal_t;
-	reject_tost_signal_t mRejectToastSignal; boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mRejectToastSignal.connect(cb); }
+	typedef boost::signals2::signal<void (LLUUID id)> reject_toast_signal_t;
+	boost::signals2::connection addOnRejectToastCallback(reject_toast_signal_t::slot_type cb) { return mRejectToastSignal.connect(cb); }
 
 private:
+	store_toast_signal_t mOnStoreToast;	
+	reject_toast_signal_t mRejectToastSignal; 
+
 	struct ToastElem
 	{
 		LLUUID		id;
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 0cb6c85012..e8293ebe2b 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -437,9 +437,9 @@ LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
 : LLSysWellWindow(key)
 {
 	// init connections to the list's update events
-	connectListUpdaterToSignal("notify");
-	connectListUpdaterToSignal("groupnotify");
-	connectListUpdaterToSignal("offer");
+	connectListUpdaterToSignal("Notifications");
+	connectListUpdaterToSignal("Group Notifications");
+	connectListUpdaterToSignal("Offer");
 }
 
 // static
@@ -519,7 +519,7 @@ void LLNotificationWellWindow::initChannel()
 	LLSysWellWindow::initChannel();
 	if(mChannel)
 	{
-		mChannel->setOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
+		mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
 	}
 }
 
@@ -548,8 +548,7 @@ void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
 
 void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type)
 {
-	LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
-	LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
+	LLNotificationsUI::LLEventHandler* n_handler = dynamic_cast<LLNotificationsUI::LLEventHandler*>(LLNotifications::instance().getChannel(notification_type).get());
 	if(n_handler)
 	{
 		n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1));
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 75178a6ef8..707d2d9765 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -51,7 +51,7 @@
 
 const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 7;
 
-LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
+LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notification)
 :	LLToastPanel(notification),
 	mInventoryOffer(NULL)
 {
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
index 7794ec9f63..3b8b31eac1 100644
--- a/indra/newview/lltoastgroupnotifypanel.h
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -53,7 +53,7 @@ public:
 	// Non-transient messages.  You can specify non-default button
 	// layouts (like one for script dialogs) by passing various
 	// numbers in for "layout".
-	LLToastGroupNotifyPanel(LLNotificationPtr& notification);
+	LLToastGroupNotifyPanel(const LLNotificationPtr& notification);
 
 	/*virtual*/ ~LLToastGroupNotifyPanel();
 protected:
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index de305bf3d9..dc5cc88dc4 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -52,7 +52,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
 
 LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
 
-LLToastNotifyPanel::LLToastNotifyPanel(LLNotificationPtr& notification, const LLRect& rect, bool show_images) : 
+LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) : 
 LLToastPanel(notification),
 mTextBox(NULL),
 mInfoPanel(NULL),
@@ -536,7 +536,7 @@ void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id
 	}
 }
 
-void LLToastNotifyPanel::disableRespondedOptions(LLNotificationPtr& notification)
+void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification)
 {
 	LLSD response = notification->getResponse();
 	for (LLSD::map_const_iterator response_it = response.beginMap(); 
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index 57711b3d80..db517ec858 100644
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -60,7 +60,7 @@ public:
 	 * @deprecated if you intend to instantiate LLToastNotifyPanel - it's point to
 	 * implement right class for desired toast panel. @see LLGenericTipPanel as example.
 	 */
-	LLToastNotifyPanel(LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
+	LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
 	virtual ~LLToastNotifyPanel();
 	LLPanel * getControlPanel() { return mControlPanel; }
 
@@ -118,7 +118,7 @@ protected:
 	/**
 	 * Process response data. Will disable selected options
 	 */
-	void disableRespondedOptions(LLNotificationPtr& notification);
+	void disableRespondedOptions(const LLNotificationPtr& notification);
 
 	bool mIsTip;
 	bool mAddedDefaultBtn;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 3c6770df43..4f83d9096c 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2776,7 +2776,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				chat.mOwnerID = from_id;
 				LLSD args;
 				args["slurl"] = location;
-				args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
 
 				// Look for IRC-style emotes here so object name formatting is correct
 				std::string prefix = message.substr(0, 4);
@@ -3379,7 +3378,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		// pass owner_id to chat so that we can display the remote
 		// object inspect for an object that is chatting with you
 		LLSD args;
-		args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
 		chat.mOwnerID = owner_id;
 
 		if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e0653fec30..6d9b8b4eb3 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1548,11 +1548,11 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mViewerWindowListener(new LLViewerWindowListener(this)),
 	mProgressView(NULL)
 {
-	LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
-	LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
+	LLNotificationChannelPtr vw_alerts_channel(new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")));
+	LLNotificationChannelPtr vw_alerts_modal_channel(new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")));
 
-	LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
-	LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
+	vw_alerts_channel->connectChanged(&LLViewerWindow::onAlert);
+	vw_alerts_modal_channel->connectChanged(&LLViewerWindow::onAlert);
 	LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
 	llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index af75d49353..da83ffbab4 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -2904,6 +2904,7 @@ Would you like to trust this authority?
    icon="alertmodal.tga"
    name="GrantedModifyRights"
    persist="true"
+   log_to_im="true"   
    type="notify">
 [NAME] has given you permission to edit their objects.
   </notification>
@@ -2912,6 +2913,7 @@ Would you like to trust this authority?
    icon="alertmodal.tga"
    name="RevokedModifyRights"
    persist="true"
+   log_to_im="true"   
    type="notify">
 Your privilege to modify [NAME]&apos;s objects has been revoked
   </notification>
@@ -5161,6 +5163,8 @@ The string [STRING_NAME] is missing from strings.xml
   <notification
    icon="notifytip.tga"
    name="IMSystemMessageTip"
+   log_to_im="true"   
+   log_to_chat="true"   
    type="notifytip">
 [MESSAGE]
   </notification>
@@ -5205,6 +5209,7 @@ Topic: [SUBJECT], Message: [MESSAGE]
   <notification
    icon="notifytip.tga"
    name="FriendOnline"
+   log_to_chat="true"
    type="notifytip">
     <tag>friendship</tag>
 &lt;nolink&gt;[NAME]&lt;/nolink&gt; is Online
@@ -5213,6 +5218,7 @@ Topic: [SUBJECT], Message: [MESSAGE]
   <notification
    icon="notifytip.tga"
    name="FriendOffline"
+   log_to_chat="true"
    type="notifytip">
     <tag>friendship</tag>
 &lt;nolink&gt;[NAME]&lt;/nolink&gt; is Offline
@@ -5459,6 +5465,8 @@ You don&apos;t have permission to copy this.
   <notification
    icon="notifytip.tga"
    name="InventoryAccepted"
+   log_to_im="true"   
+   log_to_chat="true"
    type="notifytip">
 [NAME] received your inventory offer.
   </notification>
@@ -5466,6 +5474,8 @@ You don&apos;t have permission to copy this.
   <notification
    icon="notifytip.tga"
    name="InventoryDeclined"
+   log_to_im="true"   
+   log_to_chat="true"
    type="notifytip">
 [NAME] declined your inventory offer.
   </notification>
@@ -5547,6 +5557,7 @@ Please select at least one type of content to search (General, Moderate, or Adul
   <notification
    icon="notify.tga"
    name="PaymentReceived"
+   log_to_im="true"   
    persist="true"
    type="notify">
     <tag>funds</tag>
@@ -5556,6 +5567,7 @@ Please select at least one type of content to search (General, Moderate, or Adul
   <notification
    icon="notify.tga"
    name="PaymentSent"
+   log_to_im="true"   
    persist="true"
    type="notify">
     <tag>funds</tag>
@@ -5700,6 +5712,7 @@ The objects on the selected parcel that are NOT owned by you have been returned
   <notification
    icon="notify.tga"
    name="ServerObjectMessage"
+   log_to_im="true"   
    persist="true"
    type="notify">
 Message from [NAME]:
@@ -6070,6 +6083,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="UserGiveItem"
+   log_to_im ="true"
    type="offer">
 [NAME_SLURL] has given you this [OBJECTTYPE]:
 [ITEM_SLURL]
@@ -6125,6 +6139,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="TeleportOffered"
+   log_to_im="true"
    type="offer">
 [NAME_SLURL] has offered to teleport you to their location:
 
@@ -6145,6 +6160,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="TeleportOfferSent"
+   log_to_im="true"   
    type="offer">
 	Teleport offer sent to [TO_NAME]
   </notification>
@@ -6172,6 +6188,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="OfferFriendship"
+   log_to_im="true"
    type="offer">
     <tag>friendship</tag>
     <tag>confirm</tag>
@@ -6195,6 +6212,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="FriendshipOffered"
+   log_to_im="true"   
    type="offer">
     <tag>friendship</tag>
 	You have offered friendship to [TO_NAME]
@@ -6224,6 +6242,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="FriendshipAccepted"
+   log_to_im="true"   
    type="offer">
     <tag>friendship</tag>
 &lt;nolink&gt;[NAME]&lt;/nolink&gt; accepted your friendship offer.
@@ -6232,6 +6251,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="FriendshipDeclined"
+   log_to_im="true"   
    persist="true"
    type="notify">
     <tag>friendship</tag>
@@ -6241,6 +6261,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
     <notification
    icon="notify.tga"
    name="FriendshipAcceptedByMe"
+   log_to_im="true"   
    type="offer">
     <tag>friendship</tag>
 Friendship offer accepted.
@@ -6249,6 +6270,7 @@ Friendship offer accepted.
   <notification
    icon="notify.tga"
    name="FriendshipDeclinedByMe"
+   log_to_im="true"   
    type="offer">
     <tag>friendship</tag>
 Friendship offer declined.
-- 
cgit v1.2.3


From 2fa1c42aadbe2a29e1bcced9a487c0e5abf0602b Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 29 Mar 2012 23:48:29 -0700
Subject: CHUI-51 WIP notifications routig code cleanup phase 2, removal of
 extraneous signaling in favor of llnotificationchannels made
 notificationchannels work better with overrides and lifetime managed by
 creator

---
 indra/llcommon/llinstancetracker.h              |  5 +-
 indra/llcommon/llrefcount.h                     | 19 +++++
 indra/llcommon/llthread.h                       | 17 +++++
 indra/llui/llnotifications.cpp                  | 92 +++++++++++++------------
 indra/llui/llnotifications.h                    | 49 ++++++++-----
 indra/llui/llnotificationslistener.cpp          |  8 +--
 indra/newview/llchiclet.cpp                     | 26 +++----
 indra/newview/llchiclet.h                       | 31 +++++++--
 indra/newview/llfloaternotificationsconsole.cpp | 38 ++--------
 indra/newview/llimhandler.cpp                   | 12 ----
 indra/newview/llnotificationgrouphandler.cpp    | 14 ----
 indra/newview/llnotificationhandler.h           | 23 +------
 indra/newview/llnotificationhandlerutil.cpp     | 88 ++++++++---------------
 indra/newview/llnotificationmanager.cpp         | 19 ++---
 indra/newview/llnotificationmanager.h           |  1 +
 indra/newview/llnotificationofferhandler.cpp    | 42 ++---------
 indra/newview/llnotificationscripthandler.cpp   | 19 +----
 indra/newview/llsyswellwindow.cpp               | 37 +++++-----
 indra/newview/llsyswellwindow.h                 | 19 +++--
 indra/newview/lltoastgroupnotifypanel.h         |  3 -
 indra/newview/lltoastscripttextbox.h            |  2 -
 21 files changed, 241 insertions(+), 323 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 34d841a4e0..11f582372e 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -43,7 +43,7 @@
  * semantics: one instance per process, rather than one instance per module as
  * sometimes happens with data simply declared static.
  */
-class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
+class LL_COMMON_API LLInstanceTrackerBase
 {
 protected:
 	/// Get a process-unique void* pointer slot for the specified type_info
@@ -209,6 +209,9 @@ protected:
 	virtual const KEY& getKey() const { return mInstanceKey; }
 
 private:
+	LLInstanceTracker( const LLInstanceTracker& );
+	const LLInstanceTracker& operator=( const LLInstanceTracker& );
+
 	void add_(KEY key) 
 	{ 
 		mInstanceKey = key; 
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 8eb5d53f3f..32ae15435a 100644
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -27,6 +27,7 @@
 #define LLREFCOUNT_H
 
 #include <boost/noncopyable.hpp>
+#include <boost/intrusive_ptr.hpp>
 
 #define LL_REF_COUNT_DEBUG 0
 #if LL_REF_COUNT_DEBUG
@@ -86,4 +87,22 @@ private:
 #endif
 };
 
+/**
+ * intrusive pointer support
+ * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
+ */
+namespace boost
+{
+	inline void intrusive_ptr_add_ref(LLRefCount* p)
+	{
+		p->ref();
+	}
+
+	inline void intrusive_ptr_release(LLRefCount* p)
+	{
+		p->unref();
+	}
+};
+
+
 #endif
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index b52e70ab2e..cf39696b4f 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -30,6 +30,7 @@
 #include "llapp.h"
 #include "llapr.h"
 #include "apr_thread_cond.h"
+#include "boost/intrusive_ptr.hpp"
 
 class LLThread;
 class LLMutex;
@@ -266,6 +267,22 @@ private:
 	S32	mRef; 
 };
 
+/**
+ * intrusive pointer support for LLThreadSafeRefCount
+ * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
+ */
+namespace boost
+{
+	inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p) 
+	{
+		p->ref();
+	}
+
+	inline void intrusive_ptr_release(LLThreadSafeRefCount* p) 
+	{
+		p->unref(); 
+	}
+};
 //============================================================================
 
 // Simple responder for self destructing callbacks
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 038a86d20a..c45899a4bd 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -966,7 +966,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 	std::string cmd = payload["sigtype"];
 	LLNotificationSet::iterator foundItem = mItems.find(pNotification);
 	bool wasFound = (foundItem != mItems.end());
-	bool passesFilter = mFilter(pNotification);
+	bool passesFilter = mFilter ? mFilter(pNotification) : true;
 	
 	// first, we offer the result of the filter test to the simple
 	// signals for pass/fail. One of these is guaranteed to be called.
@@ -1071,27 +1071,28 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 	return abortProcessing;
 }
 
+LLNotificationChannel::LLNotificationChannel(const Params& p)
+:	LLNotificationChannelBase(p.filter(), p.comparator()),
+	LLInstanceTracker<LLNotificationChannel, std::string>(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()),
+	mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString())
+{
+	BOOST_FOREACH(const std::string& source, p.sources)
+	{
+		connectToChannel(source);
+	}
+}
+
+
 LLNotificationChannel::LLNotificationChannel(const std::string& name, 
 											 const std::string& parent,
 											 LLNotificationFilter filter, 
-											 LLNotificationComparator comparator) : 
-LLNotificationChannelBase(filter, comparator),
-mName(name),
-mParent(parent)
+											 LLNotificationComparator comparator) 
+:	LLNotificationChannelBase(filter, comparator),
+	LLInstanceTracker<LLNotificationChannel, std::string>(name),
+	mName(name)
 {
-	// store myself in the channel map
-	LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));
 	// bind to notification broadcast
-	if (parent.empty())
-	{
-		LLNotifications::instance().connectChanged(
-			boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
-	}
-	else
-	{
-		LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent);
-		p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
-	}
+	connectToChannel(parent);
 }
 
 
@@ -1134,6 +1135,21 @@ std::string LLNotificationChannel::summarize()
 	return s;
 }
 
+void LLNotificationChannel::connectToChannel( const std::string& channel_name )
+{
+	if (channel_name.empty())
+	{
+		LLNotifications::instance().connectChanged(
+			boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+	}
+	else
+	{
+		LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name);
+		p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+	}
+}
+
+
 
 // ---
 // END OF LLNotificationChannel implementation
@@ -1248,21 +1264,9 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
 	return false;
 }
 
-
-void LLNotifications::addChannel(LLNotificationChannelPtr pChan)
-{
-	mChannels[pChan->getName()] = pChan;
-}
-
 LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
 {
-	ChannelMap::iterator p = mChannels.find(channelName);
-	if(p == mChannels.end())
-	{
-		llerrs << "Did not find channel named " << channelName << llendl;
-		return LLNotificationChannelPtr();
-	}
-	return p->second;
+	return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName));
 }
 
 
@@ -1278,20 +1282,20 @@ void LLNotifications::createDefaultChannels()
 {
 	// now construct the various channels AFTER loading the notifications,
 	// because the history channel is going to rewrite the stored notifications file
-	new LLNotificationChannel("Enabled", "",
-		!boost::bind(&LLNotifications::getIgnoreAllNotifications, this));
-	new LLNotificationChannel("Expiration", "Enabled",
-		boost::bind(&LLNotifications::expirationFilter, this, _1));
-	new LLNotificationChannel("Unexpired", "Enabled",
-		!boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
-	new LLNotificationChannel("Unique", "Unexpired",
-		boost::bind(&LLNotifications::uniqueFilter, this, _1));
-	new LLNotificationChannel("Ignore", "Unique",
-		filterIgnoredNotifications);
-	new LLNotificationChannel("VisibilityRules", "Ignore",
-		boost::bind(&LLNotifications::isVisibleByRules, this, _1));
-	new LLNotificationChannel("Visible", "VisibilityRules",
-		&LLNotificationFilters::includeEverything);
+	mDefaultChannels.push_back(new LLNotificationChannel("Enabled", "",
+		!boost::bind(&LLNotifications::getIgnoreAllNotifications, this)));
+	mDefaultChannels.push_back(new LLNotificationChannel("Expiration", "Enabled",
+		boost::bind(&LLNotifications::expirationFilter, this, _1)));
+	mDefaultChannels.push_back(new LLNotificationChannel("Unexpired", "Enabled",
+		!boost::bind(&LLNotifications::expirationFilter, this, _1))); // use negated bind
+	mDefaultChannels.push_back(new LLNotificationChannel("Unique", "Unexpired",
+		boost::bind(&LLNotifications::uniqueFilter, this, _1)));
+	mDefaultChannels.push_back(new LLNotificationChannel("Ignore", "Unique",
+		filterIgnoredNotifications));
+	mDefaultChannels.push_back(new LLNotificationChannel("VisibilityRules", "Ignore",
+		boost::bind(&LLNotifications::isVisibleByRules, this, _1)));
+	mDefaultChannels.push_back(new LLNotificationChannel("Visible", "VisibilityRules",
+		&LLNotificationFilters::includeEverything));
 
 	// create special persistent notification channel
 	// this isn't a leak, don't worry about the empty "new"
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index f83365a97d..344108ecbf 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -94,10 +94,11 @@
 // and we need this to manage the notification callbacks
 #include "llevents.h"
 #include "llfunctorregistry.h"
-#include "llpointer.h"
 #include "llinitparam.h"
 #include "llnotificationslistener.h"
 #include "llnotificationptr.h"
+#include "llpointer.h"
+#include "llrefcount.h"
 
 class LLAvatarName;
 typedef enum e_notification_priority
@@ -707,7 +708,8 @@ typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
 // all of the built-in tests should attach to the "Visible" channel
 //
 class LLNotificationChannelBase :
-	public LLEventTrackable
+	public LLEventTrackable,
+	public LLRefCount
 {
 	LOG_CLASS(LLNotificationChannelBase);
 public:
@@ -787,26 +789,48 @@ protected:
 // destroy it, but if it becomes necessary to do so, the shared_ptr model
 // will ensure that we don't leak resources.
 class LLNotificationChannel;
-typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr;
+typedef boost::intrusive_ptr<LLNotificationChannel> LLNotificationChannelPtr;
 
 // manages a list of notifications
 // Note that if this is ever copied around, we might find ourselves with multiple copies
 // of a queue with notifications being added to different nonequivalent copies. So we 
-// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it.
+// make it inherit from boost::noncopyable, and then create a map of LLPointer to manage it.
 // 
 class LLNotificationChannel : 
 	boost::noncopyable, 
-	public LLNotificationChannelBase
+	public LLNotificationChannelBase,
+	public LLInstanceTracker<LLNotificationChannel, std::string>
 {
 	LOG_CLASS(LLNotificationChannel);
 
 public:  
+	// Notification Channels have a filter, which determines which notifications
+	// will be added to this channel. 
+	// Channel filters cannot change.
+	struct Params : public LLInitParam::Block<Params>
+	{
+		Mandatory<std::string>				name;
+		Optional<LLNotificationFilter>		filter;
+		Optional<LLNotificationComparator>	comparator;
+		Multiple<std::string>				sources;
+
+		Params()
+		:	comparator("", LLNotificationComparators::orderByUUID())
+		{}
+	};
+
+	LLNotificationChannel(const Params& p = Params());
+
+	LLNotificationChannel(const std::string& name, const std::string& parent,
+		LLNotificationFilter filter, LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
+
 	virtual ~LLNotificationChannel() {}
 	typedef LLNotificationSet::iterator Iterator;
     
 	std::string getName() const { return mName; }
-	std::string getParentChannelName() { return mParent; }
     
+	void connectToChannel(const std::string& channel_name);
+
     bool isEmpty() const;
     
     Iterator begin();
@@ -818,14 +842,6 @@ public:
 	
 	std::string summarize();
 
-    // Notification Channels have a filter, which determines which notifications
-	// will be added to this channel. 
-	// Channel filters cannot change.
-	// Channels have a protected constructor so you can't make smart pointers that don't 
-	// come from our internal reference; call NotificationChannel::build(args)
-	LLNotificationChannel(const std::string& name, const std::string& parent,
-						  LLNotificationFilter filter, LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
-
 private:
 	std::string mName;
 	std::string mParent;
@@ -912,10 +928,6 @@ public:
 
 	void createDefaultChannels();
 
-	typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap;
-	ChannelMap mChannels;
-
-	void addChannel(LLNotificationChannelPtr pChan);
 	LLNotificationChannelPtr getChannel(const std::string& channelName);
 	
 	std::string getGlobalString(const std::string& key) const;
@@ -954,6 +966,7 @@ private:
 	bool mIgnoreAllNotifications;
 
     boost::scoped_ptr<LLNotificationsListener> mListener;
+	std::vector<LLNotificationChannelPtr> mDefaultChannels;
 };
 
 /**
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
index 3bbeb3a778..e4e127336b 100644
--- a/indra/llui/llnotificationslistener.cpp
+++ b/indra/llui/llnotificationslistener.cpp
@@ -121,13 +121,13 @@ void LLNotificationsListener::listChannels(const LLSD& params) const
 {
     LLReqID reqID(params);
     LLSD response(reqID.makeResponse());
-    for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()),
-                                                     cmend(mNotifications.mChannels.end());
+    for (LLNotificationChannel::instance_iter cmi(LLNotificationChannel::beginInstances()),
+                                                     cmend(LLNotificationChannel::endInstances());
          cmi != cmend; ++cmi)
     {
         LLSD channelInfo;
-        channelInfo["parent"] = cmi->second->getParentChannelName();
-        response[cmi->first] = channelInfo;
+        //channelInfo["parent"] = cmi->second->getParentChannelName();
+        response[cmi->getName()] = channelInfo;
     }
     LLEventPumps::instance().obtain(params["reply"]).post(response);
 }
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 9f19f8dd1c..67519a3ca6 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -335,29 +335,15 @@ void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
 /*               LLNotificationChiclet implementation                   */
 /************************************************************************/
 LLNotificationChiclet::LLNotificationChiclet(const Params& p)
-: LLSysWellChiclet(p)
-, mUreadSystemNotifications(0)
+:	LLSysWellChiclet(p),
+	mUreadSystemNotifications(0)
 {
-	// connect counter handlers to the signals
-	connectCounterUpdatersToSignal("Notify");
-	connectCounterUpdatersToSignal("Group Notify");
-	connectCounterUpdatersToSignal("Offer");
-
+	mNotificationChannel.reset(new ChicletNotificationChannel(this));
 	// ensure that notification well window exists, to synchronously
 	// handle toast add/delete events.
 	LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
 }
 
-void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type)
-{
-	LLNotificationsUI::LLEventHandler* n_handler = dynamic_cast<LLNotificationsUI::LLEventHandler*>(LLNotifications::instance().getChannel(notification_type).get());
-	if(n_handler)
-	{
-		n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
-		n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this));
-	}
-}
-
 void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
 {
 	std::string action = user_data.asString();
@@ -406,6 +392,12 @@ void LLNotificationChiclet::setCounter(S32 counter)
 	updateWidget(getCounter() == 0);
 	
 }
+
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notify )
+{
+	return !(notify->canLogToIM() && notify->hasFormElements());
+}
+
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 1f1069dcb4..dd0d47cccd 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -34,6 +34,7 @@
 #include "lloutputmonitorctrl.h"
 #include "llgroupmgr.h"
 #include "llimview.h"
+#include "llnotifications.h"
 
 class LLMenuGL;
 class LLIMFloater;
@@ -911,11 +912,35 @@ protected:
 
 class LLNotificationChiclet : public LLSysWellChiclet
 {
+	LOG_CLASS(LLNotificationChiclet);
+	
 	friend class LLUICtrlFactory;
 public:
 	struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
 
 protected:
+	struct ChicletNotificationChannel : public LLNotificationChannel
+	{
+		ChicletNotificationChannel(LLNotificationChiclet* chiclet) 
+		:	LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString())),
+			mChiclet(chiclet)
+		{
+			// connect counter handlers to the signals
+			connectToChannel("IM Notifications");
+			connectToChannel("Group Notifications");
+			connectToChannel("Offer");
+		}
+
+		static bool filterNotification(LLNotificationPtr notify);
+		// connect counter updaters to the corresponding signals
+		/*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
+		/*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
+
+		LLNotificationChiclet* const mChiclet;
+	};
+
+	boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
+
 	LLNotificationChiclet(const Params& p);
 
 	/**
@@ -933,12 +958,6 @@ protected:
 	 */
 	/*virtual*/ void createMenu();
 
-	// connect counter updaters to the corresponding signals
-	void connectCounterUpdatersToSignal(const std::string& notification_type);
-
-	// methods for updating a number of unread System notifications
-	void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); }
-	void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); }
 	/*virtual*/ void setCounter(S32 counter);
 	S32 mUreadSystemNotifications;
 };
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index 90dbabebfb..4f35c325a8 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -44,21 +44,16 @@ public:
 	BOOL postBuild();
 
 private:
-	bool update(const LLSD& payload, bool passed_filter);
+	bool update(const LLSD& payload);
 	static void toggleClick(void* user_data);
 	static void onClickNotification(void* user_data);
-	static void onClickNotificationReject(void* user_data);
 	LLNotificationChannelPtr mChannelPtr;
-	LLNotificationChannelPtr mChannelRejectsPtr;
 };
 
 LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p) 
 :	LLLayoutPanel(p)
 {
 	mChannelPtr = LLNotifications::instance().getChannel(p.name);
-	mChannelRejectsPtr = LLNotificationChannelPtr(
-		new LLNotificationChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(),
-											!boost::bind(mChannelPtr->getFilter(), _1)));
 	buildFromFile( "panel_notifications_channel.xml");
 }
 
@@ -68,15 +63,11 @@ BOOL LLNotificationChannelPanel::postBuild()
 	header_button->setLabel(mChannelPtr->getName());
 	header_button->setClickedCallback(toggleClick, this);
 
-	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
-	mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
+	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1));
 
 	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
 	scroll->setDoubleClickCallback(onClickNotification, this);
 	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
-	scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
-	scroll->setDoubleClickCallback(onClickNotificationReject, this);
-	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
 	return TRUE;
 }
 
@@ -97,8 +88,6 @@ void LLNotificationChannelPanel::toggleClick(void *user_data)
 	// turn off tab stop for collapsed panel
 	self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
 	self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
-	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
-	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
 }
 
 /*static*/
@@ -118,24 +107,7 @@ void LLNotificationChannelPanel::onClickNotification(void* user_data)
 	}
 }
 
-/*static*/
-void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
-{
-	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
-	if (!self) return;
-	LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected();
-	llassert(firstselected);
-	if (firstselected)
-	{
-		void* data = firstselected->getUserdata();
-		if (data)
-		{
-			gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
-		}
-	}
-}
-
-bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
+bool LLNotificationChannelPanel::update(const LLSD& payload)
 {
 	LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
 	if (notification)
@@ -151,9 +123,7 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
 		row["columns"][2]["column"] = "date";
 		row["columns"][2]["type"] = "date";
 
-		LLScrollListItem* sli = passed_filter ? 
-			getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
-			getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
+		LLScrollListItem* sli = getChild<LLScrollListCtrl>("notifications_list")->addElement(row);
 		sli->setUserdata(&(*notification));
 	}
 
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index a92c4fa387..1437d0747c 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -95,24 +95,12 @@ bool LLIMHandler::processNotification(const LLNotificationPtr& notification)
 	p.notification = notification;
 	p.panel = im_box;
 	p.can_be_stored = false;
-	p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
 	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
 	if(channel)
 		channel->addToast(p);
 
-	// send a signal to the counter manager;
-	mNewNotificationSignal();
-	
 	return false;
 }
 
-//--------------------------------------------------------------------------
-void LLIMHandler::onDeleteToast(LLToast* toast)
-{
-	// send a signal to the counter manager
-	mDelNotificationSignal();
-}
-
-//--------------------------------------------------------------------------
 
 
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 2ce51fa094..97e382e42f 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -87,25 +87,11 @@ bool LLGroupHandler::processNotification(const LLNotificationPtr& notification)
 	if(channel)
 		channel->addToast(p);
 
-	// send a signal to the counter manager
-	mNewNotificationSignal();
-
 	LLGroupActions::refresh_notices();
 
 	return false;
 }
 
-//--------------------------------------------------------------------------
-void LLGroupHandler::onDeleteToast(LLToast* toast)
-{
-	// send a signal to the counter manager
-	mDelNotificationSignal();
-
-	// send a signal to a listener to let him perform some action
-	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
-	mNotificationIDSignal(toast->getNotificationID());
-}
-
 //--------------------------------------------------------------------------
 void LLGroupHandler::onRejectToast(LLUUID& id)
 {
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index ff9371f7df..419b8a14b6 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -67,19 +67,6 @@ class LLEventHandler
 public:
 	virtual ~LLEventHandler() {};
 
-	// callbacks for counters
-	typedef boost::function<void (void)> notification_callback_t;
-	typedef boost::signals2::signal<void (void)> notification_signal_t;
-	notification_signal_t mNewNotificationSignal;
-	notification_signal_t mDelNotificationSignal;
-	boost::signals2::connection setNewNotificationCallback(notification_callback_t cb) { return mNewNotificationSignal.connect(cb); }
-	boost::signals2::connection setDelNotification(notification_callback_t cb) { return mDelNotificationSignal.connect(cb); }
-	// callback for notification/toast
-	typedef boost::function<void (const LLUUID id)> notification_id_callback_t;
-	typedef boost::signals2::signal<void (const LLUUID id)> notification_id_signal_t;
-	notification_id_signal_t mNotificationIDSignal;
-	boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); }
-
 protected:
 	virtual void onDeleteToast(LLToast* toast) {}
 
@@ -143,7 +130,6 @@ public:
 
 protected:
 	bool processNotification(const LLNotificationPtr& p);
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 };
 
@@ -201,7 +187,6 @@ public:
 	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 
 	// own handlers
@@ -244,7 +229,6 @@ public:
 	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 
 	// own handlers
@@ -313,12 +297,7 @@ public:
 	/**
 	 * Writes notification message to IM  p2p session.
 	 */
-	static void logToIMP2P(const LLNotificationPtr& notification);
-
-	/**
-	 * Writes notification message to IM  p2p session.
-	 */
-	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only);
+	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);
 
 	/**
 	 * Writes group notice notification message to IM  group session.
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index dca7fda151..3ebf0bcc9e 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -111,37 +111,18 @@ void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)
 	}
 }
 
-const static std::string	OBJECT_GIVE_ITEM("ObjectGiveItem");
-
-static LLIMFloater* find_im_floater(const LLNotificationPtr& notification)
-{
-	LLUUID from_id = notification->getPayload()["from_id"];
-	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
-	return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
 // static
 bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
 {
 	bool res = false;
 
-	LLIMFloater* im_floater = find_im_floater(notification);
-	if (im_floater != NULL)
-	{
-		res = im_floater->getVisible() == TRUE;
-	}
-
-	return res;
-}
-
-static bool is_IM_floater_focused(const LLNotificationPtr& notification)
-{
-	bool res = false;
+	LLUUID from_id = notification->getPayload()["from_id"];
+	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
+	LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
 
-	LLIMFloater* im_floater = find_im_floater(notification);
 	if (im_floater != NULL)
 	{
-		res = im_floater->hasFocus() == TRUE;
+		res = im_floater->getVisible() == TRUE;
 	}
 
 	return res;
@@ -208,12 +189,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 	}
 }
 
-// static
-void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification)
-{
-	logToIMP2P(notification, false);
-}
-
 void log_name_callback(const std::string& full_name, const std::string& from_name, 
 					   const std::string& message, const LLUUID& from_id)
 
@@ -225,25 +200,21 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam
 // static
 void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
 {
-	// don't create IM p2p session with objects, it's necessary condition to log
-	//if (notification->getName() != OBJECT_GIVE_ITEM)
-	{
-		LLUUID from_id = notification->getPayload()["from_id"];
+	LLUUID from_id = notification->getPayload()["from_id"];
 
-		if (from_id.isNull())
-		{
-			llwarns << " from_id for notification " << notification->getName() << " is null " << llendl;
-			return;
-		}
+	if (from_id.isNull())
+	{
+		llwarns << " from_id for notification " << notification->getName() << " is null " << llendl;
+		return;
+	}
 
-		if(to_file_only)
-		{
-			gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
-		}
-		else
-		{
-			gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
-		}
+	if(to_file_only)
+	{
+		gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
+	}
+	else
+	{
+		gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
 	}
 }
 
@@ -377,23 +348,20 @@ void LLHandlerUtil::updateVisibleIMFLoaterMesages(const LLNotificationPtr& notif
 void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
 {
 	const std::string name = LLHandlerUtil::getSubstitutionName(notification);
-	LLUUID from_id = notification->getPayload()["from_id"];
-	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
+	LLUUID from_id 		   = notification->getPayload()["from_id"];
+	LLUUID session_id 	   = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
 
-	LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(
-			session_id);
+	LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(session_id);
 
-	if (session == NULL)
+	if (session)
 	{
-		return;
+		LLSD arg;
+		arg["session_id"] = session_id;
+		session->mNumUnread--;
+		arg["num_unread"] = session->mNumUnread;
+		session->mParticipantUnreadMessageCount--;
+		arg["participant_unread"] = session->mParticipantUnreadMessageCount;
+		LLIMModel::getInstance()->mNewMsgSignal(arg);
 	}
-
-	LLSD arg;
-	arg["session_id"] = session_id;
-	session->mNumUnread--;
-	arg["num_unread"] = session->mNumUnread;
-	session->mParticipantUnreadMessageCount--;
-	arg["participant_unread"] = session->mParticipantUnreadMessageCount;
-	LLIMModel::getInstance()->mNewMsgSignal(arg);
 }
 
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index 394ae2ac21..9beb8afac6 100644
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -52,15 +52,16 @@ LLNotificationManager::~LLNotificationManager()
 //--------------------------------------------------------------------------
 void LLNotificationManager::init()
 {
-	new LLScriptHandler();
-	new LLTipHandler();
-	new LLGroupHandler();
-	new LLAlertHandler("Alerts", "alert", false);
-	new LLAlertHandler("AlertModal", "alertmodal", true);
-	new LLOfferHandler();
-	new LLHintHandler();
-	new LLBrowserNotification();
-	new LLOutboxNotification();
+	mChannels.push_back(new LLScriptHandler());
+	mChannels.push_back(new LLTipHandler());
+	mChannels.push_back(new LLGroupHandler());
+	mChannels.push_back(new LLAlertHandler("Alerts", "alert", false));
+	mChannels.push_back(new LLAlertHandler("AlertModal", "alertmodal", true));
+	mChannels.push_back(new LLOfferHandler());
+	mChannels.push_back(new LLHintHandler());
+	mChannels.push_back(new LLBrowserNotification());
+	mChannels.push_back(new LLOutboxNotification());
+	mChannels.push_back(new LLIMHandler());
 	
 	mChatHandler = boost::shared_ptr<LLNearbyChatHandler>(new LLNearbyChatHandler());
 }
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
index 4d124e1379..c8afdf9e46 100644
--- a/indra/newview/llnotificationmanager.h
+++ b/indra/newview/llnotificationmanager.h
@@ -61,6 +61,7 @@ public:
 
 private:
 	boost::shared_ptr<class LLNearbyChatHandler> mChatHandler;
+	std::vector<LLNotificationChannelPtr> mChannels;
 };
 
 }
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 8010417d43..051075cff9 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -79,16 +79,17 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 		initChannel();
 	}
 
-	bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements();
 
 	if( notification->getPayload().has("give_inventory_notification")
-		&& !notification->getPayload()["give_inventory_notification"] )
+		&& notification->getPayload()["give_inventory_notification"].asBoolean() == false)
 	{
 		// This is an original inventory offer, so add a script floater
 		LLScriptFloaterManager::instance().onAddNotification(notification->getID());
 	}
 	else
 	{
+		bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements();
+
 		notification->setReusable(add_notif_to_im);
 
 		LLUUID session_id;
@@ -99,10 +100,6 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 			LLUUID from_id = notification->getPayload()["from_id"];
 
 			session_id = LLHandlerUtil::spawnIMSession(name, from_id);
-		}
-
-		if (add_notif_to_im)
-		{
 			LLHandlerUtil::addNotifPanelToIM(notification);
 		}
 
@@ -120,33 +117,19 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 			p.notif_id = notification->getID();
 			p.notification = notification;
 			p.panel = notify_box;
-			p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
 			// we not save offer notifications to the syswell floater that should be added to the IM floater
 			p.can_be_stored = !add_notif_to_im;
 
 			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
 			if(channel)
 				channel->addToast(p);
-
-			// if we not add notification to IM - add it to notification well
-			if (!add_notif_to_im)
-			{
-				// send a signal to the counter manager
-				mNewNotificationSignal();
-			}
 		}
 
 		if (notification->canLogToIM())
 		{
 			// log only to file if notif panel can be embedded to IM and IM is opened
-			if (add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification))
-			{
-				LLHandlerUtil::logToIMP2P(notification, true);
-			}
-			else
-			{
-				LLHandlerUtil::logToIMP2P(notification);
-			}
+			bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification);
+			LLHandlerUtil::logToIMP2P(notification, file_only);
 		}
 	}
 
@@ -173,21 +156,6 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 	}
 }
 
-//--------------------------------------------------------------------------
-
-void LLOfferHandler::onDeleteToast(LLToast* toast)
-{
-	if (!toast->getNotification()->canLogToIM() || !toast->getNotification()->hasFormElements())
-	{
-		// send a signal to the counter manager
-		mDelNotificationSignal();
-	}
-
-	// send a signal to a listener to let him perform some action
-	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
-	mNotificationIDSignal(toast->getNotificationID());
-}
-
 //--------------------------------------------------------------------------
 void LLOfferHandler::onRejectToast(LLUUID& id)
 {
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 714f14963c..c74c967722 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -37,10 +37,6 @@
 
 using namespace LLNotificationsUI;
 
-static const std::string SCRIPT_DIALOG				("ScriptDialog");
-static const std::string SCRIPT_DIALOG_GROUP		("ScriptDialogGroup");
-static const std::string SCRIPT_LOAD_URL			("LoadWebPage");
-
 //--------------------------------------------------------------------------
 LLScriptHandler::LLScriptHandler()
 :	LLSysHandler("Notifications", "notify")
@@ -87,7 +83,7 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 		LLHandlerUtil::logToIMP2P(notification);
 	}
 
-	if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
+	if(notification->hasFormElements())
 	{
 		LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
 	}
@@ -106,9 +102,6 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 		{
 			channel->addToast(p);
 		}
-
-		// send a signal to the counter manager
-		mNewNotificationSignal();
 	}
 	
 	return false;
@@ -117,7 +110,7 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 
 void LLScriptHandler::onDelete( LLNotificationPtr notification )
 {
-	if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
+	if(notification->hasFormElements())
 	{
 		LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
 	}
@@ -132,17 +125,11 @@ void LLScriptHandler::onDelete( LLNotificationPtr notification )
 
 void LLScriptHandler::onDeleteToast(LLToast* toast)
 {
-	// send a signal to the counter manager
-	mDelNotificationSignal();
-
 	// send a signal to a listener to let him perform some action
 	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
-	mNotificationIDSignal(toast->getNotificationID());
-
 	LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID());
 	
-	if( notification && 
-		(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) )
+	if( notification && notification->hasFormElements())
 	{
 		LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
 	}
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index e8293ebe2b..18e0d9d0d2 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -433,13 +433,19 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas
 
 //////////////////////////////////////////////////////////////////////////
 // PUBLIC METHODS
+LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window)
+:	LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())),
+	mWellWindow(well_window)
+{
+	connectToChannel("Notifications");
+	connectToChannel("Group Notifications");
+	connectToChannel("Offer");
+}
+
 LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
-: LLSysWellWindow(key)
+:	LLSysWellWindow(key)
 {
-	// init connections to the list's update events
-	connectListUpdaterToSignal("Notifications");
-	connectListUpdaterToSignal("Group Notifications");
-	connectListUpdaterToSignal("Offer");
+	mNotificationUpdates.reset(new WellNotificationChannel(this));
 }
 
 // static
@@ -546,19 +552,6 @@ void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
 	addItem(p);
 }
 
-void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type)
-{
-	LLNotificationsUI::LLEventHandler* n_handler = dynamic_cast<LLNotificationsUI::LLEventHandler*>(LLNotifications::instance().getChannel(notification_type).get());
-	if(n_handler)
-	{
-		n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1));
-	}
-	else
-	{
-		llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl;
-	}
-}
-
 void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
 {
 	LLUUID id = item->getID();
@@ -573,6 +566,12 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
 		mChannel->killToastByNotificationID(id);
 }
 
+void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
+{
+	removeItemByID(notify->getID());
+}
+
+
 
 
 /************************************************************************/
@@ -866,4 +865,4 @@ bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& respo
 	return false;
 }
 
-// EOF
+
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 272e9cfcb1..caf30cfd67 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -34,6 +34,7 @@
 #include "llscreenchannel.h"
 #include "llscrollcontainer.h"
 #include "llimview.h"
+#include "llnotifications.h"
 
 #include "boost/shared_ptr.hpp"
 
@@ -111,7 +112,7 @@ public:
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void setVisible(BOOL visible);
-
+	/*virtual*/ void onAdd(LLNotificationPtr notify);
 	// Operating with items
 	void addItem(LLSysWellItem::Params p);
 
@@ -119,6 +120,18 @@ public:
 	void closeAll();
 
 protected:
+	struct WellNotificationChannel : public LLNotificationChannel
+	{
+		WellNotificationChannel(LLNotificationWellWindow*);
+		void onAdd(LLNotificationPtr notify)
+		{
+			mWellWindow->removeItemByID(notify->getID());
+		} 
+
+		LLNotificationWellWindow* mWellWindow;
+	};
+
+	LLNotificationChannelPtr mNotificationUpdates;
 	/*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }
 
 private:
@@ -126,12 +139,8 @@ private:
 	void initChannel();
 	void clearScreenChannels();
 
-
 	void onStoreToast(LLPanel* info_panel, LLUUID id);
 
-	// connect counter and list updaters to the corresponding signals
-	void connectListUpdaterToSignal(std::string notification_type);
-
 	// Handlers
 	void onItemClick(LLSysWellItem* item);
 	void onItemClose(LLSysWellItem* item);
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
index 3b8b31eac1..dfdc6ae559 100644
--- a/indra/newview/lltoastgroupnotifypanel.h
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -47,9 +47,6 @@ class LLToastGroupNotifyPanel
 public:
 	void close();
 
-	static bool onNewNotification(const LLSD& notification);
-
-
 	// Non-transient messages.  You can specify non-default button
 	// layouts (like one for script dialogs) by passing various
 	// numbers in for "layout".
diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h
index 8e69d8834d..7d33446248 100644
--- a/indra/newview/lltoastscripttextbox.h
+++ b/indra/newview/lltoastscripttextbox.h
@@ -39,8 +39,6 @@ class LLToastScriptTextbox
 public:
 	void close();
 
-	static bool onNewNotification(const LLSD& notification);
-
 	// Non-transient messages.  You can specify non-default button
 	// layouts (like one for script dialogs) by passing various
 	// numbers in for "layout".
-- 
cgit v1.2.3


From c2afd200a0d55c5137de6f89200a8d4b09ba8b6e Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 30 Mar 2012 18:36:43 -0700
Subject: CHUI-51 WIP notifications routing code cleanup object inventory
 offers don't increment system menu count added customizable merging behavior
 for duplicate "unique" notifications fixed overeager notification channels

---
 indra/llui/llnotifications.cpp              | 43 ++++++++++++++++-------------
 indra/llui/llnotifications.h                |  8 ++++++
 indra/llui/llnotificationtemplate.h         | 14 ++++++++++
 indra/newview/llchiclet.cpp                 | 10 +++++--
 indra/newview/llnotificationhandler.h       | 33 +++++++++++-----------
 indra/newview/llnotificationhinthandler.cpp |  2 +-
 indra/newview/llscreenchannel.cpp           |  9 +++++-
 7 files changed, 80 insertions(+), 39 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index c45899a4bd..79135d2c60 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -246,7 +246,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
 	LLParamSDParser parser;
 	parser.writeSD(mFormData, p.form_elements);
 
-	if (!mFormData.isArray())
+	if (!mFormData.isArray() && !mFormData.isUndefined())
 	{
 		// change existing contents to a one element array
 		LLSD new_llsd_array = LLSD::emptyArray();
@@ -407,6 +407,7 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 	mURLOption(p.url.option),
 	mURLTarget(p.url.target),
 	mUnique(p.unique.isProvided()),
+	mCombineBehavior(p.unique.combine),
 	mPriority(p.priority),
 	mPersist(p.persist),
 	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()),
@@ -903,6 +904,10 @@ bool LLNotification::hasFormElements() const
 	return mTemplatep->mForm->getNumElements() != 0;
 }
 
+LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const
+{
+	return mTemplatep->mCombineBehavior;
+}
 
 
 
@@ -1242,22 +1247,25 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
 		return false;
 	}
 
-	// Update the existing unique notification with the data from this particular instance...
-	// This guarantees that duplicate notifications will be collapsed to the one
-	// most recently triggered
-	for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
-		existing_it != mUniqueNotifications.end();
-		++existing_it)
+	if (pNotif->getCombineBehavior() == LLNotification::USE_NEWEST)
 	{
-		LLNotificationPtr existing_notification = existing_it->second;
-		if (pNotif != existing_notification 
-			&& pNotif->isEquivalentTo(existing_notification))
+		// Update the existing unique notification with the data from this particular instance...
+		// This guarantees that duplicate notifications will be collapsed to the one
+		// most recently triggered
+		for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
+			existing_it != mUniqueNotifications.end();
+			++existing_it)
 		{
-			// copy notification instance data over to oldest instance
-			// of this unique notification and update it
-			existing_notification->updateFrom(pNotif);
-			// then delete the new one
-			cancel(pNotif);
+			LLNotificationPtr existing_notification = existing_it->second;
+			if (pNotif != existing_notification 
+				&& pNotif->isEquivalentTo(existing_notification))
+			{
+				// copy notification instance data over to oldest instance
+				// of this unique notification and update it
+				existing_notification->updateFrom(pNotif);
+				// then delete the new one
+				cancel(pNotif);
+			}
 		}
 	}
 
@@ -1296,10 +1304,7 @@ void LLNotifications::createDefaultChannels()
 		boost::bind(&LLNotifications::isVisibleByRules, this, _1)));
 	mDefaultChannels.push_back(new LLNotificationChannel("Visible", "VisibilityRules",
 		&LLNotificationFilters::includeEverything));
-
-	// create special persistent notification channel
-	// this isn't a leak, don't worry about the empty "new"
-	new LLPersistentNotificationChannel();
+	mDefaultChannels.push_back(new LLPersistentNotificationChannel());
 
 	// connect action methods to these channels
 	LLNotifications::instance().getChannel("Enabled")->
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 344108ecbf..4e2b997156 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -297,6 +297,7 @@ LOG_CLASS(LLNotification);
 friend class LLNotifications;
 
 public:
+
 	// parameter object used to instantiate a new notification
 	struct Params : public LLInitParam::Block<Params>
 	{
@@ -518,6 +519,13 @@ public:
 	bool canLogToIM() const;
 	bool hasFormElements() const;
 
+	typedef enum e_combine_behavior
+	{
+		USE_NEWEST,
+		USE_OLDEST
+	} ECombineBehavior;
+
+	ECombineBehavior getCombineBehavior() const;
 	const LLNotificationFormPtr getForm();
 
 	const LLDate getExpiration() const
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 1df7205b23..8080acbf87 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -61,6 +61,17 @@ typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
 // from the appropriate local language directory).
 struct LLNotificationTemplate
 {
+	struct CombineBehaviorNames
+		:	public LLInitParam::TypeValuesHelper<LLNotification::ECombineBehavior, CombineBehaviorNames>
+	{
+		static void declareValues()
+		{
+			declare("newest", LLNotification::USE_NEWEST);
+			declare("oldest", LLNotification::USE_OLDEST);
+		}
+	};
+
+
 	struct GlobalString : public LLInitParam::Block<GlobalString>
 	{
 		Mandatory<std::string>	name,
@@ -94,9 +105,11 @@ struct LLNotificationTemplate
 		Optional<LLInitParam::Flag>	dummy_val;
 	public:
 		Multiple<UniquenessContext>	contexts;
+		Optional<LLNotification::ECombineBehavior, CombineBehaviorNames> combine;
 
 		UniquenessConstraint()
 		:	contexts("context"),
+			combine("combine", LLNotification::USE_NEWEST),
 			dummy_val("")
 		{}
 	};
@@ -249,6 +262,7 @@ struct LLNotificationTemplate
     // (used for things like progress indications, or repeating warnings
     // like "the grid is going down in N minutes")
     bool mUnique;
+	LLNotification::ECombineBehavior mCombineBehavior;
     // if we want to be unique only if a certain part of the payload or substitutions args
 	// are constant specify the field names for the payload. The notification will only be
     // combined if all of the fields named in the context are identical in the
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 67519a3ca6..b4c70b6edb 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -393,9 +393,15 @@ void LLNotificationChiclet::setCounter(S32 counter)
 	
 }
 
-bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notify )
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
 {
-	return !(notify->canLogToIM() && notify->hasFormElements());
+	if( !(notification->canLogToIM() && notification->hasFormElements())
+		&& (!notification->getPayload().has("give_inventory_notification")
+			|| notification->getPayload()["give_inventory_notification"]))
+	{
+		return true;
+	}
+	return false;
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 419b8a14b6..21f3961d18 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -94,7 +94,7 @@ public:
 
 	// base interface functions
 	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
 	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel) mChannel->killToastByNotificationID(p->getID());}
 
 	virtual bool processNotification(const LLNotificationPtr& notify)=0;
@@ -130,7 +130,7 @@ public:
 
 protected:
 	bool processNotification(const LLNotificationPtr& p);
-	virtual void initChannel();
+	/*virtual*/ void initChannel();
 };
 
 /**
@@ -144,11 +144,12 @@ public:
 	virtual ~LLTipHandler();
 
 	// base interface functions
-	virtual bool processNotification(const LLNotificationPtr& p);
+	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onRejectToast(const LLUUID& id);
-	virtual void initChannel();
+	/*virtual*/ void onRejectToast(const LLUUID& id);
+	/*virtual*/ void initChannel();
 };
 
 /**
@@ -161,13 +162,13 @@ public:
 	LLScriptHandler();
 	virtual ~LLScriptHandler();
 
-	virtual void onDelete(LLNotificationPtr p);
+	/*virtual*/ void onDelete(LLNotificationPtr p);
 	// base interface functions
-	virtual bool processNotification(const LLNotificationPtr& p);
+	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
-	virtual void initChannel();
+	/*virtual*/ void onDeleteToast(LLToast* toast);
+	/*virtual*/ void initChannel();
 
 	// own handlers
 	void onRejectToast(LLUUID& id);
@@ -184,7 +185,8 @@ public:
 	virtual ~LLGroupHandler();
 	
 	// base interface functions
-	virtual bool processNotification(const LLNotificationPtr& p);
+	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void initChannel();
@@ -204,9 +206,7 @@ public:
 
 	/*virtual*/ void onChange(LLNotificationPtr p);
 	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
-
-	// base interface functions
-	virtual bool processNotification(const LLNotificationPtr& p);
+	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void initChannel();
@@ -225,11 +225,12 @@ public:
 	virtual ~LLOfferHandler();
 
 	// base interface functions
+	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
 	/*virtual*/ void onDelete(LLNotificationPtr notification);
-	virtual bool processNotification(const LLNotificationPtr& p);
+	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void initChannel();
+	/*virtual*/ void initChannel();
 
 	// own handlers
 	void onRejectToast(LLUUID& id);
@@ -246,7 +247,7 @@ public:
 	virtual ~LLHintHandler() {}
 
 	/*virtual*/ void onAdd(LLNotificationPtr p);
-	/*virtual*/ void onChange(LLNotificationPtr p);
+	/*virtual*/ void onLoad(LLNotificationPtr p);
 	/*virtual*/ void onDelete(LLNotificationPtr p);
 };
 
diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp
index 47156a3915..271f418507 100644
--- a/indra/newview/llnotificationhinthandler.cpp
+++ b/indra/newview/llnotificationhinthandler.cpp
@@ -34,5 +34,5 @@
 using namespace LLNotificationsUI;
 
 void LLHintHandler::onAdd(LLNotificationPtr p) { LLHints::show(p); }
-void LLHintHandler::onChange(LLNotificationPtr p) { LLHints::show(p); }
+void LLHintHandler::onLoad(LLNotificationPtr p) { LLHints::show(p); }
 void LLHintHandler::onDelete(LLNotificationPtr p) { LLHints::hide(p); }
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 5301955964..cc68c4c91a 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -251,7 +251,14 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
 {
 	bool store_toast = false, show_toast = false;
 
-	mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+	if (mDisplayToastsAlways)
+	{
+		show_toast = true;
+	}
+	else
+	{
+		show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+	}
 	store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;
 
 	if(!show_toast && !store_toast)
-- 
cgit v1.2.3


From 10503b13e0cd5b6f89d885982b72ed23ec131e85 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 5 Apr 2012 19:22:37 +0300
Subject: CHUI-77 WIP People panel layout change: filter pane moved inside the
 tab.

---
 .../newview/skins/default/xui/en/panel_people.xml  | 587 ++++++++++-----------
 1 file changed, 285 insertions(+), 302 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 98c7c49ff4..919661eff6 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -60,21 +60,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 	<string
 	 name="AltMiniMapToolTipMsg"
 	 value="[REGION](Double-click to teleport, shift-drag to pan)"/>
-	<filter_editor
-     follows="left|top|right"
-     height="23"
-     layout="topleft"
-     left="10"
-     label="Filter"
-     max_length_chars="300"
-     name="filter_input"
-     text_color="Black"
-     text_pad_left="10"
-     top="3"
-     width="303" />
     <tab_container
      follows="all"
-     height="383"
+     height="419"
      layout="topleft"
      left="3"
      name="tabs"
@@ -82,10 +70,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      tab_min_width="70"
      tab_height="30"
      tab_position="top"
-     top_pad="10"
+     top="0"
      halign="center"
      width="319">
-     	<panel
+        <panel
          background_opaque="true"
          background_visible="true"
          bg_alpha_color="DkGray"
@@ -99,13 +87,85 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          name="nearby_panel"
          top="0"
          width="313">
+            <panel
+             follows="left|top|right"
+             height="27"
+             label="bottom_panel"
+             layout="topleft"
+             left="0"
+             name="nearby_buttons_panel"
+             top="0"
+             width="313">
+                <filter_editor
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left="3"
+                 label="Filter"
+                 max_length_chars="300"
+                 name="nearby_filter_input"
+                 text_color="Black"
+                 text_pad_left="10"
+                 top="2"
+                 width="167" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="10"
+                 name="nearby_sort_btn"
+                 top="1"
+                 width="31" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Hierarchy_View_Disabled"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="nearby_view_btn"
+                 top="1"
+                 width="31" />
+                <button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="nearby_add_btn"
+                 top="1"
+                 width="31" />
+                <dnd_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TrashItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 left_pad="2"
+                 layout="topleft"
+                 name="nearby_del_btn"
+                 top="1"
+                 width="31"/>
+            </panel>
          <layout_stack
            clip="false"
            follows="all"
            height="355"
            layout="topleft"
+           left="0"
            mouse_opaque="false"
            orientation="vertical"
+           top_pad="0"
            width="313">
            <layout_panel
              height="142"
@@ -147,54 +207,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                width="306" />
            </layout_panel>
          </layout_stack>
-         <panel
-             background_visible="true"
-             follows="left|right|bottom"
-             height="27"
-             label="bottom_panel"
-             layout="topleft"
-             left="3"
-             name="bottom_panel"
-             top_pad="0"
-             width="313">
-             <menu_button
-             follows="bottom|left"
-             height="25"
-             image_hover_unselected="Toolbar_Left_Over"
-             image_overlay="OptionsMenu_Off"
-             image_selected="Toolbar_Left_Selected"
-             image_unselected="Toolbar_Left_Off"
-             layout="topleft"
-             left="0"
-             name="nearby_view_sort_btn"
-             tool_tip="Options"
-             top="1"
-             width="31" />
-             <button
-                 follows="bottom|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-             	 image_overlay="AddItem_Off"
-                 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 left_pad="1"
-                 name="add_friend_btn"
-                 tool_tip="Add selected Resident to your friends List"
-                 width="31">
-               <commit_callback
-                  function="People.addFriend" />
-             </button>
-             <icon
-             follows="bottom|left|right"
-             height="25"
-             image_name="Toolbar_Right_Off"
-             layout="topleft"
-             left_pad="1"
-             name="dummy_icon"
-             width="243"
-             />
-            </panel>
         </panel>
         <panel
          background_opaque="true"
@@ -210,6 +222,76 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          name="friends_panel"
          top="0"
          width="313">
+            <panel
+             follows="left|top|right"
+             height="27"
+             label="bottom_panel"
+             layout="topleft"
+             left="0"
+             name="friends_buttons_panel"
+             top="0"
+             width="313">
+                <filter_editor
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left="3"
+                 label="Filter"
+                 max_length_chars="300"
+                 name="friends_filter_input"
+                 text_color="Black"
+                 text_pad_left="10"
+                 top="2"
+                 width="167" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="10"
+                 name="friends_sort_btn"
+                 top="1"
+                 width="31" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Hierarchy_View_Disabled"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="friends_view_btn"
+                 top="1"
+                 width="31" />
+                <button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="friends_add_btn"
+                 top="1"
+                 width="31" />
+                <dnd_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TrashItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 left_pad="2"
+                 layout="topleft"
+                 name="friends_del_btn"
+                 top="1"
+                 width="31"/>
+            </panel>
             <accordion
        		 background_visible="true"
        		 bg_alpha_color="DkGray2"
@@ -219,7 +301,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              layout="topleft"
              left="3"
              name="friends_accordion"
-             top="0"
+             top_pad="0"
              width="307">
                 <accordion_tab
                  layout="topleft"
@@ -257,153 +339,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                          width="307" />
                 </accordion_tab>
             </accordion>
-            <panel
-             background_visible="true"
-             follows="left|right|bottom"
-             height="27"
-             label="bottom_panel"
-             layout="topleft"
-             left="3"
-             name="bottom_panel"
-             top_pad="0"
-             width="313">
-             
-             	  <layout_stack
-				   animate="false"
-				   border_size="0"
-				   follows="left|right|bottom"
-				   height="25"
-				   layout="topleft"
-				   orientation="horizontal"
-				   top_pad="1"
-				   left="0"
-				   name="bottom_panel"
-				   width="308">
-				      <layout_panel
-				       auto_resize="false"
-				       height="25"
-				       layout="topleft"
-				       name="options_gear_btn_panel"
-				       width="32">
-				          <menu_button
-				           follows="bottom|left"
-				           tool_tip="Show additional options"
-				           height="25"
-				           image_hover_unselected="Toolbar_Left_Over"
-				           image_overlay="OptionsMenu_Off"
-				           image_selected="Toolbar_Left_Selected"
-				           image_unselected="Toolbar_Left_Off"
-				           layout="topleft"
-				           left="0"
-				           name="friends_viewsort_btn"
-				           top="0"
-				           width="31" />
-				      </layout_panel>
-				      <layout_panel
-				       auto_resize="false"
-				       height="25"
-				       layout="topleft"
-				       name="add_btn_panel"
-				       width="32">
-				          <button
-				           follows="bottom|left"
-				           height="25"
-				           image_hover_unselected="Toolbar_Middle_Over"
-				           image_overlay="AddItem_Off"
-				           image_selected="Toolbar_Middle_Selected"
-				           image_unselected="Toolbar_Middle_Off"
-				           layout="topleft"
-				           left="0"
-				           name="add_btn"
-				           tool_tip="Offer friendship to a Resident"
-				           top="0"
-				           width="31" />
-				      </layout_panel>
-				      <layout_panel
-				       auto_resize="true"
-				       height="25"
-				       layout="topleft"
-				       name="dummy_panel"
-				       width="210">
-				          <icon
-				           follows="bottom|left|right"
-				           height="25"
-				           image_name="Toolbar_Middle_Off"
-				           layout="topleft"
-				           left="0"
-				           top="0"
-				           name="dummy_icon"
-				           width="210" />
-				      </layout_panel>
-				      <layout_panel
-				       auto_resize="false"
-				       height="25"
-				       layout="topleft"
-				       name="trash_btn_panel"
-				       width="31">
-				          <dnd_button
-				           follows="bottom|left"
-				           height="25"
-				           image_hover_unselected="Toolbar_Right_Over"
-				           image_overlay="TrashItem_Off"
-				           image_selected="Toolbar_Right_Selected"
-				           image_unselected="Toolbar_Right_Off"
-				           left="0"
-				           layout="topleft"
-				           name="del_btn"
-				           tool_tip="Remove selected person from your Friends list"
-				           top="0"
-				           width="31"/>
-				      </layout_panel>
-				  </layout_stack><!--
-             
-               <button
-               follows="bottom|left"
-               tool_tip="Options"
-               height="25"
-               image_hover_unselected="Toolbar_Left_Over"
-               image_overlay="OptionsMenu_Off"
-               image_selected="Toolbar_Left_Selected"
-               image_unselected="Toolbar_Left_Off"
-               layout="topleft"
-               left="0"
-               name="friends_viewsort_btn"
-               top="1"
-               width="31" />
-                <button
-                 follows="bottom|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-             	 image_overlay="AddItem_Off"
-             	 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 left_pad="1"
-                 name="add_btn"
-                 tool_tip="Offer friendship to a Resident"
-                 width="31" />
-                <icon
-             	 follows="bottom|left|right"
-             	 height="25"
-             	 image_name="Toolbar_Middle_Off"
-             	 layout="topleft"
-             	 left_pad="1"
-             	 name="dummy_icon"
-             	 width="209"
-             />
-                <button
-                 follows="bottom|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Right_Over"
-                 image_overlay="TrashItem_Off"
-                 image_selected="Toolbar_Right_Selected"
-                 image_unselected="Toolbar_Right_Off"
-                 layout="topleft"
-                 left_pad="1"
-                 name="del_btn"
-                 tool_tip="Remove selected person from your Friends list"
-                 width="31" />
-            --></panel>
             <text
              follows="all"
              height="450"
@@ -431,72 +366,97 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      *NOTE: no_groups_msg & group_list attributes are not defined as translatable in VLT. See EXT-5931
      Values are set from appropriate strings at the top of file via LLPeoplePanel::postBuild()
     -->
-            <group_list
-             allow_select="true" 
-             follows="all"
-             height="356"
-             layout="topleft"
-             left="3"
-             name="group_list"
-             top="0"
-             width="307" />
             <panel
-             background_visible="true"
-             follows="left|right|bottom"
+             follows="left|top|right"
              height="27"
              label="bottom_panel"
              layout="topleft"
              left="0"
-             name="bottom_panel"
-             top_pad="0"
+             name="groups_buttons_panel"
+             top="0"
              width="313">
-               <menu_button
-               follows="bottom|left"
-               tool_tip="Options"
-               height="25"
-               image_hover_unselected="Toolbar_Left_Over"
-               image_overlay="OptionsMenu_Off"
-               image_selected="Toolbar_Left_Selected"
-               image_unselected="Toolbar_Left_Off"
-               layout="topleft"
-               left="3"
-               name="groups_viewsort_btn"
-               top="1"
-               width="31" />
-                <button
-                 follows="bottom|left"
+                <filter_editor
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left="3"
+                 label="Filter"
+                 max_length_chars="300"
+                 name="groups_filter_input"
+                 text_color="Black"
+                 text_pad_left="10"
+                 top="2"
+                 width="134" />
+                <menu_button
+                 follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="AddItem_Off"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="10"
+                 name="groups_sort_btn"
+                 top="1"
+                 width="31" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Hierarchy_View_Disabled"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="1"
-                 name="plus_btn"
-                 tool_tip="Join group/Create new group"
+                 left_pad="2"
+                 name="groups_view_btn"
+                 top="1"
                  width="31" />
                 <button
-                 follows="bottom|left"
+                 follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
                  image_overlay="Activate_Checkmark"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="1"
-                 name="activate_btn"
-                 tool_tip="Activate selected group"
+                 left_pad="2"
+                 name="groups_activate_btn"
+                 top="1"
                  width="31" />
-                 <icon
-             	 follows="bottom|left|right"
-             	 height="25"
-             	 image_name="Toolbar_Right_Off"
-             	 layout="topleft"
-             	 left_pad="1"
-             	 name="dummy_icon"
-             	 width="212"
-             />
+                <button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="groups_add_btn"
+                 top="1"
+                 width="31" />
+                <dnd_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TrashItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 left_pad="2"
+                 layout="topleft"
+                 name="groups_del_btn"
+                 top="1"
+                 width="31"/>
             </panel>
+            <group_list
+             allow_select="true" 
+             follows="all"
+             height="356"
+             layout="topleft"
+             left="3"
+             name="group_list"
+             top_pad="0"
+             width="307" />
         </panel>
         <panel
          background_opaque="true"
@@ -512,64 +472,87 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          name="recent_panel"
          top="0"
          width="313">
-            <avatar_list
-             allow_select="true"
-             follows="all"
-             height="356"
-             layout="topleft"
-             left="3"
-             multi_select="true"
-             name="avatar_list"
-             show_last_interaction_time="true"
-             top="0"
-             width="307" />
             <panel
-             background_visible="true"
-             follows="left|right|bottom"
+             follows="left|top|right"
              height="27"
              label="bottom_panel"
              layout="topleft"
-             left="3"
-             name="bottom_panel"
-             top_pad="0"
+             left="0"
+             name="recent_buttons_panel"
+             top="0"
              width="313">
-               <menu_button
-               follows="bottom|left"
-               tool_tip="Options"
-               height="25"
-               image_hover_unselected="Toolbar_Left_Over"
-               image_overlay="OptionsMenu_Off"
-               image_selected="Toolbar_Left_Selected"
-               image_unselected="Toolbar_Left_Off"
-               layout="topleft"
-               name="recent_viewsort_btn"
-               top="1"
-               width="31" />
-              <button
-                 follows="bottom|left"
+                <filter_editor
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left="3"
+                 label="Filter"
+                 max_length_chars="300"
+                 name="recent_filter_input"
+                 text_color="Black"
+                 text_pad_left="10"
+                 top="2"
+                 width="167" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="10"
+                 name="recent_sort_btn"
+                 top="1"
+                 width="31" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Hierarchy_View_Disabled"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="recent_view_btn"
+                 top="1"
+                 width="31" />
+                <button
+                 follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
                  image_overlay="AddItem_Off"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="1"
-                 name="add_friend_btn"
-                 tool_tip="Add selected Resident to your friends List"
-                 width="31">
-                <commit_callback
-                   function="People.addFriend" />
-              </button>
-              <icon
-             	 follows="bottom|left|right"
-             	 height="25"
-             	 image_name="Toolbar_Right_Off"
-             	 layout="topleft"
-             	 left_pad="1"
-             	 name="dummy_icon"
-             	 width="244"
-             />
+                 left_pad="2"
+                 name="recent_add_btn"
+                 top="1"
+                 width="31" />
+                <dnd_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TrashItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 left_pad="2"
+                 layout="topleft"
+                 name="recent_del_btn"
+                 top="1"
+                 width="31"/>
             </panel>
+            <avatar_list
+             allow_select="true"
+             follows="all"
+             height="356"
+             layout="topleft"
+             left="3"
+             multi_select="true"
+             name="avatar_list"
+             show_last_interaction_time="true"
+             top_pad="0"
+             width="307" />
         </panel>
     </tab_container>
     <panel
-- 
cgit v1.2.3


From e5c0cfdc5a0dd20afbec047049cbd920686cb55d Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Wed, 4 Apr 2012 22:04:38 +0300
Subject: CHUI-78 WIP Fixed parsing of menu_button.menu_position XUI parameter.

---
 indra/llui/llmenubutton.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index e2396e7fb2..84e63911a3 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -53,7 +53,7 @@ public:
 	{
 		// filename for it's toggleable menu
 		Optional<std::string>	menu_filename;
-		Optional<EMenuPosition>	position;
+		Optional<EMenuPosition, MenuPositions>	position;
 	
 		Params();
 	};
-- 
cgit v1.2.3


From 69cf10a1e9b969a1c87473a8b153281dc60e7b56 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Thu, 5 Apr 2012 17:29:25 +0300
Subject: CHUI-78 WIP Renamamed menu_button.position XUI attribute to
 menu_position for consistency with menu_filename.

---
 indra/llui/llmenubutton.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 50d59f79f4..cfae524f3b 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -44,8 +44,9 @@ void LLMenuButton::MenuPositions::declareValues()
 
 LLMenuButton::Params::Params()
 :	menu_filename("menu_filename"),
-	position("position", MP_BOTTOM_LEFT)
+	position("menu_position", MP_BOTTOM_LEFT)
 {
+	addSynonym(position, "position");
 }
 
 
-- 
cgit v1.2.3


From 177c1f80bc132fdad4e46009b074c0609454332f Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Thu, 5 Apr 2012 20:37:28 +0300
Subject: CHUI-78 WIP Enabled LLMenuButton to manage its menu's lifetime.

---
 indra/llui/llmenubutton.cpp | 53 +++++++++++++++++++++++++++++++--------------
 indra/llui/llmenubutton.h   |  9 +++++++-
 2 files changed, 45 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index cfae524f3b..2f5e29c36e 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -53,25 +53,18 @@ LLMenuButton::Params::Params()
 LLMenuButton::LLMenuButton(const LLMenuButton::Params& p)
 :	LLButton(p),
 	mIsMenuShown(false),
-	mMenuPosition(p.position)
+	mMenuPosition(p.position),
+	mOwnMenu(false)
 {
 	std::string menu_filename = p.menu_filename;
 
-	if (!menu_filename.empty())
-	{
-		LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
-		if (!menu)
-		{
-			llwarns << "Error loading menu_button menu" << llendl;
-			return;
-		}
-
-		menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
-
-		mMenuHandle = menu->getHandle();
+	setMenu(menu_filename, mMenuPosition);
+	updateMenuOrigin();
+}
 
-		updateMenuOrigin();
-	}
+LLMenuButton::~LLMenuButton()
+{
+	cleanup();
 }
 
 boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
@@ -95,12 +88,32 @@ LLToggleableMenu* LLMenuButton::getMenu()
 	return dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
 }
 
-void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/)
+void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition position /*MP_TOP_LEFT*/)
+{
+	if (menu_filename.empty())
+	{
+		return;
+	}
+
+	LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+	if (!menu)
+	{
+		llwarns << "Error loading menu_button menu" << llendl;
+		return;
+	}
+
+	setMenu(menu, position, true);
+}
+
+void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/, bool take_ownership /*false*/)
 {
 	if (!menu) return;
 
+	cleanup(); // destroy the previous memnu if we own it
+
 	mMenuHandle = menu->getHandle();
 	mMenuPosition = position;
+	mOwnMenu = take_ownership;
 
 	menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
 }
@@ -212,3 +225,11 @@ void LLMenuButton::onMenuVisibilityChange(const LLSD& param)
 		mIsMenuShown = false;
 	}
 }
+
+void LLMenuButton::cleanup()
+{
+	if (mMenuHandle.get() && mOwnMenu)
+	{
+		mMenuHandle.get()->die();
+	}
+}
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index 84e63911a3..67ec1983b3 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -34,6 +34,8 @@ class LLToggleableMenu;
 class LLMenuButton
 : public LLButton
 {
+	LOG_CLASS(LLMenuButton);
+
 public:
 	typedef enum e_menu_position
 	{
@@ -68,13 +70,15 @@ public:
 	void hideMenu();
 
 	LLToggleableMenu* getMenu();
-	void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT);
+	void setMenu(const std::string& menu_filename, EMenuPosition position = MP_TOP_LEFT);
+	void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT, bool take_ownership = false);
 
 	void setMenuPosition(EMenuPosition position) { mMenuPosition = position; }
 
 protected:
 	friend class LLUICtrlFactory;
 	LLMenuButton(const Params&);
+	~LLMenuButton();
 
 	void toggleMenu();
 	void updateMenuOrigin();
@@ -82,11 +86,14 @@ protected:
 	void onMenuVisibilityChange(const LLSD& param);
 
 private:
+	void cleanup();
+
 	LLHandle<LLView>		mMenuHandle;
 	bool					mIsMenuShown;
 	EMenuPosition			mMenuPosition;
 	S32						mX;
 	S32						mY;
+	bool					mOwnMenu; // true if we manage the menu lifetime
 };
 
 
-- 
cgit v1.2.3


From 2dc032e3e582d39a04c40b7cfb3366424491b491 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Thu, 5 Apr 2012 22:56:18 +0300
Subject: CHUI-78 WIP Added drop-down menus and connected callbacks to the new
 view/sort/add/remove buttons.

---
 indra/llui/llmenubutton.cpp                        |   5 +
 indra/newview/llpanelpeople.cpp                    | 137 +++++--------------
 indra/newview/llpanelpeople.h                      |  16 +--
 .../skins/default/xui/en/menu_group_plus.xml       |   4 +-
 .../default/xui/en/menu_people_friends_sort.xml    |  26 ++++
 .../default/xui/en/menu_people_friends_view.xml    |  26 ++++
 .../xui/en/menu_people_friends_view_sort.xml       |  47 -------
 .../default/xui/en/menu_people_groups_view.xml     |  17 +++
 .../xui/en/menu_people_groups_view_sort.xml        |  26 ----
 .../default/xui/en/menu_people_nearby_sort.xml     |  36 +++++
 .../default/xui/en/menu_people_nearby_view.xml     |  31 +++++
 .../xui/en/menu_people_nearby_view_sort.xml        |  57 --------
 .../default/xui/en/menu_people_recent_sort.xml     |  26 ++++
 .../default/xui/en/menu_people_recent_view.xml     |  18 +++
 .../xui/en/menu_people_recent_view_sort.xml        |  39 ------
 .../newview/skins/default/xui/en/panel_people.xml  | 152 ++++++++++++++++-----
 16 files changed, 339 insertions(+), 324 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_friends_sort.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_friends_view.xml
 delete mode 100644 indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_groups_view.xml
 delete mode 100644 indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_nearby_sort.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
 delete mode 100644 indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_recent_sort.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_recent_view.xml
 delete mode 100644 indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml

(limited to 'indra')

diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 2f5e29c36e..98f7e0540c 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -153,6 +153,11 @@ BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask)
 
 void LLMenuButton::toggleMenu()
 {
+	if (mValidateSignal && !(*mValidateSignal)(this, LLSD()))
+	{
+		return;
+	}
+
 	if(mMenuHandle.isDead()) return;
 
 	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 9c46f04abf..238834aa92 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -501,17 +501,38 @@ LLPanelPeople::LLPanelPeople()
 		mNearbyList(NULL),
 		mRecentList(NULL),
 		mGroupList(NULL),
-		mNearbyGearButton(NULL),
-		mFriendsGearButton(NULL),
-		mGroupsGearButton(NULL),
-		mRecentGearButton(NULL),
 		mMiniMap(NULL)
 {
 	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList,	this));
 	mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList,	this));
 	mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList,	this));
 	mButtonsUpdater = new LLButtonsUpdater(boost::bind(&LLPanelPeople::updateButtons, this));
-	mCommitCallbackRegistrar.add("People.addFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+
+	mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+	mCommitCallbackRegistrar.add("People.AddFriendWizard",	boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.DelFriend",		boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.Group.Activate",	boost::bind(&LLPanelPeople::onActivateButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.Group.Minus",		boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this));
+	mCommitCallbackRegistrar.add("People.ViewProfile",	boost::bind(&LLPanelPeople::onViewProfileButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.GroupInfo",	boost::bind(&LLPanelPeople::onGroupInfoButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.Chat",			boost::bind(&LLPanelPeople::onChatButtonClicked,		this));
+	mCommitCallbackRegistrar.add("People.IM",			boost::bind(&LLPanelPeople::onImButtonClicked,			this));
+	mCommitCallbackRegistrar.add("People.Call",			boost::bind(&LLPanelPeople::onCallButtonClicked,		this));
+	mCommitCallbackRegistrar.add("People.GroupCall",	boost::bind(&LLPanelPeople::onGroupCallButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.Teleport",		boost::bind(&LLPanelPeople::onTeleportButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.Share",		boost::bind(&LLPanelPeople::onShareButtonClicked,		this));
+
+	mCommitCallbackRegistrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2));
+	mCommitCallbackRegistrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2));
+	mCommitCallbackRegistrar.add("People.Nearby.ViewSort.Action",  boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked,  this, _2));
+	mCommitCallbackRegistrar.add("People.Groups.ViewSort.Action",  boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked,  this, _2));
+	mCommitCallbackRegistrar.add("People.Recent.ViewSort.Action",  boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked,  this, _2));
+
+	mEnableCallbackRegistrar.add("People.Friends.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck,	this, _2));
+	mEnableCallbackRegistrar.add("People.Recent.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck,	this, _2));
+	mEnableCallbackRegistrar.add("People.Nearby.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck,	this, _2));
+
+	mEnableCallbackRegistrar.add("People.Group.Plus.Validate",	boost::bind(&LLPanelPeople::onGroupPlusButtonValidate,	this));
 }
 
 LLPanelPeople::~LLPanelPeople()
@@ -525,13 +546,6 @@ LLPanelPeople::~LLPanelPeople()
 	{
 		LLVoiceClient::getInstance()->removeObserver(this);
 	}
-
-	if (mGroupPlusMenuHandle.get()) mGroupPlusMenuHandle.get()->die();
-	if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
-	if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
-	if (mGroupsViewSortMenuHandle.get()) mGroupsViewSortMenuHandle.get()->die();
-	if (mRecentViewSortMenuHandle.get()) mRecentViewSortMenuHandle.get()->die();
-
 }
 
 void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list)
@@ -601,14 +615,6 @@ BOOL LLPanelPeople::postBuild()
 	setSortOrder(mAllFriendList,	(ESortOrder)gSavedSettings.getU32("FriendsSortOrder"),		false);
 	setSortOrder(mNearbyList,		(ESortOrder)gSavedSettings.getU32("NearbyPeopleSortOrder"),	false);
 
-	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));
-
-	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));
-
 	mOnlineFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
 	mAllFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
 	mNearbyList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
@@ -637,70 +643,9 @@ BOOL LLPanelPeople::postBuild()
 	accordion_tab->setDropDownStateChangedCallback(
 		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mOnlineFriendList));
 
-	buttonSetAction("view_profile_btn",	boost::bind(&LLPanelPeople::onViewProfileButtonClicked,	this));
-	buttonSetAction("group_info_btn",	boost::bind(&LLPanelPeople::onGroupInfoButtonClicked,	this));
-	buttonSetAction("chat_btn",			boost::bind(&LLPanelPeople::onChatButtonClicked,		this));
-	buttonSetAction("im_btn",			boost::bind(&LLPanelPeople::onImButtonClicked,			this));
-	buttonSetAction("call_btn",			boost::bind(&LLPanelPeople::onCallButtonClicked,		this));
-	buttonSetAction("group_call_btn",	boost::bind(&LLPanelPeople::onGroupCallButtonClicked,	this));
-	buttonSetAction("teleport_btn",		boost::bind(&LLPanelPeople::onTeleportButtonClicked,	this));
-	buttonSetAction("share_btn",		boost::bind(&LLPanelPeople::onShareButtonClicked,		this));
-
 	// Must go after setting commit callback and initializing all pointers to children.
 	mTabContainer->selectTabByName(NEARBY_TAB_NAME);
 
-	// Create menus.
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-	
-	registrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2));
-	registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this));
-	registrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2));
-	registrar.add("People.Nearby.ViewSort.Action",  boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked,  this, _2));
-	registrar.add("People.Groups.ViewSort.Action",  boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked,  this, _2));
-	registrar.add("People.Recent.ViewSort.Action",  boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked,  this, _2));
-
-	enable_registrar.add("People.Group.Minus.Enable",	boost::bind(&LLPanelPeople::isRealGroup,	this));
-	enable_registrar.add("People.Friends.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck,	this, _2));
-	enable_registrar.add("People.Recent.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck,	this, _2));
-	enable_registrar.add("People.Nearby.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck,	this, _2));
-
-	mNearbyGearButton = getChild<LLMenuButton>("nearby_view_sort_btn");
-	mFriendsGearButton = getChild<LLMenuButton>("friends_viewsort_btn");
-	mGroupsGearButton = getChild<LLMenuButton>("groups_viewsort_btn");
-	mRecentGearButton = getChild<LLMenuButton>("recent_viewsort_btn");
-
-	LLMenuGL* plus_menu  = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	mGroupPlusMenuHandle  = plus_menu->getHandle();
-
-	LLToggleableMenu* nearby_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_nearby_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(nearby_view_sort)
-	{
-		mNearbyViewSortMenuHandle  = nearby_view_sort->getHandle();
-		mNearbyGearButton->setMenu(nearby_view_sort);
-	}
-
-	LLToggleableMenu* friend_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_friends_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(friend_view_sort)
-	{
-		mFriendsViewSortMenuHandle  = friend_view_sort->getHandle();
-		mFriendsGearButton->setMenu(friend_view_sort);
-	}
-
-	LLToggleableMenu* group_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(group_view_sort)
-	{
-		mGroupsViewSortMenuHandle  = group_view_sort->getHandle();
-		mGroupsGearButton->setMenu(group_view_sort);
-	}
-
-	LLToggleableMenu* recent_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_recent_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(recent_view_sort)
-	{
-		mRecentViewSortMenuHandle  = recent_view_sort->getHandle();
-		mRecentGearButton->setMenu(recent_view_sort);
-	}
-
 	LLVoiceClient::getInstance()->addObserver(this);
 
 	// call this method in case some list is empty and buttons can be in inconsistent state
@@ -835,13 +780,6 @@ void LLPanelPeople::buttonSetEnabled(const std::string& btn_name, bool enabled)
 	button->setEnabled(enabled);
 }
 
-void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb)
-{
-	// To make sure we're referencing the right widget (a child of the button bar).
-	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
-	button->setClickedCallback(cb);
-}
-
 void LLPanelPeople::updateButtons()
 {
 	std::string cur_tab		= getActiveTabName();
@@ -877,7 +815,7 @@ void LLPanelPeople::updateButtons()
 
 		LLPanel* groups_panel = mTabContainer->getCurrentPanel();
 		groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected
-		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull());
+		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
 	}
 	else
 	{
@@ -893,10 +831,12 @@ void LLPanelPeople::updateButtons()
 		LLPanel* cur_panel = mTabContainer->getCurrentPanel();
 		if (cur_panel)
 		{
-			cur_panel->getChildView("add_friend_btn")->setEnabled(!is_friend);
+			if (cur_panel->hasChild("add_friend_btn", TRUE))
+				cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend);
+
 			if (friends_tab_active)
 			{
-				cur_panel->getChildView("del_btn")->setEnabled(multiple_selected);
+				cur_panel->getChildView("friends_del_btn")->setEnabled(multiple_selected);
 			}
 		}
 	}
@@ -1031,11 +971,6 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save
 	}
 }
 
-bool LLPanelPeople::isRealGroup()
-{
-	return getCurrentItemID() != LLUUID::null;
-}
-
 void LLPanelPeople::onFilterEdit(const std::string& search_string)
 {
 	mFilterSubStringOrig = search_string;
@@ -1226,19 +1161,15 @@ void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAv
 		LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getCompleteName());
 }
 
-void LLPanelPeople::onGroupPlusButtonClicked()
+bool LLPanelPeople::onGroupPlusButtonValidate()
 {
 	if (!gAgent.canJoinGroups())
 	{
 		LLNotificationsUtil::add("JoinedTooManyGroups");
-		return;
+		return false;
 	}
 
-	LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
-	if (!plus_menu)
-		return;
-
-	showGroupMenu(plus_menu);
+	return true;
 }
 
 void LLPanelPeople::onGroupMinusButtonClicked()
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 46c58cd139..684dcdeb6d 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -82,7 +82,6 @@ private:
 	void					getCurrentItemIDs(uuid_vec_t& selected_uuids) const;
 	void					buttonSetVisible(std::string btn_name, BOOL visible);
 	void					buttonSetEnabled(const std::string& btn_name, bool enabled);
-	void					buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb);
 	void					showGroupMenu(LLMenuGL* menu);
 	void					setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true);
 
@@ -104,7 +103,7 @@ private:
 	void					onActivateButtonClicked();
 	void					onAvatarListDoubleClicked(LLUICtrl* ctrl);
 	void					onAvatarListCommitted(LLAvatarList* list);
-	void					onGroupPlusButtonClicked();
+	bool					onGroupPlusButtonValidate();
 	void					onGroupMinusButtonClicked();
 	void					onGroupPlusMenuItemClicked(const LLSD& userdata);
 
@@ -113,8 +112,6 @@ private:
 	void					onGroupsViewSortMenuItemClicked(const LLSD& userdata);
 	void					onRecentViewSortMenuItemClicked(const LLSD& userdata);
 
-	//returns false only if group is "none"
-	bool					isRealGroup();
 	bool					onFriendsViewSortMenuItemCheck(const LLSD& userdata);
 	bool					onRecentViewSortMenuItemCheck(const LLSD& userdata);
 	bool					onNearbyViewSortMenuItemCheck(const LLSD& userdata);
@@ -144,22 +141,11 @@ private:
 	LLGroupList*			mGroupList;
 	LLNetMap*				mMiniMap;
 
-	LLHandle<LLView>		mGroupPlusMenuHandle;
-	LLHandle<LLView>		mNearbyViewSortMenuHandle;
-	LLHandle<LLView>		mFriendsViewSortMenuHandle;
-	LLHandle<LLView>		mGroupsViewSortMenuHandle;
-	LLHandle<LLView>		mRecentViewSortMenuHandle;
-
 	Updater*				mFriendListUpdater;
 	Updater*				mNearbyListUpdater;
 	Updater*				mRecentListUpdater;
 	Updater*				mButtonsUpdater;
 
-	LLMenuButton*			mNearbyGearButton;
-	LLMenuButton*			mFriendsGearButton;
-	LLMenuButton*			mGroupsGearButton;
-	LLMenuButton*			mRecentGearButton;
-
 	std::string				mFilterSubString;
 	std::string				mFilterSubStringOrig;
 };
diff --git a/indra/newview/skins/default/xui/en/menu_group_plus.xml b/indra/newview/skins/default/xui/en/menu_group_plus.xml
index fce7414d80..eca9e7f3c9 100644
--- a/indra/newview/skins/default/xui/en/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/en/menu_group_plus.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu name="menu_group_plus"
+<toggleable_menu name="menu_group_plus"
      left="0" bottom="0" visible="false"
      mouse_opaque="false">
   <menu_item_call name="item_join" label="Join Group...">
@@ -8,4 +8,4 @@
   <menu_item_call name="item_new" label="New Group...">
     <menu_item_call.on_click function="People.Group.Plus.Action" userdata="new_group" />
   </menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_sort.xml
new file mode 100644
index 0000000000..532e295386
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_sort.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+     name="menu_group_plus"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check
+   label="Sort by Name"
+   name="sort_name">
+      <menu_item_check.on_click
+       function="People.Friends.ViewSort.Action"
+       parameter="sort_name" />
+      <menu_item_check.on_check
+       function="People.Friends.ViewSort.CheckItem"
+       parameter="sort_name" />
+  </menu_item_check>
+  <menu_item_check
+   label="Sort by Status"
+   name="sort_status">
+      <menu_item_check.on_click
+       function="People.Friends.ViewSort.Action"
+       parameter="sort_status" />
+      <menu_item_check.on_check
+       function="People.Friends.ViewSort.CheckItem"
+       parameter="sort_status" />
+  </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
new file mode 100644
index 0000000000..be23e91587
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+     name="menu_group_plus"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check name="view_icons" label="View People Icons">
+    <menu_item_check.on_click
+     function="People.Friends.ViewSort.Action"
+     parameter="view_icons" />
+    <menu_item_check.on_check
+     function="CheckControl"
+     parameter="FriendsListShowIcons" />
+  </menu_item_check>
+  <menu_item_check name="view_permissions" label="View Permissions Granted">
+    <menu_item_check.on_click
+     function="People.Friends.ViewSort.Action"
+     parameter="view_permissions" />
+    <menu_item_check.on_check
+     function="CheckControl"
+     parameter="FriendsListShowPermissions" />
+  </menu_item_check>
+  <menu_item_separator layout="topleft" />
+  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
+    <menu_item_call.on_click function="People.Friends.ViewSort.Action" parameter="panel_block_list_sidetray" />
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
deleted file mode 100644
index b452f96e7a..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
-     name="menu_group_plus"
-     left="0" bottom="0" visible="false"
-     mouse_opaque="false">
-  <menu_item_check
-   label="Sort by Name"
-   name="sort_name">
-      <menu_item_check.on_click
-       function="People.Friends.ViewSort.Action"
-       parameter="sort_name" />
-      <menu_item_check.on_check
-       function="People.Friends.ViewSort.CheckItem"
-       parameter="sort_name" />
-  </menu_item_check>
-  <menu_item_check
-   label="Sort by Status"
-   name="sort_status">
-      <menu_item_check.on_click
-       function="People.Friends.ViewSort.Action"
-       parameter="sort_status" />
-      <menu_item_check.on_check
-       function="People.Friends.ViewSort.CheckItem"
-       parameter="sort_status" />
-  </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_check name="view_icons" label="View People Icons">
-    <menu_item_check.on_click
-     function="People.Friends.ViewSort.Action"
-     parameter="view_icons" />
-    <menu_item_check.on_check
-     function="CheckControl"
-     parameter="FriendsListShowIcons" />
-  </menu_item_check>
-  <menu_item_check name="view_permissions" label="View Permissions Granted">
-    <menu_item_check.on_click
-     function="People.Friends.ViewSort.Action"
-     parameter="view_permissions" />
-    <menu_item_check.on_check
-     function="CheckControl"
-     parameter="FriendsListShowPermissions" />
-  </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
-    <menu_item_call.on_click function="People.Friends.ViewSort.Action" parameter="panel_block_list_sidetray" />
-  </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml
new file mode 100644
index 0000000000..73f79f1e70
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_group_plus"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check
+   label="Display Group Icons"
+   layout="topleft"
+   name="Display Group Icons">
+      <menu_item_check.on_click
+       function="People.Groups.ViewSort.Action"
+       parameter="show_icons" />
+      <menu_item_check.on_check
+       function="CheckControl"
+       parameter="GroupListShowIcons" />
+  </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
deleted file mode 100644
index c710fe3b9b..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu 
-     name="menu_group_plus"
-     left="0" bottom="0" visible="false"
-     mouse_opaque="false">
-  <menu_item_check
-   label="Display Group Icons"
-   layout="topleft"
-   name="Display Group Icons">
-      <menu_item_check.on_click
-       function="People.Groups.ViewSort.Action"
-       parameter="show_icons" />
-      <menu_item_check.on_check
-       function="CheckControl"
-       parameter="GroupListShowIcons" />
-  </menu_item_check>
-  <menu_item_call
-   label="Leave Selected Group"
-   layout="topleft"
-   name="Leave Selected Group">
-      <menu_item_call.on_click
-       function="People.Group.Minus.Action"/>
-      <menu_item_call.on_enable
-       function="People.Group.Minus.Enable"/>
-  </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_sort.xml
new file mode 100644
index 0000000000..cf7f4f4fce
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_sort.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+     name="menu_group_plus"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check
+     label="Sort by Recent Speakers"
+     name="sort_by_recent_speakers">
+    <menu_item_check.on_click
+       function="People.Nearby.ViewSort.Action"
+       parameter="sort_by_recent_speakers"/>
+    <menu_item_check.on_check
+       function="People.Nearby.ViewSort.CheckItem"
+       parameter="sort_by_recent_speakers"/>
+  </menu_item_check>
+  <menu_item_check
+     label="Sort by Name"
+     name="sort_name">
+    <menu_item_check.on_click
+       function="People.Nearby.ViewSort.Action"
+       parameter="sort_name"/>
+    <menu_item_check.on_check
+       function="People.Nearby.ViewSort.CheckItem"
+       parameter="sort_name"/>
+  </menu_item_check>
+  <menu_item_check
+     label="Sort by Distance"
+     name="sort_distance">
+    <menu_item_check.on_click
+       function="People.Nearby.ViewSort.Action"
+       parameter="sort_distance"/>
+    <menu_item_check.on_check
+       function="People.Nearby.ViewSort.CheckItem"
+       parameter="sort_distance"/>
+  </menu_item_check>
+ </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
new file mode 100644
index 0000000000..187dd3bcb5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+    <menu_item_check name="view_icons" label="View People Icons">
+        <menu_item_check.on_click
+         function="People.Nearby.ViewSort.Action"
+         parameter="view_icons" />
+        <menu_item_check.on_check
+         function="CheckControl"
+         parameter="NearbyListShowIcons" />
+    </menu_item_check>
+    <menu_item_check name ="view_map" label="View Map">
+        <menu_item_check.on_check
+         function="CheckControl"
+         parameter="NearbyListShowMap" />
+        <menu_item_check.on_click
+         function="ToggleControl"
+         parameter="NearbyListShowMap" />
+    </menu_item_check>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     name="show_blocked_list"
+     label="Show Blocked Residents &amp; Objects">
+        <menu_item_call.on_click
+         function="People.Nearby.ViewSort.Action"
+         userdata="panel_block_list_sidetray" />
+    </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
deleted file mode 100644
index 614dd693c5..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
-     name="menu_group_plus"
-     left="0" bottom="0" visible="false"
-     mouse_opaque="false">
-  <menu_item_check
-     label="Sort by Recent Speakers"
-     name="sort_by_recent_speakers">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_by_recent_speakers"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_by_recent_speakers"/>
-  </menu_item_check>
-  <menu_item_check
-     label="Sort by Name"
-     name="sort_name">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_name"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_name"/>
-  </menu_item_check>
-  <menu_item_check
-     label="Sort by Distance"
-     name="sort_distance">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_distance"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_distance"/>
-  </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_check name="view_icons" label="View People Icons">
-    <menu_item_check.on_click
-     function="People.Nearby.ViewSort.Action"
-     parameter="view_icons" />
-    <menu_item_check.on_check
-     function="CheckControl"
-     parameter="NearbyListShowIcons" />
-  </menu_item_check>
-  <menu_item_check name ="view_map" label="View Map">
-    <menu_item_check.on_check
-      function="CheckControl"
-      parameter="NearbyListShowMap" />
-    <menu_item_check.on_click
-      function="ToggleControl"
-      parameter="NearbyListShowMap" />
-  </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
-    <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="panel_block_list_sidetray" />
-  </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_sort.xml
new file mode 100644
index 0000000000..f14be88780
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_sort.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_group_plus"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check
+   label="Sort by Most Recent"
+   name="sort_most">
+      <menu_item_check.on_click
+       function="People.Recent.ViewSort.Action"
+       parameter="sort_recent" />
+      <menu_item_check.on_check
+       function="People.Recent.ViewSort.CheckItem"
+       parameter="sort_recent" />
+  </menu_item_check>
+  <menu_item_check
+   label="Sort by Name"
+   name="sort_name">
+      <menu_item_check.on_click
+       function="People.Recent.ViewSort.Action"
+       parameter="sort_name" />
+      <menu_item_check.on_check
+       function="People.Recent.ViewSort.CheckItem"
+       parameter="sort_name" />
+  </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
new file mode 100644
index 0000000000..5520bc993c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_group_plus"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check name="view_icons" label="View People Icons">
+    <menu_item_check.on_click
+     function="People.Recent.ViewSort.Action"
+     parameter="view_icons" />
+    <menu_item_check.on_check
+     function="CheckControl"
+     parameter="RecentListShowIcons" />
+  </menu_item_check>
+  <menu_item_separator layout="topleft" />
+  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
+    <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="panel_block_list_sidetray" />
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
deleted file mode 100644
index 485a5a658c..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu 
-     name="menu_group_plus"
-     left="0" bottom="0" visible="false"
-     mouse_opaque="false">
-  <menu_item_check
-   label="Sort by Most Recent"
-   name="sort_most">
-      <menu_item_check.on_click
-       function="People.Recent.ViewSort.Action"
-       parameter="sort_recent" />
-      <menu_item_check.on_check
-       function="People.Recent.ViewSort.CheckItem"
-       parameter="sort_recent" />
-  </menu_item_check>
-  <menu_item_check
-   label="Sort by Name"
-   name="sort_name">
-      <menu_item_check.on_click
-       function="People.Recent.ViewSort.Action"
-       parameter="sort_name" />
-      <menu_item_check.on_check
-       function="People.Recent.ViewSort.CheckItem"
-       parameter="sort_name" />
-  </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_check name="view_icons" label="View People Icons">
-    <menu_item_check.on_click
-     function="People.Recent.ViewSort.Action"
-     parameter="view_icons" />
-    <menu_item_check.on_check
-     function="CheckControl"
-     parameter="RecentListShowIcons" />
-  </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
-    <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="panel_block_list_sidetray" />
-  </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 919661eff6..f61b0b3dbd 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -73,6 +73,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      top="0"
      halign="center"
      width="319">
+
+<!-- ================================= NEARBY tab =========================== -->
+
         <panel
          background_opaque="true"
          background_visible="true"
@@ -117,19 +120,23 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="10"
-                 name="nearby_sort_btn"
+                 menu_filename="menu_people_nearby_view.xml"
+                 menu_position="bottomleft"
+                 name="nearby_view_btn"
                  top="1"
                  width="31" />
                 <menu_button
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Hierarchy_View_Disabled"
+                 image_overlay="Inv_Underpants"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="nearby_view_btn"
+                 menu_filename="menu_people_nearby_sort.xml"
+                 menu_position="bottomleft"
+                 name="nearby_sort_btn"
                  top="1"
                  width="31" />
                 <button
@@ -141,10 +148,14 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="nearby_add_btn"
+                 name="add_friend_btn"
                  top="1"
-                 width="31" />
+                 width="31">
+                    <commit_callback
+                     function="People.AddFriend" />
+                </button>
                 <dnd_button
+                 enabled="false"
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
@@ -155,7 +166,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  name="nearby_del_btn"
                  top="1"
-                 width="31"/>
+                 width="31">
+                    <commit_callback
+                     function="People.DelFriend" />
+                 </dnd_button>
             </panel>
          <layout_stack
            clip="false"
@@ -208,6 +222,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
            </layout_panel>
          </layout_stack>
         </panel>
+
+<!-- ================================= FRIENDS tab ========================== -->
+
         <panel
          background_opaque="true"
        background_visible="true"
@@ -252,19 +269,23 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="10"
-                 name="friends_sort_btn"
+                 menu_filename="menu_people_friends_view.xml"
+                 menu_position="bottomleft"
+                 name="friends_view_btn"
                  top="1"
                  width="31" />
                 <menu_button
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Hierarchy_View_Disabled"
+                 image_overlay="Inv_Underpants"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="friends_view_btn"
+                 menu_filename="menu_people_friends_sort.xml"
+                 menu_position="bottomleft"
+                 name="friends_sort_btn"
                  top="1"
                  width="31" />
                 <button
@@ -278,7 +299,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  name="friends_add_btn"
                  top="1"
-                 width="31" />
+                 width="31">
+                    <commit_callback
+                     function="People.AddFriendWizard" />
+                </button>
                 <dnd_button
                  follows="right"
                  height="25"
@@ -290,7 +314,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  name="friends_del_btn"
                  top="1"
-                 width="31"/>
+                 width="31">
+                    <commit_callback
+                     function="People.DelFriend" />
+                </dnd_button>
             </panel>
             <accordion
        		 background_visible="true"
@@ -348,6 +375,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              width="293"
              wrap="true" />
         </panel>
+
+<!-- ================================= GROUPS tab =========================== -->
+
         <panel
          background_opaque="true"
        background_visible="true"
@@ -396,19 +426,22 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="10"
-                 name="groups_sort_btn"
+                 menu_filename="menu_people_groups_view.xml"
+                 menu_position="bottomleft"
+                 name="groups_view_btn"
                  top="1"
                  width="31" />
                 <menu_button
+                 enabled="false"
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Hierarchy_View_Disabled"
+                 image_overlay="Inv_Underpants"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="groups_view_btn"
+                 name="groups_sort_btn"
                  top="1"
                  width="31" />
                 <button
@@ -420,10 +453,13 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="groups_activate_btn"
+                 name="activate_btn"
                  top="1"
-                 width="31" />
-                <button
+                 width="31">
+                    <commit_callback
+                     function="People.Group.Activate" />
+                </button>
+                <menu_button
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
@@ -432,9 +468,14 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="groups_add_btn"
+                 menu_filename="menu_group_plus.xml"
+                 menu_position="bottomleft"
+                 name="minus_btn"
                  top="1"
-                 width="31" />
+                 width="31">
+                    <validate_callback
+                     function="People.Group.Plus.Validate" />
+                </menu_button>
                 <dnd_button
                  follows="right"
                  height="25"
@@ -444,9 +485,12 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  left_pad="2"
                  layout="topleft"
-                 name="groups_del_btn"
+                 name="minus_btn"
                  top="1"
-                 width="31"/>
+                 width="31">
+                    <commit_callback
+                     function="People.Group.Minus" />
+                </dnd_button>
             </panel>
             <group_list
              allow_select="true" 
@@ -458,6 +502,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              top_pad="0"
              width="307" />
         </panel>
+
+<!-- ================================= RECENT tab =========================== -->
+
         <panel
          background_opaque="true"
        background_visible="true"
@@ -502,19 +549,23 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="10"
-                 name="recent_sort_btn"
+                 menu_filename="menu_people_recent_view.xml"
+                 menu_position="bottomleft"
+                 name="recent_view_btn"
                  top="1"
                  width="31" />
                 <menu_button
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Hierarchy_View_Disabled"
+                 image_overlay="Inv_Underpants"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="recent_view_btn"
+                 menu_filename="menu_people_recent_sort.xml"
+                 menu_position="bottomleft"
+                 name="recent_sort_btn"
                  top="1"
                  width="31" />
                 <button
@@ -526,10 +577,14 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="recent_add_btn"
+                 name="add_friend_btn"
                  top="1"
-                 width="31" />
+                 width="31">
+                    <commit_callback
+                     function="People.AddFriend" />
+                </button>
                 <dnd_button
+                 enabled="false"
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
@@ -540,7 +595,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  name="recent_del_btn"
                  top="1"
-                 width="31"/>
+                 width="31">
+                    <commit_callback
+                     function="People.DelFriend" />
+                 </dnd_button>
             </panel>
             <avatar_list
              allow_select="true"
@@ -592,7 +650,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 		         name="view_profile_btn"
 		         tool_tip="Show picture, groups, and other Residents information"
 		         top="0"
-		         width="67" />	
+		         width="67">
+                    <commit_callback
+                     function="People.ViewProfile" />
+		        </button>
 			</layout_panel>
 			
 			<layout_panel
@@ -612,7 +673,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 		         name="im_btn"
 		         tool_tip="Open instant message session"
 		         top="0"
-		         width="40" />			
+		         width="40">
+                    <commit_callback
+                     function="People.IM" />
+		        </button>			
 			</layout_panel>
 			
 			<layout_panel
@@ -632,7 +696,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 		         name="call_btn"
 		         tool_tip="Call this Resident"
 		         top="0"
-		         width="51" />		
+		         width="51">
+                    <commit_callback
+                     function="People.Call" />
+		        </button>		
 			</layout_panel>
 			
 			<layout_panel
@@ -652,7 +719,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 		         name="share_btn"
 		         tool_tip="Share an inventory item"
 		         top="0"
-		         width="65" />	
+		         width="65">
+                    <commit_callback
+                     function="People.Share" />
+		        </button>	
 			</layout_panel>
 			
 			<layout_panel
@@ -672,7 +742,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 		         name="teleport_btn"
 		         tool_tip="Offer teleport"
 		         top="0"
-		         width="76" />		
+		         width="76">
+                    <commit_callback
+                     function="People.Teleport" />
+		        </button>
 			</layout_panel>
 		</layout_stack>
 		
@@ -706,7 +779,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 		        name="group_info_btn"
 		        tool_tip="Show group information"
 		        top="0"
-		        width="107" />		
+		        width="107">
+                    <commit_callback
+                     function="People.GroupInfo" />
+		        </button>		
 			</layout_panel>
 			
 			<layout_panel
@@ -728,7 +804,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 		        name="chat_btn"
 		        tool_tip="Open chat session"
 		        top="0"
-		        width="100" />			
+		        width="100">
+                    <commit_callback
+                     function="People.Chat" />
+		        </button>			
 			</layout_panel>
 		
 			<layout_panel
@@ -750,7 +829,10 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          		name="group_call_btn"
          		tool_tip="Call this group"
 		        top="0"
-         		width="95" />			
+         		width="95">
+                    <commit_callback
+                     function="People.GroupCall" />
+         	    </button>
 			</layout_panel>		
 		</layout_stack>
     </panel>
-- 
cgit v1.2.3


From 9626ab8fec34f73cd60822bd34376c1cb94e11d7 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 5 Apr 2012 16:10:07 -0700
Subject: CHUI-89 FIX Make nametags appear consistently next to avatar heads
 nametags now track avatar head avatar_skeleton now loaded as param block
 vector3 param block parsing support fixes for param block recursion

---
 indra/llxuixml/llinitparam.h         | 227 +++++----
 indra/llxuixml/llxuiparser.cpp       |  27 +
 indra/llxuixml/llxuiparser.h         |   2 +
 indra/newview/llhudnametag.cpp       | 279 +++--------
 indra/newview/llhudnametag.h         |   2 -
 indra/newview/llspatialpartition.cpp |   4 +-
 indra/newview/llviewermenu.cpp       |   9 -
 indra/newview/llvoavatar.cpp         | 948 ++++++++++++++++-------------------
 indra/newview/llvoavatar.h           |  15 +-
 indra/newview/pipeline.cpp           |   5 -
 10 files changed, 689 insertions(+), 829 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index ab20957760..6fffb73acd 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -377,8 +377,9 @@ namespace LLInitParam
 		class Lazy
 		{
 		public:
+			
 			Lazy()
-				: mPtr(NULL)
+			:	mPtr(NULL)
 			{}
 
 			~Lazy()
@@ -386,6 +387,11 @@ namespace LLInitParam
 				delete mPtr;
 			}
 
+			Lazy(const T& value)
+			{
+				mPtr = new T(value);
+			}
+
 			Lazy(const Lazy& other)
 			{
 				if (other.mPtr)
@@ -424,12 +430,17 @@ namespace LLInitParam
 
 			const T& get() const
 			{
-				return ensureInstance();
+				return *ensureInstance();
 			}
 
 			T& get()
 			{
-				return ensureInstance();
+				return *ensureInstance();
+			}
+
+			operator const T&() const
+			{ 
+				return get(); 
 			}
 
 		private:
@@ -520,8 +531,8 @@ namespace LLInitParam
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const BaseBlock& other)
@@ -539,6 +550,15 @@ namespace LLInitParam
 
 		ParamDescriptorPtr findParamDescriptor(const Param& param);
 
+		// take all provided params from other and apply to self
+		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			static BlockDescriptor sBlockDescriptor;
+			return sBlockDescriptor;
+		}
+
 	protected:
 		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
 
@@ -547,25 +567,11 @@ namespace LLInitParam
 		{
 			return mergeBlock(block_data, source, overwrite);
 		}
-		// take all provided params from other and apply to self
-		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
-
-		static BlockDescriptor& selfBlockDescriptor()
-		{
-			static BlockDescriptor sBlockDescriptor;
-			return sBlockDescriptor;
-		}
 
 	private:
 		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
 	};
 
-	template<typename T>
-	struct ParamCompare<BaseBlock::Lazy<T>, false >
-	{
-		static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
-	};
-
 	class Param
 	{
 	public:
@@ -607,26 +613,16 @@ namespace LLInitParam
 
 	// these templates allow us to distinguish between template parameters
 	// that derive from BaseBlock and those that don't
-	template<typename T, typename Void = void>
+	template<typename T, typename BLOCK_IDENTIFIER = void>
 	struct IsBlock
 	{
 		static const bool value = false;
-		struct EmptyBase {};
-		typedef EmptyBase base_class_t;
 	};
 
 	template<typename T>
 	struct IsBlock<T, typename T::baseblock_base_class_t>
 	{
 		static const bool value = true;
-		typedef BaseBlock base_class_t;
-	};
-
-	template<typename T>
-	struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t >
-	{
-		static const bool value = true;
-		typedef BaseBlock base_class_t;
 	};
 
 	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
@@ -817,13 +813,13 @@ namespace LLInitParam
 	public:
 		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>		self_t;
 		typedef ParamValue<T, NAME_VALUE_LOOKUP>											param_value_t;
-		typedef typename param_value_t::value_assignment_t				value_assignment_t;
-		typedef NAME_VALUE_LOOKUP															name_value_lookup_t;
+		typedef typename param_value_t::value_assignment_t									value_assignment_t;
 
 		using param_value_t::operator();
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
-		:	Param(block_descriptor.mCurrentBlockPtr)
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const T& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		:	Param(block_descriptor.mCurrentBlockPtr),
+			param_value_t(value)
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
@@ -837,8 +833,6 @@ namespace LLInitParam
 												min_count, max_count));
 				BaseBlock::addParam(block_descriptor, param_descriptor, name);
 			}
-
-			setValue(value);
 		} 
 
 		bool isProvided() const { return Param::anyProvided(); }
@@ -857,14 +851,14 @@ namespace LLInitParam
 				}
 				
 				// try to parse a known named value
-				if(name_value_lookup_t::valueNamesExist())
+				if(param_value_t::valueNamesExist())
 				{
 					// try to parse a known named value
 					std::string name;
 					if (parser.readValue(name))
 					{
 						// try to parse a per type named value
-						if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+						if (param_value_t::getValueFromName(name, typed_param.getValue()))
 						{
 							typed_param.setValueName(name);
 							typed_param.setProvided();
@@ -917,9 +911,9 @@ namespace LLInitParam
 			// tell parser about our actual type
 			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
 			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
-			if (name_value_lookup_t::getPossibleValues())
+			if (param_value_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, param_value_t::getPossibleValues());
 			}
 		}
 
@@ -969,11 +963,10 @@ namespace LLInitParam
 		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;
 		typedef typename param_value_t::value_assignment_t		value_assignment_t;
 		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true>	self_t;
-		typedef NAME_VALUE_LOOKUP								name_value_lookup_t;
 
 		using param_value_t::operator();
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const T& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr),
 			param_value_t(value)
 		{
@@ -1002,14 +995,14 @@ namespace LLInitParam
 				return true;
 			}
 
-			if(name_value_lookup_t::valueNamesExist())
+			if(param_value_t::valueNamesExist())
 			{
 				// try to parse a known named value
 				std::string name;
 				if (parser.readValue(name))
 				{
 					// try to parse a per type named value
-					if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+					if (param_value_t::getValueFromName(name, typed_param.getValue()))
 					{
 						typed_param.setValueName(name);
 						typed_param.setProvided();
@@ -1041,7 +1034,7 @@ namespace LLInitParam
 			}
 			else
 			{
-				typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
+				typed_param.serializeBlock(parser, name_stack, &static_cast<const BaseBlock&>(*static_cast<const self_t*>(diff_param)));
 			}
 		}
 
@@ -1115,7 +1108,7 @@ namespace LLInitParam
 
 			if (src_typed_param.anyProvided())
 			{
-				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::getBlockDescriptor(), src_typed_param, overwrite))
 				{
 					dst_typed_param.clearValueName();
 					dst_typed_param.setProvided(true);
@@ -1138,9 +1131,8 @@ namespace LLInitParam
 		typedef const container_t&											value_assignment_t;
 
 		typedef typename param_value_t::value_t								value_t;
-		typedef NAME_VALUE_LOOKUP											name_value_lookup_t;
 		
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const container_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), std::back_inserter(mValues));
@@ -1176,14 +1168,14 @@ namespace LLInitParam
 				}
 				
 				// try to parse a known named value
-				if(name_value_lookup_t::valueNamesExist())
+				if(param_value_t::valueNamesExist())
 				{
 					// try to parse a known named value
 					std::string name;
 					if (parser.readValue(name))
 					{
 						// try to parse a per type named value
-						if (name_value_lookup_t::getValueFromName(name, value))
+						if (param_value_t::getValueFromName(name, value))
 						{
 							typed_param.add(value);
 							typed_param.mValues.back().setValueName(name);
@@ -1234,9 +1226,9 @@ namespace LLInitParam
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
 			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
-			if (name_value_lookup_t::getPossibleValues())
+			if (param_value_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, param_value_t::getPossibleValues());
 			}
 		}
 
@@ -1261,12 +1253,12 @@ namespace LLInitParam
 			setProvided();
 		}
 
-		void add(const typename name_value_lookup_t::name_t& name)
+		void add(const typename param_value_t::name_t& name)
 		{
 			value_t value;
 
 			// try to parse a per type named value
-			if (name_value_lookup_t::getValueFromName(name, value))
+			if (param_value_t::getValueFromName(name, value))
 			{
 				add(value);
 				mValues.back().setValueName(name);
@@ -1330,9 +1322,8 @@ namespace LLInitParam
 		typedef typename std::vector<param_value_t>						container_t;
 		typedef const container_t&										value_assignment_t;
 		typedef typename param_value_t::value_t							value_t;
-		typedef NAME_VALUE_LOOKUP										name_value_lookup_t;
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const container_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), back_inserter(mValues));
@@ -1372,14 +1363,14 @@ namespace LLInitParam
 				typed_param.setProvided();
 				return true;
 			}
-			else if(name_value_lookup_t::valueNamesExist())
+			else if(param_value_t::valueNamesExist())
 			{
 				// try to parse a known named value
 				std::string name;
 				if (parser.readValue(name))
 				{
 					// try to parse a per type named value
-					if (name_value_lookup_t::getValueFromName(name, value.getValue()))
+					if (param_value_t::getValueFromName(name, value.getValue()))
 					{
 						typed_param.mValues.back().setValueName(name);
 						typed_param.setProvided();
@@ -1447,12 +1438,12 @@ namespace LLInitParam
 			setProvided();
 		}
 
-		void add(const typename name_value_lookup_t::name_t& name)
+		void add(const typename param_value_t::name_t& name)
 		{
 			value_t value;
 
 			// try to parse a per type named value
-			if (name_value_lookup_t::getValueFromName(name, value))
+			if (param_value_t::getValueFromName(name, value))
 			{
 				add(value);
 				mValues.back().setValueName(name);
@@ -1526,13 +1517,13 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
 		}
 
 		// take all provided params that are not already provided, and apply to self
 		bool fillFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
 		}
 
 		bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
@@ -1550,7 +1541,7 @@ namespace LLInitParam
 		bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
 		{
 			mCurChoice = other.mCurChoice;
-			return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
+			return base_block_t::mergeBlock(getBlockDescriptor(), other, overwrite);
 		}
 
 		// clear out old choice when param has changed
@@ -1571,14 +1562,14 @@ namespace LLInitParam
 			base_block_t::paramChanged(changed_param, user_provided);
 		}
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 	protected:
 		ChoiceBlock()
 		:	mCurChoice(0)
 		{
-			BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+			BaseBlock::init(getBlockDescriptor(), base_block_t::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
 		}
 
 		// Alternatives are mutually exclusive wrt other Alternatives in the same block.  
@@ -1596,13 +1587,13 @@ namespace LLInitParam
 
 			using super_t::operator =;
 
-			explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
+			explicit Alternative(const char* name = "", const T& val = defaultValue<T>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),
 				mOriginalValue(val)
 			{
 				// assign initial choice to first declared option
-				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
-				if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
+				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr);
+				if (LL_UNLIKELY(DERIVED_BLOCK::getBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
 				{
 					if(blockp->mCurChoice == 0)
 					{
@@ -1654,8 +1645,8 @@ namespace LLInitParam
 			T			mOriginalValue;
 		};
 
-	protected:
-		static BlockDescriptor& selfBlockDescriptor()
+	public:
+		static BlockDescriptor& getBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
@@ -1683,23 +1674,23 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
 		}
 
 		// take all provided params that are not already provided, and apply to self
 		bool fillFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
 		}
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 	protected:
 		Block()
 		{
 			//#pragma message("Parsing LLInitParam::Block")
-			BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+			BaseBlock::init(getBlockDescriptor(), BASE_BLOCK::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
 		}
 
 		//
@@ -1715,8 +1706,8 @@ namespace LLInitParam
 			using super_t::operator();
 			using super_t::operator =;
 			
-			explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
+			explicit Optional(const char* name = "", const T& val = defaultValue<T>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)
 			{
 				//#pragma message("Parsing LLInitParam::Block::Optional")
 			}
@@ -1746,8 +1737,8 @@ namespace LLInitParam
 			using super_t::operator =;
 
 			// mandatory parameters require a name to be parseable
-			explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
+			explicit Mandatory(const char* name = "", const T& val = defaultValue<T>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)
 			{}
 
 			Mandatory& operator =(value_assignment_t val)
@@ -1782,7 +1773,7 @@ namespace LLInitParam
 			typedef typename super_t::const_iterator								const_iterator;
 
 			explicit Multiple(const char* name = "")
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
 			{}
 
 			Multiple& operator =(value_assignment_t val)
@@ -1808,9 +1799,9 @@ namespace LLInitParam
 		{
 		public:
 			explicit Deprecated(const char* name)
-			:	Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
+			:	Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)
 			{
-				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
+				BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();
 				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 				{
 					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
@@ -1841,13 +1832,14 @@ namespace LLInitParam
 		// different semantics for documentation purposes, but functionally identical
 		typedef Deprecated Ignored;
 
-	protected:
-		static BlockDescriptor& selfBlockDescriptor()
+	public:
+		static BlockDescriptor& getBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
 		}
 
+	protected:
 		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
 		void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param, 
 			typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
@@ -1887,7 +1879,7 @@ namespace LLInitParam
 			{
 				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
 				// merge individual parameters into destination
-				return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
+				return super_t::mergeBlock(super_t::getBlockDescriptor(), other, overwrite);
 			}
 			return false;
 		}
@@ -1955,14 +1947,36 @@ namespace LLInitParam
 		mutable bool 	mValidated; // lazy validation flag
 	};
 
-	template<typename T, bool IS_BLOCK>
+	template<typename T, typename BLOCK_IDENTIFIER>
+	struct IsBlock<ParamValue<BaseBlock::Lazy<T>, TypeValues<BaseBlock::Lazy<T> > > , BLOCK_IDENTIFIER>
+	{
+		static const bool value = true;//IsBlock<T>::value;
+	};
+
+	template<typename T>
+	struct ParamCompare<BaseBlock::Lazy<T>, false>
+	{
+		static bool equals(const T&a, const T &b)
+		{
+			return a == b;
+		}
+
+		static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b)
+		{
+			if (a.empty() || b.empty()) return false;
+			return a.get() == b.get();
+		}
+	};
+
+
+	template<typename T, bool VALUE_IS_BLOCK>
 	class ParamValue <BaseBlock::Lazy<T>,
-					TypeValues<T>,
-					IS_BLOCK>
-	:	public IsBlock<T>::base_class_t
+					TypeValues<BaseBlock::Lazy<T> >,
+					VALUE_IS_BLOCK>
+	:	public TypeValues<T>
 	{
 	public:
-		typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
+		typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<BaseBlock::Lazy<T> >, false> self_t;
 		typedef const T& value_assignment_t;
 		typedef T value_t;
 	
@@ -1971,11 +1985,16 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		ParamValue(value_assignment_t other)
+		ParamValue(const BaseBlock::Lazy<T>& other)
 		:	mValue(other),
 			mValidated(false)
 		{}
 
+		ParamValue(const T& value)
+		:	mValue(value),
+			mValidated(false)
+		{}
+
 		void setValue(value_assignment_t val)
 		{
 			mValue.set(val);
@@ -1991,6 +2010,11 @@ namespace LLInitParam
 			return mValue.get();
 		}
 
+		operator const BaseBlock&() const
+		{
+			return mValue.get();
+		}
+
 		operator value_assignment_t() const
 		{
 			return mValue.get();
@@ -2020,7 +2044,22 @@ namespace LLInitParam
 			return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
 		}
 
-	protected:
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+		{
+			return mValue.get().mergeBlock(block_data, source.getValue(),  overwrite);
+		}
+
+		bool validateBlock(bool emit_errors = true) const
+		{
+			return mValue.get().validateBlock(emit_errors);
+		}
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			return T::getBlockDescriptor();
+		}
+
+
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index afc76024d1..3c89fa3aaf 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -42,6 +42,7 @@
 #include <boost/spirit/include/classic_core.hpp>
 
 #include "lluicolor.h"
+#include "v3math.h"
 
 using namespace BOOST_SPIRIT_CLASSIC_NS;
 
@@ -670,6 +671,7 @@ LLXUIParser::LLXUIParser()
 		registerParserFuncs<S32>(readS32Value, writeS32Value);
 		registerParserFuncs<F32>(readF32Value, writeF32Value);
 		registerParserFuncs<F64>(readF64Value, writeF64Value);
+		registerParserFuncs<LLVector3>(readVector3Value, writeVector3Value);
 		registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value);
 		registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue);
 		registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue);
@@ -1144,6 +1146,31 @@ bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_
 	return false;
 }
 
+bool LLXUIParser::readVector3Value(Parser& parser, void* val_ptr)
+{
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	LLVector3* vecp = (LLVector3*)val_ptr;
+	if(self.mCurReadNode->getFloatValue(3, vecp->mV) >= 3)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+bool LLXUIParser::writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	LLXMLNodePtr node = self.getNode(stack);
+	if (node.notNull())
+	{
+		LLVector3 vector = *((LLVector3*)val_ptr);
+		node->setFloatValue(3, vector.mV);
+		return true;
+	}
+	return false;
+}
+
 bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
index d7cd256967..e48663e5cc 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llxuixml/llxuiparser.h
@@ -127,6 +127,7 @@ private:
 	static bool readS32Value(Parser& parser, void* val_ptr);
 	static bool readF32Value(Parser& parser, void* val_ptr);
 	static bool readF64Value(Parser& parser, void* val_ptr);
+	static bool readVector3Value(Parser& parser, void* val_ptr);
 	static bool readColor4Value(Parser& parser, void* val_ptr);
 	static bool readUIColorValue(Parser& parser, void* val_ptr);
 	static bool readUUIDValue(Parser& parser, void* val_ptr);
@@ -144,6 +145,7 @@ private:
 	static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&);
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 482294c8a6..cf55954d7d 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -187,45 +187,42 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
 
-	//if (mUseBubble)
-	{
-		LLVector3 bg_pos = render_position
-			+ (F32)mOffsetY * y_pixel_vec
-			- (width_vec / 2.f)
-			- (height_vec);
-		//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+	LLVector3 bg_pos = render_position
+		+ (F32)mOffsetY * y_pixel_vec
+		- (width_vec / 2.f)
+		- (height_vec);
+	//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
 
-		LLVector3 v[] = 
-		{
-			bg_pos,
-			bg_pos + width_vec,
-			bg_pos + width_vec + height_vec,
-			bg_pos + height_vec,
-		};
+	LLVector3 v[] = 
+	{
+		bg_pos,
+		bg_pos + width_vec,
+		bg_pos + width_vec + height_vec,
+		bg_pos + height_vec,
+	};
 
-		if (debug_render)
-		{
-			gGL.begin(LLRender::LINE_STRIP);
-			gGL.vertex3fv(v[0].mV);
-			gGL.vertex3fv(v[1].mV);
-			gGL.vertex3fv(v[2].mV);
-			gGL.vertex3fv(v[3].mV);
-			gGL.vertex3fv(v[0].mV);
-			gGL.vertex3fv(v[2].mV);
-			gGL.end();
-		}
+	if (debug_render)
+	{
+		gGL.begin(LLRender::LINE_STRIP);
+		gGL.vertex3fv(v[0].mV);
+		gGL.vertex3fv(v[1].mV);
+		gGL.vertex3fv(v[2].mV);
+		gGL.vertex3fv(v[3].mV);
+		gGL.vertex3fv(v[0].mV);
+		gGL.vertex3fv(v[2].mV);
+		gGL.end();
+	}
 
-		LLVector3 dir = end-start;
-		F32 a, b, t;
+	LLVector3 dir = end-start;
+	F32 a, b, t;
 
-		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
-			LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+	if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
+		LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+	{
+		if (t <= 1.f)
 		{
-			if (t <= 1.f)
-			{
-				intersection = start + dir*t;
-				return TRUE;
-			}
+			intersection = start + dir*t;
+			return TRUE;
 		}
 	}
 
@@ -241,12 +238,6 @@ void LLHUDNameTag::render()
 	}
 }
 
-void LLHUDNameTag::renderForSelect()
-{
-	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-	renderText(TRUE);
-}
-
 void LLHUDNameTag::renderText(BOOL for_select)
 {
 	if (!mVisible || mHidden)
@@ -336,142 +327,53 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	LLCoordGL screen_pos;
 	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
 
-	LLVector2 screen_offset;
-//	if (!mUseBubble)
-//	{
-//		screen_offset = mPositionOffset;
-//	}
-//	else
-//	{
-		screen_offset = updateScreenPos(mPositionOffset);
-//	}
+	LLVector2 screen_offset = updateScreenPos(mPositionOffset);
 
 	LLVector3 render_position = mPositionAgent  
 			+ (x_pixel_vec * screen_offset.mV[VX])
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
-//	if (mUseBubble)
+	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+	LLUI::pushMatrix();
 	{
-		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-		LLUI::pushMatrix();
-		{
-			LLVector3 bg_pos = render_position
-				+ (F32)mOffsetY * y_pixel_vec
-				- (width_vec / 2.f)
-				- (height_vec);
-			LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+		LLVector3 bg_pos = render_position
+			+ (F32)mOffsetY * y_pixel_vec
+			- (width_vec / 2.f)
+			- (height_vec);
+		LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
 
-			if (for_select)
-			{
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				S32 name = mSourceObject->mGLName;
-				LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
-				gGL.color4ubv(coloru.mV);
-				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-				LLUI::popMatrix();
-				return;
-			}
-			else
-			{
-				gGL.getTexUnit(0)->bind(imagep->getImage());
+		if (for_select)
+		{
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+			S32 name = mSourceObject->mGLName;
+			LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
+			gGL.color4ubv(coloru.mV);
+			gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
+			LLUI::popMatrix();
+			return;
+		}
+		else
+		{
+			gGL.getTexUnit(0)->bind(imagep->getImage());
 				
-				gGL.color4fv(bg_color.mV);
-				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
+			gGL.color4fv(bg_color.mV);
+			gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
 		
-				if ( mLabelSegments.size())
-				{
-					LLUI::pushMatrix();
-					{
-						gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
-						LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
-						LLVector3 label_offset = height_vec - label_height;
-						LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
-						gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
-					}
-					LLUI::popMatrix();
-				}
-			}
-
-			BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f;
-			BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f);
-
-			// draw line segments pointing to parent object
-			if (!mOffscreen && (outside_width || outside_height))
+			if ( mLabelSegments.size())
 			{
 				LLUI::pushMatrix();
 				{
-					gGL.color4fv(bg_color.mV);
-					LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec);
-					target_pos += (width_vec / 2.f);
-					target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero;
-					target_pos -= 3.f * x_pixel_vec;
-					target_pos -= 6.f * y_pixel_vec;
-					LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]);
-					gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);	
+					gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
+					LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
+					LLVector3 label_offset = height_vec - label_height;
+					LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
+					gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
 				}
 				LLUI::popMatrix();
-
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
-				
-				LLVector3 box_center_offset;
-				box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f);
-				LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
-				gGL.color4fv(bg_color.mV);
-				LLUI::setLineWidth(2.0);
-				gGL.begin(LLRender::LINES);
-				{
-					if (outside_width)
-					{
-						LLVector3 vert;
-						// draw line in x then y
-						if (mPositionOffset.mV[VX] < 0.f)
-						{
-							// start at right edge
-							vert = width_vec * 0.5f;
-							gGL.vertex3fv(vert.mV);
-						}
-						else
-						{
-							// start at left edge
-							vert = width_vec * -0.5f;
-							gGL.vertex3fv(vert.mV);
-						}
-						vert = -mPositionOffset.mV[VX] * x_pixel_vec;
-						gGL.vertex3fv(vert.mV);
-						gGL.vertex3fv(vert.mV);
-						vert -= mPositionOffset.mV[VY] * y_pixel_vec;
-						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
-						gGL.vertex3fv(vert.mV);
-					}
-					else
-					{
-						LLVector3 vert;
-						// draw line in y then x
-						if (mPositionOffset.mV[VY] < 0.f)
-						{
-							// start at top edge
-							vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
-							gGL.vertex3fv(vert.mV);
-						}
-						else
-						{
-							// start at bottom edge
-							vert = (height_vec * -0.5f)  - (mPositionOffset.mV[VX] * x_pixel_vec);
-							gGL.vertex3fv(vert.mV);
-						}
-						vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec;
-						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
-						gGL.vertex3fv(vert.mV);
-					}
-				}
-				gGL.end();
-				LLUI::setLineWidth(1.0);
-
 			}
 		}
-		LLUI::popMatrix();
 	}
+	LLUI::popMatrix();
 
 	F32 y_offset = (F32)mOffsetY;
 		
@@ -874,29 +776,26 @@ void LLHUDNameTag::updateAll()
 	for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it)
 	{
 		LLHUDNameTag* textp = (*r_it);
-//		if (textp->mUseBubble)
-//		{
-			if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
-			{
-				textp->setLOD(3);
-			}
-			else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
-			{
-				textp->setLOD(2);
-			}
-			else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
-			{
-				textp->setLOD(1);
-			}
-			else
-			{
-				textp->setLOD(0);
-			}
-			textp->updateSize();
-			// find on-screen position and initialize collision rectangle
-			textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
-			current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
-//		}
+		if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
+		{
+			textp->setLOD(3);
+		}
+		else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
+		{
+			textp->setLOD(2);
+		}
+		else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
+		{
+			textp->setLOD(1);
+		}
+		else
+		{
+			textp->setLOD(0);
+		}
+		textp->updateSize();
+		// find on-screen position and initialize collision rectangle
+		textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
+		current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
 	}
 
 	LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat();
@@ -914,20 +813,12 @@ void LLHUDNameTag::updateAll()
 		{
 			LLHUDNameTag* src_textp = (*src_it);
 
-//			if (!src_textp->mUseBubble)
-//			{
-//				continue;
-//			}
 			VisibleTextObjectIterator dst_it = src_it;
 			++dst_it;
 			for (; dst_it != sVisibleTextObjects.end(); ++dst_it)
 			{
 				LLHUDNameTag* dst_textp = (*dst_it);
 
-//				if (!dst_textp->mUseBubble)
-//				{
-//					continue;
-//				}
 				if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect))
 				{
 					LLRectf intersect_rect = src_textp->mSoftScreenRect;
@@ -976,10 +867,6 @@ void LLHUDNameTag::updateAll()
 	VisibleTextObjectIterator this_object_it;
 	for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)
 	{
-//		if (!(*this_object_it)->mUseBubble)
-//		{
-//			continue;
-//		}
 		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC));
 	}
 }
@@ -1037,10 +924,6 @@ void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list)
 	VisibleTextObjectIterator text_it;
 	for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it)
 	{
-//		if (!(*text_it)->mUseBubble)
-//		{
-//			continue;
-//		}
 		pick_list.insert((*text_it)->mSourceObject);
 	}
 }
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 3325c22def..72647d5b26 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -118,7 +118,6 @@ public:
 	/*virtual*/ void markDead();
 	friend class LLHUDObject;
 	/*virtual*/ F32 getDistance() const { return mLastDistance; }
-	//void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; }
 	S32  getLOD() { return mLOD; }
 	BOOL getVisible() { return mVisible; }
 	BOOL getHidden() const { return mHidden; }
@@ -136,7 +135,6 @@ protected:
 	LLHUDNameTag(const U8 type);
 
 	/*virtual*/ void render();
-	/*virtual*/ void renderForSelect();
 	void renderText(BOOL for_select);
 	static void updateAll();
 	void setLOD(S32 lod);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5d196a465f..1333862855 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2774,7 +2774,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 
 void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)
 {
-	gGL.diffuseColor4fv(color.mV);
+	gGL.color4fv(color.mV);
 	gGL.begin(LLRender::LINES);
 	{
 		gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
@@ -3904,7 +3904,7 @@ void renderAgentTarget(LLVOAvatar* avatar)
 	if (avatar->isSelf())
 	{
 		renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
-		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
+		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
 		renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
 		renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
 	}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 99540ccce9..ae32683c99 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3190,15 +3190,6 @@ bool enable_freeze_eject(const LLSD& avatar_id)
 	return new_value;
 }
 
-
-void login_done(S32 which, void *user)
-{
-	llinfos << "Login done " << which << llendl;
-
-	LLPanelLogin::closePanel();
-}
-
-
 bool callback_leave_group(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bc7f5a9744..f00363bfa6 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -62,6 +62,7 @@
 #include "llhudmanager.h"
 #include "llhudnametag.h"
 #include "llhudtext.h"				// for mText/mDebugText
+#include "llinitparam.h"
 #include "llkeyframefallmotion.h"
 #include "llkeyframestandmotion.h"
 #include "llkeyframewalkmotion.h"
@@ -193,6 +194,9 @@ const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN;
 const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;
 const F32 CHAT_FADE_TIME = 8.0;
 const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
+const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;
+const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
+const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.15f;
 
 const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
 
@@ -224,55 +228,62 @@ struct LLTextureMaskData
  **/
 
 //------------------------------------------------------------------------
-// LLVOBoneInfo
+// LLVOAvatarBoneInfo
 // Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton.
 //------------------------------------------------------------------------
-class LLVOAvatarBoneInfo
+struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo>
 {
-	friend class LLVOAvatar;
-	friend class LLVOAvatarSkeletonInfo;
-public:
-	LLVOAvatarBoneInfo() : mIsJoint(FALSE) {}
-	~LLVOAvatarBoneInfo()
-	{
-		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
-	}
-	BOOL parseXml(LLXmlTreeNode* node);
+	LLVOAvatarCollisionVolumeInfo() 
+	:	name("name"),
+		pos("pos"),
+		rot("rot"),
+		scale("scale")
+	{}
+
+	Mandatory<std::string>	name;
+	Mandatory<LLVector3>	pos,
+							rot,
+							scale;
+};
+
+struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
+{
+	Alternative<Lazy<struct LLVOAvatarBoneInfo> >	bone;
+	Alternative<LLVOAvatarCollisionVolumeInfo>		collision_volume;
+
+	LLVOAvatarChildJoint()
+	:	bone("bone"),
+		collision_volume("collision_volume")
+	{}
+};
+
+struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo>
+{
+	LLVOAvatarBoneInfo() 
+	:	pivot("pivot")
+	{}
 	
-private:
-	std::string mName;
-	BOOL mIsJoint;
-	LLVector3 mPos;
-	LLVector3 mRot;
-	LLVector3 mScale;
-	LLVector3 mPivot;
-	typedef std::vector<LLVOAvatarBoneInfo*> child_list_t;
-	child_list_t mChildList;
+	Mandatory<LLVector3>					pivot;
+	Multiple<LLVOAvatarChildJoint>			children;
 };
 
 //------------------------------------------------------------------------
 // LLVOAvatarSkeletonInfo
 // Overall avatar skeleton
 //------------------------------------------------------------------------
-class LLVOAvatarSkeletonInfo
+struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo>
 {
-	friend class LLVOAvatar;
-public:
-	LLVOAvatarSkeletonInfo() :
-		mNumBones(0), mNumCollisionVolumes(0) {}
-	~LLVOAvatarSkeletonInfo()
-	{
-		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
-	}
-	BOOL parseXml(LLXmlTreeNode* node);
-	S32 getNumBones() const { return mNumBones; }
-	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+	LLVOAvatarSkeletonInfo()
+	:	skeleton_root(""),
+		num_bones("num_bones"),
+		num_collision_volumes("num_collision_volumes"),
+		version("version")
+	{}
 	
-private:
-	S32 mNumBones;
-	S32 mNumCollisionVolumes;
-	typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t;
-	bone_info_list_t mBoneInfoList;
+	Mandatory<std::string>			version;
+	Mandatory<S32>					num_bones,
+									num_collision_volumes;
+	Mandatory<LLVOAvatarChildJoint>	skeleton_root;
 };
 
 //-----------------------------------------------------------------------------
@@ -597,7 +608,7 @@ private:
 // Static Data
 //-----------------------------------------------------------------------------
 LLXmlTree LLVOAvatar::sXMLTree;
-LLXmlTree LLVOAvatar::sSkeletonXMLTree;
+LLXMLNodePtr LLVOAvatar::sSkeletonXMLTree;
 LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;
 LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
 LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL;
@@ -1123,18 +1134,6 @@ void LLVOAvatar::initClass()
 		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
 	}
 
-	// Process XML data
-
-	// avatar_skeleton.xml
-	if (sAvatarSkeletonInfo)
-	{ //this can happen if a login attempt failed
-		delete sAvatarSkeletonInfo;
-	}
-	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
-	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
-	{
-		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
-	}
 	// parse avatar_lad.xml
 	if (sAvatarXmlInfo)
 	{ //this can happen if a login attempt failed
@@ -1183,7 +1182,7 @@ void LLVOAvatar::initClass()
 void LLVOAvatar::cleanupClass()
 {
 	deleteAndClear(sAvatarXmlInfo);
-	sSkeletonXMLTree.cleanup();
+	sSkeletonXMLTree = NULL;
 	sXMLTree.cleanup();
 }
 
@@ -1655,33 +1654,39 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
 	//-------------------------------------------------------------------------
 	// parse the file
 	//-------------------------------------------------------------------------
-	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
+	
+	LLXMLNodePtr skeleton_xml;
+	BOOL parsesuccess = LLXMLNode::parseFile(filename, skeleton_xml, NULL);
 
-	if (!parsesuccess)
+	if (!parsesuccess || skeleton_xml.isNull())
 	{
 		llerrs << "Can't parse skeleton file: " << filename << llendl;
 		return FALSE;
 	}
 
-	// now sanity check xml file
-	LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
-	if (!root) 
+	// Process XML data
+	if (sAvatarSkeletonInfo)
+	{ //this can happen if a login attempt failed
+		delete sAvatarSkeletonInfo;
+	}
+	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
+
+	LLXUIParser parser;
+	parser.readXUI(skeleton_xml, *sAvatarSkeletonInfo, filename);
+	if (!sAvatarSkeletonInfo->validateBlock())
 	{
-		llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
-		return FALSE;
+		llerrs << "Error parsing skeleton XML file: " << filename << llendl;
 	}
 
-	if( !root->hasName( "linden_skeleton" ) )
+	if( !skeleton_xml->hasName( "linden_skeleton" ) )
 	{
 		llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
 		return FALSE;
 	}
 
-	std::string version;
-	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
-	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+	if (sAvatarSkeletonInfo->version() != "1.0")
 	{
-		llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
+		llerrs << "Invalid avatar skeleton file version: " << sAvatarSkeletonInfo->version() << " in file: " << filename << llendl;
 		return FALSE;
 	}
 
@@ -1690,14 +1695,13 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
 
 //-----------------------------------------------------------------------------
 // setupBone()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
+//-----------------------------------------------------------
+BOOL LLVOAvatar::setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
 {
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
 	
 	LLViewerJoint* joint = NULL;
-
-	if (info->mIsJoint)
+	if (info.bone.isChosen())
 	{
 		joint = (LLViewerJoint*)getCharacterJoint(joint_num);
 		if (!joint)
@@ -1705,7 +1709,23 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
 			llwarns << "Too many bones" << llendl;
 			return FALSE;
 		}
-		joint->setName( info->mName );
+		joint->setName( info.bone().name );
+		joint->setPosition(info.bone().pos);
+		joint->setRotation(mayaQ(info.bone().rot().mV[VX], info.bone().rot().mV[VY], info.bone().rot().mV[VZ], LLQuaternion::XYZ));
+		joint->setScale(info.bone().scale);
+		joint->setSkinOffset( info.bone().pivot );
+		joint_num++;
+
+		for (LLInitParam::ParamIterator<LLVOAvatarChildJoint>::const_iterator child_it = info.bone().children.begin(),
+				end_it = info.bone().children.end();
+			child_it != end_it;
+			++child_it)
+		{
+			if (!setupBone(*child_it, joint, volume_num, joint_num))
+			{
+				return FALSE;
+			}
+		}
 	}
 	else // collision volume
 	{
@@ -1715,7 +1735,11 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
 			return FALSE;
 		}
 		joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]);
-		joint->setName( info->mName );
+		joint->setName( info.collision_volume.name);
+		joint->setPosition(info.collision_volume.pos);
+		joint->setRotation(mayaQ(info.collision_volume.rot().mV[VX], info.collision_volume.rot().mV[VY], info.collision_volume.rot().mV[VZ], LLQuaternion::XYZ));
+		joint->setScale(info.collision_volume.scale);
+		volume_num++;
 	}
 
 	// add to parent
@@ -1724,34 +1748,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
 		parent->addChild( joint );
 	}
 
-	joint->setPosition(info->mPos);
-	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
-							 info->mRot.mV[VZ], LLQuaternion::XYZ));
-	joint->setScale(info->mScale);
-
 	joint->setDefaultFromCurrentXform();
 	
-	if (info->mIsJoint)
-	{
-		joint->setSkinOffset( info->mPivot );
-		joint_num++;
-	}
-	else // collision volume
-	{
-		volume_num++;
-	}
-
-	// setup children
-	LLVOAvatarBoneInfo::child_list_t::const_iterator iter;
-	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
-	{
-		LLVOAvatarBoneInfo *child_info = *iter;
-		if (!setupBone(child_info, joint, volume_num, joint_num))
-		{
-			return FALSE;
-		}
-	}
-
 	return TRUE;
 }
 
@@ -1765,35 +1763,31 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
 	//-------------------------------------------------------------------------
 	// allocate joints
 	//-------------------------------------------------------------------------
-	if (!allocateCharacterJoints(info->mNumBones))
+	if (!allocateCharacterJoints(info->num_bones))
 	{
-		llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
+		llerrs << "Can't allocate " << info->num_bones() << " joints" << llendl;
 		return FALSE;
 	}
 	
 	//-------------------------------------------------------------------------
 	// allocate volumes
 	//-------------------------------------------------------------------------
-	if (info->mNumCollisionVolumes)
+	if (info->num_collision_volumes)
 	{
-		if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
+		if (!allocateCollisionVolumes(info->num_collision_volumes))
 		{
-			llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
+			llerrs << "Can't allocate " << info->num_collision_volumes() << " collision volumes" << llendl;
 			return FALSE;
 		}
 	}
 
 	S32 current_joint_num = 0;
 	S32 current_volume_num = 0;
-	LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
-	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
+
+	if (!setupBone(info->skeleton_root, NULL, current_volume_num, current_joint_num))
 	{
-		LLVOAvatarBoneInfo *info = *iter;
-		if (!setupBone(info, NULL, current_volume_num, current_joint_num))
-		{
-			llerrs << "Error parsing bone in skeleton file" << llendl;
-			return FALSE;
-		}
+		llerrs << "Error parsing bone in skeleton file" << llendl;
+		return FALSE;
 	}
 
 	return TRUE;
@@ -2922,43 +2916,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-		BOOL new_name = FALSE;
-		if (visible_chat != mVisibleChat)
-		{
-			mVisibleChat = visible_chat;
-			new_name = TRUE;
-		}
+	BOOL new_name = FALSE;
+	if (visible_chat != mVisibleChat)
+	{
+		mVisibleChat = visible_chat;
+		new_name = TRUE;
+	}
 		
-		if (sRenderGroupTitles != mRenderGroupTitles)
-		{
-			mRenderGroupTitles = sRenderGroupTitles;
-			new_name = TRUE;
-		}
+	if (sRenderGroupTitles != mRenderGroupTitles)
+	{
+		mRenderGroupTitles = sRenderGroupTitles;
+		new_name = TRUE;
+	}
 
-		// First Calculate Alpha
-		// If alpha > 0, create mNameText if necessary, otherwise delete it
-			F32 alpha = 0.f;
-			if (mAppAngle > 5.f)
+	// First Calculate Alpha
+	// If alpha > 0, create mNameText if necessary, otherwise delete it
+		F32 alpha = 0.f;
+		if (mAppAngle > 5.f)
+		{
+			const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
+			if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
 			{
-				const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
-				if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
-				{
-					alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
-				}
-				else
-				{
-					// ...not fading, full alpha
-					alpha = 1.f;
-				}
+				alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
 			}
-			else if (mAppAngle > 2.f)
+			else
 			{
-				// far away is faded out also
-				alpha = (mAppAngle-2.f)/3.f;
+				// ...not fading, full alpha
+				alpha = 1.f;
 			}
+		}
+		else if (mAppAngle > 2.f)
+		{
+			// far away is faded out also
+			alpha = (mAppAngle-2.f)/3.f;
+		}
 
 	if (alpha <= 0.f)
-			{
+	{
 		if (mNameText)
 		{
 			mNameText->markDead();
@@ -2968,31 +2962,30 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-				if (!mNameText)
-				{
+	if (!mNameText)
+	{
 		mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
 			LLHUDObject::LL_HUD_NAME_TAG) );
 		//mNameText->setMass(10.f);
-					mNameText->setSourceObject(this);
+		mNameText->setSourceObject(this);
 		mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
-					mNameText->setVisibleOffScreen(TRUE);
-					mNameText->setMaxLines(11);
-					mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
-					sNumVisibleChatBubbles++;
-					new_name = TRUE;
-				}
+		mNameText->setVisibleOffScreen(TRUE);
+		mNameText->setMaxLines(11);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+		sNumVisibleChatBubbles++;
+		new_name = TRUE;
+	}
 				
-	LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
-	mNameText->setPositionAgent(name_position);				
+	idleUpdateNameTagPosition(root_pos_last);
 	idleUpdateNameTagText(new_name);			
 	idleUpdateNameTagAlpha(new_name, alpha);
 }
 
 void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
-			{
-		LLNameValue *title = getNVPair("Title");
-		LLNameValue* firstname = getNVPair("FirstName");
-		LLNameValue* lastname = getNVPair("LastName");
+{
+	LLNameValue *title = getNVPair("Title");
+	LLNameValue* firstname = getNVPair("FirstName");
+	LLNameValue* lastname = getNVPair("LastName");
 
 	// Avatars must have a first and last name
 	if (!firstname || !lastname) return;
@@ -3006,34 +2999,29 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		is_muted = false;
 	}
 	else
-		{
+	{
 		is_muted = LLMuteList::getInstance()->isMuted(getID());
 	}
 	bool is_friend = LLAvatarTracker::instance().isBuddy(getID());
 	bool is_cloud = getIsCloud();
 
-			if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
-			{
-				if (is_appearance != mNameAppearance)
-				{
-					if (is_appearance)
-					{
-						LLSD args;
-						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
-						args["NAME"] = getFullname();
-						LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
-						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
-					}
-					else
-					{
-						LLSD args;
-						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
-						args["NAME"] = getFullname();
-						LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
-						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
-					}
-				}
-			}
+	if (gSavedSettings.getBOOL("DebugAvatarRezTime")
+		&& is_appearance != mNameAppearance)
+	{
+		LLSD args;
+		args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
+		args["NAME"] = getFullname();
+		if (is_appearance)
+		{
+			LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
+			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
+		}
+		else
+		{
+			LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
+			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
+		}
+	}
 
 	// Rebuild name tag if state change detected
 	if (mNameString.empty()
@@ -3043,39 +3031,39 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		|| is_away != mNameAway 
 		|| is_busy != mNameBusy 
 		|| is_muted != mNameMute
-				|| is_appearance != mNameAppearance 
+		|| is_appearance != mNameAppearance 
 		|| is_friend != mNameFriend
 		|| is_cloud != mNameCloud)
-				{
+	{
 		LLColor4 name_tag_color = getNameTagColor(is_friend);
 
 		clearNameTag();
 
 		if (is_away || is_muted || is_busy || is_appearance)
-				{
+		{
 			std::string line;
-					if (is_away)
-					{
-						line += LLTrans::getString("AvatarAway");
+			if (is_away)
+			{
+				line += LLTrans::getString("AvatarAway");
 				line += ", ";
-					}
-					if (is_busy)
-					{
+			}
+			if (is_busy)
+			{
 				line += LLTrans::getString("AvatarBusy");
 				line += ", ";
 			}
 			if (is_muted)
-						{
+			{
 				line += LLTrans::getString("AvatarMuted");
-							line += ", ";
-						}
+				line += ", ";
+			}
 			if (is_appearance)
 			{
 				line += LLTrans::getString("AvatarEditingAppearance");
 				line += ", ";
-					}
+			}
 			if (is_cloud)
-					{
+			{
 				line += LLTrans::getString("LoadingData");
 				line += ", ";
 			}
@@ -3087,12 +3075,12 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 
 		if (sRenderGroupTitles
 			&& title && title->getString() && title->getString()[0] != '\0')
-						{
+		{
 			std::string title_str = title->getString();
 			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
 			addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
 				LLFontGL::getFontSansSerifSmall());
-						}
+		}
 
 		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
 		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
@@ -3106,119 +3094,118 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 				// and force a rebuild
 				LLAvatarNameCache::get(getID(),
 					boost::bind(&LLVOAvatar::clearNameTag, this));
-					}
+			}
 
 			// Might be blank if name not available yet, that's OK
 			if (show_display_names)
 			{
 				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
 					LLFontGL::getFontSansSerif());
-				}
+			}
 			// Suppress SLID display if display name matches exactly (ugh)
 			if (show_usernames && !av_name.mIsDisplayNameDefault)
-				{
+			{
 				// *HACK: Desaturate the color
 				LLColor4 username_color = name_tag_color * 0.83f;
 				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
 					LLFontGL::getFontSansSerifSmall());
 			}
-				}
+		}
 		else
-				{
+		{
 			const LLFontGL* font = LLFontGL::getFontSansSerif();
-			std::string full_name =
-				LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+			std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
 			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
-				}
+		}
 
-				mNameAway = is_away;
-				mNameBusy = is_busy;
-				mNameMute = is_muted;
-				mNameAppearance = is_appearance;
-		mNameFriend = is_friend;
-				mNameCloud = is_cloud;
-				mTitle = title ? title->getString() : "";
-				LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
-				new_name = TRUE;
-			}
+		mNameAway 		= is_away;
+		mNameBusy 		= is_busy;
+		mNameMute 		= is_muted;
+		mNameAppearance = is_appearance;
+		mNameFriend 	= is_friend;
+		mNameCloud 		= is_cloud;
+		mTitle 			= title ? title->getString() : "";
+		LLStringFn::replace_ascii_controlchars(mTitle, LL_UNKNOWN_CHAR);
+		new_name = TRUE;
+	}
 
 	if (mVisibleChat)
-			{
-				mNameText->setFont(LLFontGL::getFontSansSerif());
+	{
+		mNameText->setFont(LLFontGL::getFontSansSerif());
 		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
-				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
-			
-				char line[MAX_STRING];		/* Flawfinder: ignore */
-				line[0] = '\0';
-				std::deque<LLChat>::iterator chat_iter = mChats.begin();
-				mNameText->clearString();
-
-				LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
-				LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
-				LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
-				if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
-				{
-					++chat_iter;
-				}
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
 
-				for(; chat_iter != mChats.end(); ++chat_iter)
-				{
-					F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
-					LLFontGL::StyleFlags style;
-					switch(chat_iter->mChatType)
-					{
-						case CHAT_TYPE_WHISPER:
-							style = LLFontGL::ITALIC;
-							break;
-						case CHAT_TYPE_SHOUT:
-							style = LLFontGL::BOLD;
-							break;
-						default:
-							style = LLFontGL::NORMAL;
-							break;
-					}
-					if (chat_fade_amt < 1.f)
-					{
-						F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
-						mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
-					}
-					else if (chat_fade_amt < 2.f)
-					{
-						F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
-						mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
-					}
-					else if (chat_fade_amt < 3.f)
-					{
-						// *NOTE: only remove lines down to minimum number
-						mNameText->addLine(chat_iter->mText, old_chat, style);
-					}
-				}
-				mNameText->setVisibleOffScreen(TRUE);
+		char line[MAX_STRING];		/* Flawfinder: ignore */
+		line[0] = '\0';
+		std::deque<LLChat>::iterator chat_iter = mChats.begin();
+		mNameText->clearString();
 
-				if (mTyping)
-				{
-					S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
-					switch(dot_count)
-					{
-						case 1:
-							mNameText->addLine(".", new_chat);
-							break;
-						case 2:
-							mNameText->addLine("..", new_chat);
-							break;
-						case 3:
-							mNameText->addLine("...", new_chat);
-							break;
-					}
+		LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
+		LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
+		LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
+		if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
+		{
+			++chat_iter;
+		}
 
-				}
+		for(; chat_iter != mChats.end(); ++chat_iter)
+		{
+			F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
+			LLFontGL::StyleFlags style;
+			switch(chat_iter->mChatType)
+			{
+			case CHAT_TYPE_WHISPER:
+				style = LLFontGL::ITALIC;
+				break;
+			case CHAT_TYPE_SHOUT:
+				style = LLFontGL::BOLD;
+				break;
+			default:
+				style = LLFontGL::NORMAL;
+				break;
 			}
-			else
+			if (chat_fade_amt < 1.f)
 			{
+				F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
+				mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
+			}
+			else if (chat_fade_amt < 2.f)
+			{
+				F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
+				mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
+			}
+			else if (chat_fade_amt < 3.f)
+			{
+				// *NOTE: only remove lines down to minimum number
+				mNameText->addLine(chat_iter->mText, old_chat, style);
+			}
+		}
+		mNameText->setVisibleOffScreen(TRUE);
+
+		if (mTyping)
+		{
+			S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
+			switch(dot_count)
+			{
+			case 1:
+				mNameText->addLine(".", new_chat);
+				break;
+			case 2:
+				mNameText->addLine("..", new_chat);
+				break;
+			case 3:
+				mNameText->addLine("...", new_chat);
+				break;
+			}
+
+		}
+	}
+	else
+	{
 		// ...not using chat bubbles, just names
 		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
-				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
-				mNameText->setVisibleOffScreen(FALSE);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+		mNameText->setVisibleOffScreen(FALSE);
 	}
 }
 
@@ -3241,8 +3228,8 @@ void LLVOAvatar::clearNameTag()
 {
 	mNameString.clear();
 	if (mNameText)
-				{
-					mNameText->setLabel("");
+	{
+		mNameText->setLabel("");
 		mNameText->setString( "" );
 	}
 }
@@ -3270,34 +3257,45 @@ void LLVOAvatar::invalidateNameTags()
 		if (avatar->isDead()) continue;
 
 		avatar->clearNameTag();
-
 	}
 }
 
 // Compute name tag position during idle update
-LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
+void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 {
 	LLQuaternion root_rot = mRoot.getWorldRotation();
+	LLQuaternion inv_root_rot = ~root_rot;
 	LLVector3 pixel_right_vec;
 	LLVector3 pixel_up_vec;
 	LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
 	LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
 	camera_to_av.normalize();
-	LLVector3 local_camera_at = camera_to_av * ~root_rot;
+	LLVector3 local_camera_at = camera_to_av * inv_root_rot;
 	LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
 	local_camera_up.normalize();
-	local_camera_up = local_camera_up * ~root_rot;
+	local_camera_up = local_camera_up * inv_root_rot;
+
+	LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f,
+								mBodySize.mV[VY] * 0.4f,
+								mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT);
 
-	local_camera_up.scaleVec(mBodySize * 0.5f);
-	local_camera_at.scaleVec(mBodySize * 0.5f);
+	local_camera_up.scaleVec(avatar_ellipsoid);
+	local_camera_at.scaleVec(avatar_ellipsoid);
 
-	LLVector3 name_position = mRoot.getWorldPosition();
-	name_position[VZ] -= mPelvisToFoot;
-	name_position[VZ] += (mBodySize[VZ]* 0.55f);
+	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot.getLastWorldPosition()) * inv_root_rot;
+
+	if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
+	{
+		mTargetRootToHeadOffset = head_offset;
+	}
+	
+	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f));
+
+	LLVector3 name_position = mRoot.getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
 	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	
-	name_position += pixel_up_vec * 15.f;
+	name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
 
-	return name_position;
+	mNameText->setPositionAgent(name_position);				
 }
 
 void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
@@ -3333,7 +3331,7 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
 		else
 		{
 			color_name = "NameTagMismatch";
-	}
+		}
 	}
 	else
 	{
@@ -3370,9 +3368,9 @@ bool LLVOAvatar::isVisuallyMuted()
 	static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
 	static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
 	
-	return LLMuteList::getInstance()->isMuted(getID()) ||
-			(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
-			(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
+	return LLMuteList::getInstance()->isMuted(getID()) 
+			|| (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) 
+			|| (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
 }
 
 //------------------------------------------------------------------------
@@ -3413,8 +3411,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 	}
 
-	LLVector3d root_pos_global;
-
 	if (!mIsBuilt)
 	{
 		return FALSE;
@@ -3428,7 +3424,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	{
 		mTimeVisible.reset();
 	}
-
 	
 	//--------------------------------------------------------------------
 	// the rest should only be done occasionally for far away avatars
@@ -3823,10 +3818,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 		if ( playSound )
 		{
-//			F32 gain = clamp_rescale( mSpeedAccum,
-//							AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
-//							AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
-
 			const F32 STEP_VOLUME = 0.1f;
 			const LLUUID& step_sound_id = getStepSound();
 
@@ -4043,13 +4034,6 @@ void LLVOAvatar::updateVisibility()
 		{
 			releaseMeshData();
 		}
-		// this breaks off-screen chat bubbles
-		//if (mNameText)
-		//{
-		//	mNameText->markDead();
-		//	mNameText = NULL;
-		//	sNumVisibleChatBubbles--;
-		//}
 	}
 
 	mVisible = visible;
@@ -4065,46 +4049,6 @@ bool LLVOAvatar::shouldAlphaMask()
 
 }
 
-U32 LLVOAvatar::renderSkinnedAttachments()
-{
-	/*U32 num_indices = 0;
-	
-	const U32 data_mask =	LLVertexBuffer::MAP_VERTEX | 
-							LLVertexBuffer::MAP_NORMAL | 
-							LLVertexBuffer::MAP_TEXCOORD0 |
-							LLVertexBuffer::MAP_COLOR |
-							LLVertexBuffer::MAP_WEIGHT4;
-
-	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); 
-		 iter != mAttachmentPoints.end();
-		 ++iter)
-	{
-		LLViewerJointAttachment* attachment = iter->second;
-		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-			 attachment_iter != attachment->mAttachedObjects.end();
-			 ++attachment_iter)
-		{
-			const LLViewerObject* attached_object = (*attachment_iter);
-			if (attached_object && !attached_object->isHUDAttachment())
-			{
-				const LLDrawable* drawable = attached_object->mDrawable;
-				if (drawable)
-				{
-					for (S32 i = 0; i < drawable->getNumFaces(); ++i)
-					{
-						LLFace* face = drawable->getFace(i);
-						if (face->isState(LLFace::RIGGED))
-						{
-							
-				}
-			}
-		}
-	}
-
-	return num_indices;*/
-	return 0;
-}
-
 //-----------------------------------------------------------------------------
 // renderSkinned()
 //-----------------------------------------------------------------------------
@@ -4125,11 +4069,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 	{	//LOD changed or new mesh created, allocate new vertex buffer if needed
 		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
 		{
-		updateMeshData();
+			updateMeshData();
 			mDirtyMesh = 0;
-		mNeedsSkin = TRUE;
-		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
-	}
+			mNeedsSkin = TRUE;
+			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+		}
 	}
 
 	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -5790,36 +5734,34 @@ BOOL LLVOAvatar::updateJointLODs()
 	F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
 	F32 area_scale = 0.16f;
 
+	if (isSelf())
 	{
-		if (isSelf())
-		{
-			if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
-			{
-				mAdjustedPixelArea = MAX_PIXEL_AREA;
-			}
-			else
-			{
-				mAdjustedPixelArea = mPixelArea*area_scale;
-			}
-		}
-		else if (mIsDummy)
+		if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
 		{
 			mAdjustedPixelArea = MAX_PIXEL_AREA;
 		}
 		else
 		{
-			// reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
-			mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+			mAdjustedPixelArea = mPixelArea*area_scale;
 		}
+	}
+	else if (mIsDummy)
+	{
+		mAdjustedPixelArea = MAX_PIXEL_AREA;
+	}
+	else
+	{
+		// reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
+		mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+	}
 
-		// now select meshes to render based on adjusted pixel area
-		BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
- 		if (res)
-		{
-			sNumLODChangesThisFrame++;
-			dirtyMesh(2);
-			return TRUE;
-		}
+	// now select meshes to render based on adjusted pixel area
+	BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
+ 	if (res)
+	{
+		sNumLODChangesThisFrame++;
+		dirtyMesh(2);
+		return TRUE;
 	}
 
 	return FALSE;
@@ -6109,25 +6051,18 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
 		if ( pVObj )
 		{
 			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
-			if ( pSkinData )
-			{
-				const int jointCnt = pSkinData->mJointNames.size();
-				bool fullRig = ( jointCnt>=20 ) ? true : false;
-				if ( fullRig )
+			if (pSkinData 
+				&& pSkinData->mJointNames.size() > 20				// full rig
+				&& pSkinData->mAlternateBindMatrix.size() > 0)
+			{
+				LLVOAvatar::resetJointPositionsToDefault();
+				//Need to handle the repositioning of the cam, updating rig data etc during outfit editing 
+				//This handles the case where we detach a replacement rig.
+				if ( gAgentCamera.cameraCustomizeAvatar() )
 				{
-					const int bindCnt = pSkinData->mAlternateBindMatrix.size();							
-					if ( bindCnt > 0 )
-					{
-						LLVOAvatar::resetJointPositionsToDefault();
-						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing 
-						//This handles the case where we detach a replacement rig.
-						if ( gAgentCamera.cameraCustomizeAvatar() )
-						{
-							gAgent.unpauseAnimation();
-							//Still want to refocus on head bone
-							gAgentCamera.changeCameraToCustomizeAvatar();
-						}
-					}
+					gAgent.unpauseAnimation();
+					//Still want to refocus on head bone
+					gAgentCamera.changeCameraToCustomizeAvatar();
 				}
 			}				
 		}
@@ -6281,11 +6216,7 @@ void LLVOAvatar::getOffObject()
 		at_axis.mV[VZ] = 0.f;
 		at_axis.normalize();
 		gAgent.resetAxes(at_axis);
-
-		//reset orientation
-//		mRoot.setRotation(avWorldRot);
 		gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
-
 		gAgentCamera.setSitCamera(LLUUID::null);
 	}
 }
@@ -6335,7 +6266,6 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
 	}
 	else
 	{
-//		return LLColor4( .5f, .5f, .5f, .5f );
 		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
 	}
 }
@@ -7067,10 +6997,6 @@ LLBBox LLVOAvatar::getHUDBBox() const
 	return bbox;
 }
 
-void LLVOAvatar::rebuildHUD()
-{
-}
-
 //-----------------------------------------------------------------------------
 // onFirstTEMessageReceived()
 //-----------------------------------------------------------------------------
@@ -7192,7 +7118,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 			&& baked_index != BAKED_SKIRT)
 		{
 			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, 
-				LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+						LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, 
+																TRUE, 
+																LLViewerTexture::BOOST_NONE, 
+																LLViewerTexture::LOD_TEXTURE));
 		}
 	}
 
@@ -7483,11 +7412,6 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_
 // Called when baked texture is loaded and also when we start up with a baked texture
 void LLVOAvatar::useBakedTexture( const LLUUID& id )
 {
-	/* if(id == head_baked->getID())
-		 mHeadBakedLoaded = TRUE;
-		 mLastHeadBakedID = id;
-		 mHeadMesh0.setTexture( head_baked );
-		 mHeadMesh1.setTexture( head_baked ); */
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
 		LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );
@@ -7718,111 +7642,111 @@ LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()
 	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
 }
 
-//-----------------------------------------------------------------------------
-// LLVOAvatarBoneInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
-{
-	if (node->hasName("bone"))
-	{
-		mIsJoint = TRUE;
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (!node->getFastAttributeString(name_string, mName))
-		{
-			llwarns << "Bone without name" << llendl;
-			return FALSE;
-		}
-	}
-	else if (node->hasName("collision_volume"))
-	{
-		mIsJoint = FALSE;
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (!node->getFastAttributeString(name_string, mName))
-		{
-			mName = "Collision Volume";
-		}
-	}
-	else
-	{
-		llwarns << "Invalid node " << node->getName() << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
-	if (!node->getFastAttributeVector3(pos_string, mPos))
-	{
-		llwarns << "Bone without position" << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
-	if (!node->getFastAttributeVector3(rot_string, mRot))
-	{
-		llwarns << "Bone without rotation" << llendl;
-		return FALSE;
-	}
-	
-	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
-	if (!node->getFastAttributeVector3(scale_string, mScale))
-	{
-		llwarns << "Bone without scale" << llendl;
-		return FALSE;
-	}
-
-	if (mIsJoint)
-	{
-		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
-		if (!node->getFastAttributeVector3(pivot_string, mPivot))
-		{
-			llwarns << "Bone without pivot" << llendl;
-			return FALSE;
-		}
-	}
-
-	// parse children
-	LLXmlTreeNode* child;
-	for( child = node->getFirstChild(); child; child = node->getNextChild() )
-	{
-		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
-		if (!child_info->parseXml(child))
-		{
-			delete child_info;
-			return FALSE;
-		}
-		mChildList.push_back(child_info);
-	}
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarSkeletonInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
-{
-	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
-	if (!node->getFastAttributeS32(num_bones_string, mNumBones))
-	{
-		llwarns << "Couldn't find number of bones." << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
-	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
-
-	LLXmlTreeNode* child;
-	for( child = node->getFirstChild(); child; child = node->getNextChild() )
-	{
-		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
-		if (!info->parseXml(child))
-		{
-			delete info;
-			llwarns << "Error parsing bone in skeleton file" << llendl;
-			return FALSE;
-		}
-		mBoneInfoList.push_back(info);
-	}
-	return TRUE;
-}
+////-----------------------------------------------------------------------------
+//// LLVOAvatarBoneInfo::parseXml()
+////-----------------------------------------------------------------------------
+//BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
+//{
+//	if (node->hasName("bone"))
+//	{
+//		mIsJoint = TRUE;
+//		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+//		if (!node->getFastAttributeString(name_string, mName))
+//		{
+//			llwarns << "Bone without name" << llendl;
+//			return FALSE;
+//		}
+//	}
+//	else if (node->hasName("collision_volume"))
+//	{
+//		mIsJoint = FALSE;
+//		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+//		if (!node->getFastAttributeString(name_string, mName))
+//		{
+//			mName = "Collision Volume";
+//		}
+//	}
+//	else
+//	{
+//		llwarns << "Invalid node " << node->getName() << llendl;
+//		return FALSE;
+//	}
+//
+//	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
+//	if (!node->getFastAttributeVector3(pos_string, mPos))
+//	{
+//		llwarns << "Bone without position" << llendl;
+//		return FALSE;
+//	}
+//
+//	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
+//	if (!node->getFastAttributeVector3(rot_string, mRot))
+//	{
+//		llwarns << "Bone without rotation" << llendl;
+//		return FALSE;
+//	}
+//	
+//	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+//	if (!node->getFastAttributeVector3(scale_string, mScale))
+//	{
+//		llwarns << "Bone without scale" << llendl;
+//		return FALSE;
+//	}
+//
+//	if (mIsJoint)
+//	{
+//		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
+//		if (!node->getFastAttributeVector3(pivot_string, mPivot))
+//		{
+//			llwarns << "Bone without pivot" << llendl;
+//			return FALSE;
+//		}
+//	}
+//
+//	// parse children
+//	LLXmlTreeNode* child;
+//	for( child = node->getFirstChild(); child; child = node->getNextChild() )
+//	{
+//		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
+//		if (!child_info->parseXml(child))
+//		{
+//			delete child_info;
+//			return FALSE;
+//		}
+//		mChildList.push_back(child_info);
+//	}
+//	return TRUE;
+//}
+//
+////-----------------------------------------------------------------------------
+//// LLVOAvatarSkeletonInfo::parseXml()
+////-----------------------------------------------------------------------------
+//BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
+//{
+//	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
+//	if (!node->getFastAttributeS32(num_bones_string, mNumBones))
+//	{
+//		llwarns << "Couldn't find number of bones." << llendl;
+//		return FALSE;
+//	}
+//
+//	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
+//	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
+//
+//	LLXmlTreeNode* child;
+//	for( child = node->getFirstChild(); child; child = node->getNextChild() )
+//	{
+//		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
+//		if (!info->parseXml(child))
+//		{
+//			delete info;
+//			llwarns << "Error parsing bone in skeleton file" << llendl;
+//			return FALSE;
+//		}
+//		mBoneInfoList.push_back(info);
+//	}
+//	return TRUE;
+//}
 
 //-----------------------------------------------------------------------------
 // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index dd0317f555..e84acd51ff 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -66,8 +66,9 @@ class LLVoiceVisualizer;
 class LLHUDNameTag;
 class LLHUDEffectSpiral;
 class LLTexGlobalColor;
-class LLVOAvatarBoneInfo;
-class LLVOAvatarSkeletonInfo;
+struct LLVOAvatarBoneInfo;
+struct LLVOAvatarChildJoint;
+struct LLVOAvatarSkeletonInfo;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLVOAvatar
@@ -232,7 +233,7 @@ public:
 	void 			idleUpdateWindEffect();
 	void 			idleUpdateNameTag(const LLVector3& root_pos_last);
 	void			idleUpdateNameTagText(BOOL new_name);
-	LLVector3		idleUpdateNameTagPosition(const LLVector3& root_pos_last);
+	void			idleUpdateNameTagPosition(const LLVector3& root_pos_last);
 	void			idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
 	LLColor4		getNameTagColor(bool is_friend);
 	void			clearNameTag();
@@ -317,6 +318,8 @@ public:
 	F32					mLastPelvisToFoot;
 	F32					mPelvisFixup;
 	F32					mLastPelvisFixup;
+	LLVector3			mCurRootToHeadOffset;
+	LLVector3			mTargetRootToHeadOffset;
 
 	LLVector3			mHeadOffset; // current head position
 	LLViewerJoint		mRoot;
@@ -325,7 +328,7 @@ protected:
 	void				buildCharacter();
 	virtual BOOL		loadAvatar();
 
-	BOOL				setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+	BOOL				setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
 	BOOL				buildSkeleton(const LLVOAvatarSkeletonInfo *info);
 private:
 	BOOL				mIsBuilt; // state of deferred character building
@@ -369,7 +372,7 @@ public:
 	//--------------------------------------------------------------------
 private:
 	static LLXmlTree 	sXMLTree; // avatar config file
-	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file
+	static LLXMLNodePtr	sSkeletonXMLTree; // avatar skeleton file
 
 /**                    Skeleton
  **                                                                            **
@@ -387,7 +390,6 @@ public:
 	U32 		renderRigid();
 	U32 		renderSkinned(EAvatarRenderPass pass);
 	F32			getLastSkinTime() { return mLastSkinTime; }
-	U32			renderSkinnedAttachments();
 	U32 		renderTransparent(BOOL first_pass);
 	void 		renderCollisionVolumes();
 	static void	deleteCachedImages(bool clearAll=true);
@@ -735,7 +737,6 @@ public:
 public:
 	BOOL 				hasHUDAttachment() const;
 	LLBBox 				getHUDBBox() const;
-	void 				rebuildHUD();
 	void 				resetHUDAttachments();
 	BOOL				canAttachMoreObjects() const;
 	BOOL				canAttachMoreObjects(U32 n) const;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c523a78b22..fc499bfe9c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4678,11 +4678,6 @@ void LLPipeline::rebuildPools()
 		}
 		max_count--;
 	}
-
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->rebuildHUD();
-	}
 }
 
 void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
-- 
cgit v1.2.3


From 2eb0096dd7f173debc27c155c57969ae5cb67682 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 5 Apr 2012 17:50:22 -0700
Subject: added support for LLInitParam::Lazy<scalar> to support
 lazy-initialized non-param-block values

---
 indra/llxuixml/llinitparam.h | 94 +++++++++++++++++++++++---------------------
 1 file changed, 50 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 6fffb73acd..6c054b934b 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -369,11 +369,30 @@ namespace LLInitParam
 		class BaseBlock*				mCurrentBlockPtr;		// pointer to block currently being constructed
 	};
 
+	struct IS_BLOCK {};
+	struct NOT_BLOCK {};
+
+	// these templates allow us to distinguish between template parameters
+	// that derive from BaseBlock and those that don't
+	template<typename T, typename BLOCK_IDENTIFIER = void>
+	struct IsBlock
+	{
+		static const bool value = false;
+		typedef NOT_BLOCK value_t;
+	};
+
+	template<typename T>
+	struct IsBlock<T, typename T::baseblock_base_class_t>
+	{
+		static const bool value = true;
+		typedef IS_BLOCK value_t;
+	};
+
 	class BaseBlock
 	{
 	public:
 		//TODO: implement in terms of owned_ptr
-		template<typename T>
+		template<typename T, bool IS_BLOCK = true>
 		class Lazy
 		{
 		public:
@@ -404,7 +423,7 @@ namespace LLInitParam
 				}
 			}
 
-			Lazy<T>& operator = (const Lazy<T>& other)
+			Lazy& operator = (const Lazy& other)
 			{
 				if (other.mPtr)
 				{
@@ -462,6 +481,7 @@ namespace LLInitParam
 			mutable T* mPtr;
 		};
 
+
 		// "Multiple" constraint types, put here in root class to avoid ambiguity during use
 		struct AnyAmount
 		{
@@ -611,19 +631,6 @@ namespace LLInitParam
 
 	};
 
-	// these templates allow us to distinguish between template parameters
-	// that derive from BaseBlock and those that don't
-	template<typename T, typename BLOCK_IDENTIFIER = void>
-	struct IsBlock
-	{
-		static const bool value = false;
-	};
-
-	template<typename T>
-	struct IsBlock<T, typename T::baseblock_base_class_t>
-	{
-		static const bool value = true;
-	};
 
 	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
 	class ParamValue : public NAME_VALUE_LOOKUP
@@ -805,7 +812,7 @@ namespace LLInitParam
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
-			bool		VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>
+			bool		VALUE_IS_BLOCK = IsBlock<T>::value>
 	class TypedParam 
 	:	public Param, 
 		public ParamValue<T, NAME_VALUE_LOOKUP>
@@ -1034,7 +1041,7 @@ namespace LLInitParam
 			}
 			else
 			{
-				typed_param.serializeBlock(parser, name_stack, &static_cast<const BaseBlock&>(*static_cast<const self_t*>(diff_param)));
+				typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
 			}
 		}
 
@@ -1582,7 +1589,7 @@ namespace LLInitParam
 			friend class ChoiceBlock<DERIVED_BLOCK>;
 
 			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t;
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<T>::value>		super_t;
 			typedef typename super_t::value_assignment_t								value_assignment_t;
 
 			using super_t::operator =;
@@ -1700,7 +1707,7 @@ namespace LLInitParam
 		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<T>::value>		super_t;
 			typedef typename super_t::value_assignment_t								value_assignment_t;
 
 			using super_t::operator();
@@ -1729,7 +1736,7 @@ namespace LLInitParam
 		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<T>::value>		super_t;
 			typedef Mandatory<T, NAME_VALUE_LOOKUP>										self_t;
 			typedef typename super_t::value_assignment_t								value_assignment_t;
 
@@ -1765,7 +1772,7 @@ namespace LLInitParam
 		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>	super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<T>::value>	super_t;
 			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>							self_t;
 			typedef typename super_t::container_t									container_t;
 			typedef typename super_t::value_assignment_t							value_assignment_t;
@@ -1948,20 +1955,21 @@ namespace LLInitParam
 	};
 
 	template<typename T, typename BLOCK_IDENTIFIER>
-	struct IsBlock<ParamValue<BaseBlock::Lazy<T>, TypeValues<BaseBlock::Lazy<T> > > , BLOCK_IDENTIFIER>
+	struct IsBlock<BaseBlock::Lazy<T, true>, BLOCK_IDENTIFIER>
 	{
-		static const bool value = true;//IsBlock<T>::value;
+		static const bool value = true;
 	};
 
-	template<typename T>
-	struct ParamCompare<BaseBlock::Lazy<T>, false>
+	template<typename T, typename BLOCK_IDENTIFIER>
+	struct IsBlock<BaseBlock::Lazy<T, false>, BLOCK_IDENTIFIER>
 	{
-		static bool equals(const T&a, const T &b)
-		{
-			return a == b;
-		}
+		static const bool value = false;
+	};
 
-		static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b)
+	template<typename T, bool IS_BLOCK>
+	struct ParamCompare<BaseBlock::Lazy<T, IS_BLOCK>, false>
+	{
+		static bool equals(const BaseBlock::Lazy<T, IS_BLOCK>& a, const BaseBlock::Lazy<T, IS_BLOCK>& b)
 		{
 			if (a.empty() || b.empty()) return false;
 			return a.get() == b.get();
@@ -1969,14 +1977,14 @@ namespace LLInitParam
 	};
 
 
-	template<typename T, bool VALUE_IS_BLOCK>
-	class ParamValue <BaseBlock::Lazy<T>,
-					TypeValues<BaseBlock::Lazy<T> >,
-					VALUE_IS_BLOCK>
+	template<typename T>
+	class ParamValue <BaseBlock::Lazy<T, true>,
+					TypeValues<BaseBlock::Lazy<T, true> >,
+					true>
 	:	public TypeValues<T>
 	{
 	public:
-		typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<BaseBlock::Lazy<T> >, false> self_t;
+		typedef ParamValue <BaseBlock::Lazy<T, true>, TypeValues<BaseBlock::Lazy<T, true> >, true> self_t;
 		typedef const T& value_assignment_t;
 		typedef T value_t;
 	
@@ -1985,7 +1993,7 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		ParamValue(const BaseBlock::Lazy<T>& other)
+		ParamValue(const BaseBlock::Lazy<T, true>& other)
 		:	mValue(other),
 			mValidated(false)
 		{}
@@ -2010,11 +2018,6 @@ namespace LLInitParam
 			return mValue.get();
 		}
 
-		operator const BaseBlock&() const
-		{
-			return mValue.get();
-		}
-
 		operator value_assignment_t() const
 		{
 			return mValue.get();
@@ -2030,11 +2033,14 @@ namespace LLInitParam
 			return mValue.get().deserializeBlock(p, name_stack_range, new_name);
 		}
 
-		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
 		{
 			if (mValue.empty()) return;
 			
-			mValue.get().serializeBlock(p, name_stack, diff_block);
+			const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())
+											? &(diff_block->mValue.get())
+											: NULL;
+			mValue.get().serializeBlock(p, name_stack, base_block);
 		}
 
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
@@ -2063,7 +2069,7 @@ namespace LLInitParam
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
-		BaseBlock::Lazy<T>	mValue;
+		BaseBlock::Lazy<T, true>	mValue;
 	};
 
 	template <>
-- 
cgit v1.2.3


From 6dd7029942dcc381d670657e0c4bb7d8dcd24594 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 5 Apr 2012 18:11:45 -0700
Subject: optimized Lazy<T> params - don't generate block when checking
 validity or merging

---
 indra/llxuixml/llinitparam.h | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 6c054b934b..1f0dec5d94 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -436,6 +436,12 @@ namespace LLInitParam
 				return *this;
 			}
 
+			bool operator==(const Lazy& other) const
+			{
+				if (empty() || other.empty()) return false;
+				return *mPtr == *other.mPtr;
+			}
+
 			bool empty() const
 			{
 				return mPtr == NULL;
@@ -1966,17 +1972,6 @@ namespace LLInitParam
 		static const bool value = false;
 	};
 
-	template<typename T, bool IS_BLOCK>
-	struct ParamCompare<BaseBlock::Lazy<T, IS_BLOCK>, false>
-	{
-		static bool equals(const BaseBlock::Lazy<T, IS_BLOCK>& a, const BaseBlock::Lazy<T, IS_BLOCK>& b)
-		{
-			if (a.empty() || b.empty()) return false;
-			return a.get() == b.get();
-		}
-	};
-
-
 	template<typename T>
 	class ParamValue <BaseBlock::Lazy<T, true>,
 					TypeValues<BaseBlock::Lazy<T, true> >,
@@ -2045,19 +2040,17 @@ namespace LLInitParam
 
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
 		{
-			if (mValue.empty()) return false;
-
 			return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
 		}
 
 		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
 		{
-			return mValue.get().mergeBlock(block_data, source.getValue(),  overwrite);
+			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(),  overwrite);
 		}
 
 		bool validateBlock(bool emit_errors = true) const
 		{
-			return mValue.get().validateBlock(emit_errors);
+			return mValue.empty() || mValue.get().validateBlock(emit_errors);
 		}
 
 		static BlockDescriptor& getBlockDescriptor()
-- 
cgit v1.2.3


From 7996857500004ed9b717e049423c52be96db9191 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Thu, 12 Apr 2012 00:43:37 +0300
Subject: CHUI-80 FIXED Implemented volume indicator pop-up.

It is invoked by clicking on any speaking indicator except yours.
---
 indra/newview/CMakeLists.txt                       |   2 +
 indra/newview/llavataractions.cpp                  |  26 +++
 indra/newview/llavataractions.h                    |  10 +
 indra/newview/llfloatervoicevolume.cpp             | 209 +++++++++++++++++++++
 indra/newview/llfloatervoicevolume.h               |  35 ++++
 indra/newview/llinspectavatar.cpp                  |   3 +-
 indra/newview/lloutputmonitorctrl.cpp              |  12 ++
 indra/newview/lloutputmonitorctrl.h                |   1 +
 indra/newview/llviewerfloaterreg.cpp               |   2 +
 .../skins/default/xui/en/floater_voice_volume.xml  |  59 ++++++
 10 files changed, 357 insertions(+), 2 deletions(-)
 create mode 100644 indra/newview/llfloatervoicevolume.cpp
 create mode 100644 indra/newview/llfloatervoicevolume.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_voice_volume.xml

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f85b943c70..6197856512 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -244,6 +244,7 @@ set(viewer_SOURCE_FILES
     llfloateruipreview.cpp
     llfloaterurlentry.cpp
     llfloatervoiceeffect.cpp
+    llfloatervoicevolume.cpp
     llfloaterwebcontent.cpp
     llfloaterwebprofile.cpp
     llfloaterwhitelistentry.cpp
@@ -800,6 +801,7 @@ set(viewer_HEADER_FILES
     llfloateruipreview.h
     llfloaterurlentry.h
     llfloatervoiceeffect.h
+    llfloatervoicevolume.h
     llfloaterwebcontent.h
     llfloaterwebprofile.h
     llfloaterwhitelistentry.h
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 9a7cdcfa21..ac14ec2cc0 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -808,6 +808,26 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
 	}
 }
 
+// static
+void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
+{
+	std::string name;
+	gCacheName->getFullName(id, name); // needed for mute
+
+	LLMuteList* mute_list = LLMuteList::getInstance();
+	bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat);
+
+	LLMute mute(id, name, LLMute::AGENT);
+	if (!is_muted)
+	{
+		mute_list->add(mute, LLMute::flagVoiceChat);
+	}
+	else
+	{
+		mute_list->remove(mute, LLMute::flagVoiceChat);
+	}
+}
+
 // static
 bool LLAvatarActions::canOfferTeleport(const LLUUID& id)
 {
@@ -1022,6 +1042,12 @@ bool LLAvatarActions::isBlocked(const LLUUID& id)
 	return LLMuteList::getInstance()->isMuted(id, name);
 }
 
+// static
+bool LLAvatarActions::isVoiceMuted(const LLUUID& id)
+{
+	return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
+}
+
 // static
 bool LLAvatarActions::canBlock(const LLUUID& id)
 {
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 748b7cb3d1..e5dad74fc8 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -123,6 +123,11 @@ public:
 	 */
 	static void toggleBlock(const LLUUID& id);
 
+	/**
+	 * Block/unblock the avatar voice.
+	 */
+	static void toggleMuteVoice(const LLUUID& id);
+
 	/**
 	 * Return true if avatar with "id" is a friend
 	 */
@@ -133,6 +138,11 @@ public:
 	 */
 	static bool isBlocked(const LLUUID& id);
 
+	/**
+	 * @return true if the avatar voice is blocked
+	 */
+	static bool isVoiceMuted(const LLUUID& id);
+
 	/**
 	 * @return true if you can block the avatar
 	 */
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
new file mode 100644
index 0000000000..87b388b30a
--- /dev/null
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -0,0 +1,209 @@
+/** 
+ * @file llfloatervoicevolume.cpp
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatervoicevolume.h"
+
+// Linden libraries
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "lltextbox.h"
+
+// viewer files
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llinspect.h"
+#include "lltransientfloatermgr.h"
+#include "llvoiceclient.h"
+
+class LLAvatarName;
+
+//////////////////////////////////////////////////////////////////////////////
+// LLFloaterVoiceVolume
+//////////////////////////////////////////////////////////////////////////////
+
+// Avatar Inspector, a small information window used when clicking
+// on avatar names in the 2D UI and in the ambient inspector widget for
+// the 3D world.
+class LLFloaterVoiceVolume : public LLInspect, LLTransientFloater
+{
+	friend class LLFloaterReg;
+	
+public:
+	// avatar_id - Avatar ID for which to show information
+	// Inspector will be positioned relative to current mouse position
+	LLFloaterVoiceVolume(const LLSD& avatar_id);
+	virtual ~LLFloaterVoiceVolume();
+	
+	/*virtual*/ BOOL postBuild(void);
+	
+	// Because floater is single instance, need to re-parse data on each spawn
+	// (for example, inspector about same avatar but in different position)
+	/*virtual*/ void onOpen(const LLSD& avatar_id);
+
+	/*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
+
+private:
+	// Set the volume slider to this user's current client-side volume setting,
+	// hiding/disabling if the user is not nearby.
+	void updateVolumeControls();
+
+	void onClickMuteVolume();
+	void onVolumeChange(const LLSD& data);
+	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+	
+private:
+	LLUUID				mAvatarID;
+	// Need avatar name information to spawn friend add request
+	LLAvatarName		mAvatarName;
+};
+
+LLFloaterVoiceVolume::LLFloaterVoiceVolume(const LLSD& sd)
+:	LLInspect(LLSD())		// single_instance, doesn't really need key
+,	mAvatarID()				// set in onOpen()  *Note: we used to show partner's name but we dont anymore --angela 3rd Dec*
+,	mAvatarName()
+{
+	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
+	LLTransientFloater::init(this);
+}
+
+LLFloaterVoiceVolume::~LLFloaterVoiceVolume()
+{
+	LLTransientFloaterMgr::getInstance()->removeControlView(this);
+}
+
+/*virtual*/
+BOOL LLFloaterVoiceVolume::postBuild(void)
+{
+	getChild<LLUICtrl>("mute_btn")->setCommitCallback(
+		boost::bind(&LLFloaterVoiceVolume::onClickMuteVolume, this) );
+
+	getChild<LLUICtrl>("volume_slider")->setCommitCallback(
+		boost::bind(&LLFloaterVoiceVolume::onVolumeChange, this, _2));
+
+	return TRUE;
+}
+
+
+// Multiple calls to showInstance("floater_voice_volume", foo) will provide different
+// LLSD for foo, which we will catch here.
+//virtual
+void LLFloaterVoiceVolume::onOpen(const LLSD& data)
+{
+	// Start open animation
+	LLInspect::onOpen(data);
+
+	// Extract appropriate avatar id
+	mAvatarID = data["avatar_id"];
+
+	LLUI::positionViewNearMouse(this);
+
+	getChild<LLUICtrl>("avatar_name")->setValue("");
+	updateVolumeControls();
+
+	LLAvatarNameCache::get(mAvatarID,
+		boost::bind(&LLFloaterVoiceVolume::onAvatarNameCache, this, _1, _2));
+}
+
+void LLFloaterVoiceVolume::updateVolumeControls()
+{
+	bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID);
+
+	LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
+	LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
+
+	// Do not display volume slider and mute button if it 
+	// is ourself or we are not in a voice channel together
+	if (!voice_enabled || (mAvatarID == gAgent.getID()))
+	{
+		mute_btn->setVisible(false);
+		volume_slider->setVisible(false);
+	}
+	else 
+	{
+		mute_btn->setVisible(true);
+		volume_slider->setVisible(true);
+
+		// By convention, we only display and toggle voice mutes, not all mutes
+		bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
+		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
+
+		mute_btn->setEnabled(!is_linden);
+		mute_btn->setValue(is_muted);
+
+		volume_slider->setEnabled(!is_muted);
+
+		F32 volume;
+		if (is_muted)
+		{
+			// it's clearer to display their volume as zero
+			volume = 0.f;
+		}
+		else
+		{
+			// actual volume
+			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
+		}
+		volume_slider->setValue((F64)volume);
+	}
+
+}
+
+void LLFloaterVoiceVolume::onClickMuteVolume()
+{
+	LLAvatarActions::toggleMuteVoice(mAvatarID);
+	updateVolumeControls();
+}
+
+void LLFloaterVoiceVolume::onVolumeChange(const LLSD& data)
+{
+	F32 volume = (F32)data.asReal();
+	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
+}
+
+void LLFloaterVoiceVolume::onAvatarNameCache(
+		const LLUUID& agent_id,
+		const LLAvatarName& av_name)
+{
+	if (agent_id != mAvatarID)
+	{
+		return;
+	}
+
+	getChild<LLUICtrl>("avatar_name")->setValue(av_name.getCompleteName());
+	mAvatarName = av_name;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// LLFloaterVoiceVolumeUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterVoiceVolumeUtil::registerFloater()
+{
+	LLFloaterReg::add("floater_voice_volume", "floater_voice_volume.xml",
+					  &LLFloaterReg::build<LLFloaterVoiceVolume>);
+}
diff --git a/indra/newview/llfloatervoicevolume.h b/indra/newview/llfloatervoicevolume.h
new file mode 100644
index 0000000000..8fcf7f250b
--- /dev/null
+++ b/indra/newview/llfloatervoicevolume.h
@@ -0,0 +1,35 @@
+/** 
+ * @file llfloatervoicevolume.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERVOICEVOLUME_H
+#define LL_LLFLOATERVOICEVOLUME_H
+
+namespace LLFloaterVoiceVolumeUtil
+{
+	// Register with LLFloaterReg
+	void registerFloater();
+}
+
+#endif // LL_LLFLOATERVOICEVOLUME_H
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 17d0b0ffbb..b2a8c6e3e6 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -558,8 +558,7 @@ void LLInspectAvatar::updateVolumeSlider()
 		getChild<LLUICtrl>("volume_slider")->setVisible(true);
 
 		// By convention, we only display and toggle voice mutes, not all mutes
-		bool is_muted = LLMuteList::getInstance()->
-							isMuted(mAvatarID, LLMute::flagVoiceChat);
+		bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
 
 		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
 
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 85626d8783..096e714981 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -28,6 +28,7 @@
 #include "lloutputmonitorctrl.h"
 
 // library includes 
+#include "llfloaterreg.h"
 #include "llui.h"
 
 // viewer includes
@@ -241,6 +242,17 @@ void LLOutputMonitorCtrl::draw()
 		gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
 }
 
+// virtual
+BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+	if (mSpeakerId != gAgentID)
+	{
+		LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId));
+	}
+
+	return TRUE;
+}
+
 void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/)
 {
 	if (speaker_id.isNull() && mSpeakerId.notNull())
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 2d23753d46..7b02e84744 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -68,6 +68,7 @@ public:
 
 	// llview overrides
 	virtual void	draw();
+	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
 
 	void			setPower(F32 val);
 	F32				getPower(F32 val) const { return mPower; }
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index bb870f7651..685ef44921 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -110,6 +110,7 @@
 #include "llfloatertranslationsettings.h"
 #include "llfloateruipreview.h"
 #include "llfloatervoiceeffect.h"
+#include "llfloatervoicevolume.h"
 #include "llfloaterwhitelistentry.h"
 #include "llfloaterwindowsize.h"
 #include "llfloaterworldmap.h"
@@ -220,6 +221,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLInspectGroupUtil::registerFloater();
 	LLInspectObjectUtil::registerFloater();
 	LLInspectRemoteObjectUtil::registerFloater();
+	LLFloaterVoiceVolumeUtil::registerFloater();
 	LLNotificationsUI::registerFloater();
 	LLFloaterDisplayNameUtil::registerFloater();
 	
diff --git a/indra/newview/skins/default/xui/en/floater_voice_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_volume.xml
new file mode 100644
index 0000000000..9346295d5b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_voice_volume.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+  Not can_close / no title to avoid window chrome
+  Single instance - only have one at a time, recycle it each spawn
+-->
+<floater
+ legacy_header_height="25"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="90"
+ layout="topleft"
+ name="floater_voice_volume"
+ single_instance="true"
+ sound_flags="0"
+ title="VOICE VOLUME"
+ visible="true"
+ width="245">
+    <text
+     follows="top|left|right"
+     font="SansSerifSmall"
+     height="21"
+     left="10"
+     name="avatar_name"
+     parse_urls="false"
+     top="35"
+     text_color="White"
+     translate="false"
+     use_ellipses="true"
+     value="TestString PleaseIgnore"
+     width="225" />
+    <slider
+     follows="top|left"
+     height="23"
+     increment="0.01"
+     left="1"
+     max_val="0.95"
+     min_val="0.05"
+     name="volume_slider"
+     show_text="false"
+     tool_tip="Voice volume"
+     top_pad="0"
+     value="0.5"
+     width="200" />
+    <button
+     follows="top|left"
+     height="16"
+     image_disabled="Audio_Off"
+     image_disabled_selected="AudioMute_Off"
+     image_hover_selected="AudioMute_Over"
+     image_selected="AudioMute_Off"
+     image_unselected="Audio_Off"
+     is_toggle="true"
+     left_pad="0"
+     top_delta="4"
+     name="mute_btn"
+     width="16" />
+</floater>
-- 
cgit v1.2.3


From 4f526f12e6332307c8d3105e5a4f6e35f2dbd3d7 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Fri, 6 Apr 2012 19:29:53 +0300
Subject: CHUI-77 WIP Moved setting filter label to XML.

---
 indra/newview/llpanelpeople.cpp                     |  5 -----
 indra/newview/skins/default/xui/en/panel_people.xml | 14 ++++----------
 2 files changed, 4 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 238834aa92..2d665e9bf3 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -1016,11 +1016,6 @@ void LLPanelPeople::onTabSelected(const LLSD& param)
 	updateButtons();
 
 	showFriendsAccordionsIfNeeded();
-
-	if (GROUP_TAB_NAME == tab_name)
-		mFilterEditor->setLabel(getString("groups_filter_label"));
-	else
-		mFilterEditor->setLabel(getString("people_filter_label"));
 }
 
 void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index f61b0b3dbd..5da87456f1 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -38,12 +38,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      name="no_filtered_friends_msg">
          Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search].
     </string>
-    <string
-     name="people_filter_label"
-     value="Filter People" />
-    <string
-     name="groups_filter_label"
-     value="Filter Groups" />
      <!--
      *WORKAROUND: for group_list.no_items_msg & group_list.no_filtered_items_msg attributes.
      They are not defined as translatable in VLT. See EXT-5931
@@ -104,7 +98,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  height="23"
                  layout="topleft"
                  left="3"
-                 label="Filter"
+                 label="Filter People"
                  max_length_chars="300"
                  name="nearby_filter_input"
                  text_color="Black"
@@ -253,7 +247,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  height="23"
                  layout="topleft"
                  left="3"
-                 label="Filter"
+                 label="Filter People"
                  max_length_chars="300"
                  name="friends_filter_input"
                  text_color="Black"
@@ -410,7 +404,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  height="23"
                  layout="topleft"
                  left="3"
-                 label="Filter"
+                 label="Filter Groups"
                  max_length_chars="300"
                  name="groups_filter_input"
                  text_color="Black"
@@ -533,7 +527,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  height="23"
                  layout="topleft"
                  left="3"
-                 label="Filter"
+                 label="Filter People"
                  max_length_chars="300"
                  name="recent_filter_input"
                  text_color="Black"
-- 
cgit v1.2.3


From fff9567a67ded34471fd17af9c50bc1d307e7b19 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 6 Apr 2012 09:40:59 -0700
Subject: further LLInitParam cleanup changed bool template parameter to
 IS_BLOCK and NOT_BLOCK types moved addParam to BlockDescriptor moved init
 outside of param element constructors for faster construction

---
 indra/llui/llsdparam.cpp       |   6 +-
 indra/llui/lluiimage.h         |   4 +-
 indra/llxuixml/llinitparam.cpp |  59 +++++++-------
 indra/llxuixml/llinitparam.h   | 177 ++++++++++++++++++++++++-----------------
 4 files changed, 137 insertions(+), 109 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 0e29873bb0..828f809452 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -313,7 +313,7 @@ namespace LLInitParam
 {
 	// LLSD specialization
 	// block param interface
-	bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
+	bool ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
 	{
 		LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
 
@@ -328,12 +328,12 @@ namespace LLInitParam
 	}
 
 	//static
-	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
+	void ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
 	{
 		p.writeValue<LLSD::String>(sd.asString(), name_stack);
 	}
 
-	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
+	void ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
 	{
 		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
 		Parser::name_stack_t stack;
diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h
index f07e8fa746..b9b90fee71 100644
--- a/indra/llui/lluiimage.h
+++ b/indra/llui/lluiimage.h
@@ -92,7 +92,7 @@ protected:
 namespace LLInitParam
 {
 	template<>
-	class ParamValue<LLUIImage*, TypeValues<LLUIImage*> > 
+	class ParamValue<LLUIImage*, TypeValues<LLUIImage*>, NOT_BLOCK > 
 	:	public CustomParamValue<LLUIImage*>
 	{
 		typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type	T_const_ref;
@@ -100,7 +100,7 @@ namespace LLInitParam
 	public:
 		Optional<std::string> name;
 
-		ParamValue(LLUIImage* const& image)
+		ParamValue(LLUIImage* const& image = NULL)
 		:	super_t(image)
 		{
 			updateBlockFromValue(false);
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index db72aa19b9..3cf145cdde 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -112,6 +112,35 @@ namespace LLInitParam
 		std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
 	}
 
+	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name)
+	{
+		// create a copy of the param descriptor in mAllParams
+		// so other data structures can store a pointer to it
+		mAllParams.push_back(in_param);
+		ParamDescriptorPtr param(mAllParams.back());
+
+		std::string name(char_name);
+		if ((size_t)param->mParamHandle > mMaxParamOffset)
+		{
+			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
+		}
+
+		if (name.empty())
+		{
+			mUnnamedParams.push_back(param);
+		}
+		else
+		{
+			// don't use insert, since we want to overwrite existing entries
+			mNamedParams[name] = param;
+		}
+
+		if (param->mValidationFunc)
+		{
+			mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
+		}
+	}
+
 	BlockDescriptor::BlockDescriptor()
 	:	mMaxParamOffset(0),
 		mInitializationState(UNINITIALIZED),
@@ -358,36 +387,6 @@ namespace LLInitParam
 		return false;
 	}
 
-	//static 
-	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
-	{
-		// create a copy of the param descriptor in mAllParams
-		// so other data structures can store a pointer to it
-		block_data.mAllParams.push_back(in_param);
-		ParamDescriptorPtr param(block_data.mAllParams.back());
-
-		std::string name(char_name);
-		if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
-		{
-			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
-		}
-
-		if (name.empty())
-		{
-			block_data.mUnnamedParams.push_back(param);
-		}
-		else
-		{
-			// don't use insert, since we want to overwrite existing entries
-			block_data.mNamedParams[name] = param;
-		}
-
-		if (param->mValidationFunc)
-		{
-			block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
-		}
-	}
-
 	void BaseBlock::addSynonym(Param& param, const std::string& synonym)
 	{
 		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 1f0dec5d94..dbf2fdaa73 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -354,6 +354,7 @@ namespace LLInitParam
 		} EInitializationState;
 
 		void aggregateBlockData(BlockDescriptor& src_block_data);
+		void addParam(ParamDescriptorPtr param, const char* name);
 
 		typedef boost::unordered_map<const std::string, ParamDescriptorPtr>						param_map_t; 
 		typedef std::vector<ParamDescriptorPtr>													param_list_t; 
@@ -377,22 +378,23 @@ namespace LLInitParam
 	template<typename T, typename BLOCK_IDENTIFIER = void>
 	struct IsBlock
 	{
-		static const bool value = false;
 		typedef NOT_BLOCK value_t;
 	};
 
 	template<typename T>
 	struct IsBlock<T, typename T::baseblock_base_class_t>
 	{
-		static const bool value = true;
 		typedef IS_BLOCK value_t;
 	};
 
 	class BaseBlock
 	{
 	public:
+		typedef IS_BLOCK IS_BLOCK;
+		typedef NOT_BLOCK NOT_BLOCK;
+
 		//TODO: implement in terms of owned_ptr
-		template<typename T, bool IS_BLOCK = true>
+		template<typename T, typename BLOCK_T = IS_BLOCK>
 		class Lazy
 		{
 		public:
@@ -487,7 +489,6 @@ namespace LLInitParam
 			mutable T* mPtr;
 		};
 
-
 		// "Multiple" constraint types, put here in root class to avoid ambiguity during use
 		struct AnyAmount
 		{
@@ -572,8 +573,6 @@ namespace LLInitParam
 			return false;
 		}
 
-		static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name);
-
 		ParamDescriptorPtr findParamDescriptor(const Param& param);
 
 		// take all provided params from other and apply to self
@@ -638,7 +637,7 @@ namespace LLInitParam
 	};
 
 
-	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
+	template<typename T, typename NAME_VALUE_LOOKUP, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
 	class ParamValue : public NAME_VALUE_LOOKUP
 	{
 	public:
@@ -694,14 +693,14 @@ namespace LLInitParam
 	};
 
 	template<typename T, typename NAME_VALUE_LOOKUP>
-	class ParamValue<T, NAME_VALUE_LOOKUP, true> 
+	class ParamValue<T, NAME_VALUE_LOOKUP, IS_BLOCK> 
 	:	public T,
 		public NAME_VALUE_LOOKUP
 	{
 	public:
 		typedef const T&							value_assignment_t;
 		typedef T									value_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, true>	self_t;
+		typedef ParamValue<T, NAME_VALUE_LOOKUP, IS_BLOCK>	self_t;
 
 		ParamValue() 
 		:	T(),
@@ -758,13 +757,13 @@ namespace LLInitParam
 	};
 
 	template<typename NAME_VALUE_LOOKUP>
-	class ParamValue<std::string, NAME_VALUE_LOOKUP, false>
+	class ParamValue<std::string, NAME_VALUE_LOOKUP, NOT_BLOCK>
 	: public NAME_VALUE_LOOKUP
 	{
 	public:
 		typedef const std::string&	value_assignment_t;
 		typedef std::string			value_t;
-		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, false>	self_t;
+		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, NOT_BLOCK>	self_t;
 
 		ParamValue(): mValue() {}
 		ParamValue(value_assignment_t other) : mValue(other) {}
@@ -818,7 +817,7 @@ namespace LLInitParam
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
-			bool		VALUE_IS_BLOCK = IsBlock<T>::value>
+			typename	VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
 	class TypedParam 
 	:	public Param, 
 		public ParamValue<T, NAME_VALUE_LOOKUP>
@@ -836,15 +835,7 @@ namespace LLInitParam
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
- 				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
-												&mergeWith,
-												&deserializeParam,
-												&serializeParam,
-												validate_func,
-												&inspectParam,
-												min_count, max_count));
-				BaseBlock::addParam(block_descriptor, param_descriptor, name);
+				init(block_descriptor, validate_func, min_count, max_count, name);
 			}
 		} 
 
@@ -964,18 +955,31 @@ namespace LLInitParam
 			}
 			return false;
 		}
+	private:
+		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name ) 
+		{
+			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				&mergeWith,
+				&deserializeParam,
+				&serializeParam,
+				validate_func,
+				&inspectParam,
+				min_count, max_count));
+			block_descriptor.addParam(param_descriptor, name);
+		}
 	};
 
 	// parameter that is a block
 	template <typename T, typename NAME_VALUE_LOOKUP>
-	class TypedParam<T, NAME_VALUE_LOOKUP, false, true> 
+	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK> 
 	:	public Param,
 		public ParamValue<T, NAME_VALUE_LOOKUP>
 	{
 	public:
 		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;
 		typedef typename param_value_t::value_assignment_t		value_assignment_t;
-		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true>	self_t;
+		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK>	self_t;
 
 		using param_value_t::operator();
 
@@ -985,15 +989,7 @@ namespace LLInitParam
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
-												&mergeWith,
-												&deserializeParam,
-												&serializeParam,
-												validate_func, 
-												&inspectParam,
-												min_count, max_count));
-				BaseBlock::addParam(block_descriptor, param_descriptor, name);
+				init(block_descriptor, validate_func, min_count, max_count, name);
 			}
 		}
 
@@ -1130,15 +1126,29 @@ namespace LLInitParam
 			}
 			return false;
 		}
+
+	private:
+		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name ) 
+		{
+			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				&mergeWith,
+				&deserializeParam,
+				&serializeParam,
+				validate_func, 
+				&inspectParam,
+				min_count, max_count));
+			block_descriptor.addParam(param_descriptor, name);
+		}
 	};
 
 	// container of non-block parameters
 	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
-	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> 
+	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> 
 	:	public Param
 	{
 	public:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t;
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t;
 		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>					param_value_t;
 		typedef typename std::vector<param_value_t>							container_t;
 		typedef const container_t&											value_assignment_t;
@@ -1152,15 +1162,8 @@ namespace LLInitParam
 
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
-												&mergeWith,
-												&deserializeParam,
-												&serializeParam,
-												validate_func,
-												&inspectParam,
-												min_count, max_count));
-				BaseBlock::addParam(block_descriptor, param_descriptor, name);
+				init(block_descriptor, validate_func, min_count, max_count, name);
+
 			}
 		} 
 
@@ -1322,15 +1325,29 @@ namespace LLInitParam
 		}
 
 		container_t		mValues;
+
+	private:
+		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name ) 
+		{
+			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				&mergeWith,
+				&deserializeParam,
+				&serializeParam,
+				validate_func,
+				&inspectParam,
+				min_count, max_count));
+			block_descriptor.addParam(param_descriptor, name);
+		}
 	};
 
 	// container of block parameters
 	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
-	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> 
+	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_BLOCK> 
 	:	public Param
 	{
 	public:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>	self_t;
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_BLOCK>	self_t;
 		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>				param_value_t;
 		typedef typename std::vector<param_value_t>						container_t;
 		typedef const container_t&										value_assignment_t;
@@ -1343,15 +1360,7 @@ namespace LLInitParam
 
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
-												&mergeWith,
-												&deserializeParam,
-												&serializeParam,
-												validate_func,
-												&inspectParam,
-												min_count, max_count));
-				BaseBlock::addParam(block_descriptor, param_descriptor, name);
+				init(block_descriptor, validate_func, min_count, max_count, name);
 			}
 		} 
 
@@ -1516,6 +1525,20 @@ namespace LLInitParam
 		}
 
 		container_t			mValues;
+
+	private:
+		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name ) 
+		{
+			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				&mergeWith,
+				&deserializeParam,
+				&serializeParam,
+				validate_func,
+				&inspectParam,
+				min_count, max_count));
+			block_descriptor.addParam(param_descriptor, name);
+		}
 	};
 
 	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
@@ -1595,7 +1618,7 @@ namespace LLInitParam
 			friend class ChoiceBlock<DERIVED_BLOCK>;
 
 			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t;
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<T>::value>		super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, typename IsBlock<T>::value_t>		super_t;
 			typedef typename super_t::value_assignment_t								value_assignment_t;
 
 			using super_t::operator =;
@@ -1713,8 +1736,8 @@ namespace LLInitParam
 		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<T>::value>		super_t;
-			typedef typename super_t::value_assignment_t								value_assignment_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, typename IsBlock<T>::value_t>	super_t;
+			typedef typename super_t::value_assignment_t									value_assignment_t;
 
 			using super_t::operator();
 			using super_t::operator =;
@@ -1742,7 +1765,7 @@ namespace LLInitParam
 		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<T>::value>		super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, typename IsBlock<T>::value_t>		super_t;
 			typedef Mandatory<T, NAME_VALUE_LOOKUP>										self_t;
 			typedef typename super_t::value_assignment_t								value_assignment_t;
 
@@ -1778,7 +1801,7 @@ namespace LLInitParam
 		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<T>::value>	super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, typename IsBlock<T>::value_t>	super_t;
 			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>							self_t;
 			typedef typename super_t::container_t									container_t;
 			typedef typename super_t::value_assignment_t							value_assignment_t;
@@ -1825,7 +1848,7 @@ namespace LLInitParam
 													NULL,
 													NULL, 
 													0, S32_MAX));
-					BaseBlock::addParam(block_descriptor, param_descriptor, name);
+					block_descriptor.addParam(param_descriptor, name);
 				}
 			}
 			
@@ -1853,7 +1876,7 @@ namespace LLInitParam
 		}
 
 	protected:
-		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
+		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, typename is_block>
 		void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param, 
 			typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
 		{
@@ -1911,7 +1934,7 @@ namespace LLInitParam
 			typename NAME_VALUE_LOOKUP>
 	class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
 					NAME_VALUE_LOOKUP,
-					true>
+					IS_BLOCK>
 	:	public NAME_VALUE_LOOKUP,
 		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
 	{
@@ -1961,25 +1984,31 @@ namespace LLInitParam
 	};
 
 	template<typename T, typename BLOCK_IDENTIFIER>
-	struct IsBlock<BaseBlock::Lazy<T, true>, BLOCK_IDENTIFIER>
+	struct IsBlock<BaseBlock::Lazy<T, IS_BLOCK>, BLOCK_IDENTIFIER>
 	{
-		static const bool value = true;
+		typedef IS_BLOCK value_t;
 	};
 
 	template<typename T, typename BLOCK_IDENTIFIER>
-	struct IsBlock<BaseBlock::Lazy<T, false>, BLOCK_IDENTIFIER>
+	struct IsBlock<BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_IDENTIFIER>
 	{
-		static const bool value = false;
+		typedef NOT_BLOCK value_t;
 	};
 
+	//template<typename T, typename BLOCK_IDENTIFIER>
+	//struct IsBlock<BaseBlock::Lazy<T, void>, BLOCK_IDENTIFIER>
+	//{
+	//	typedef typename IsBlock<T>::value_t value_t;
+	//};
+
 	template<typename T>
-	class ParamValue <BaseBlock::Lazy<T, true>,
-					TypeValues<BaseBlock::Lazy<T, true> >,
-					true>
+	class ParamValue <BaseBlock::Lazy<T, IS_BLOCK>,
+					TypeValues<BaseBlock::Lazy<T, IS_BLOCK> >,
+					IS_BLOCK>
 	:	public TypeValues<T>
 	{
 	public:
-		typedef ParamValue <BaseBlock::Lazy<T, true>, TypeValues<BaseBlock::Lazy<T, true> >, true> self_t;
+		typedef ParamValue <BaseBlock::Lazy<T, IS_BLOCK>, TypeValues<BaseBlock::Lazy<T, IS_BLOCK> >, IS_BLOCK> self_t;
 		typedef const T& value_assignment_t;
 		typedef T value_t;
 	
@@ -1988,7 +2017,7 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		ParamValue(const BaseBlock::Lazy<T, true>& other)
+		ParamValue(const BaseBlock::Lazy<T, IS_BLOCK>& other)
 		:	mValue(other),
 			mValidated(false)
 		{}
@@ -2062,18 +2091,18 @@ namespace LLInitParam
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
-		BaseBlock::Lazy<T, true>	mValue;
+		BaseBlock::Lazy<T, IS_BLOCK>	mValue;
 	};
 
 	template <>
 	class ParamValue <LLSD,
 					TypeValues<LLSD>,
-					false>
+					NOT_BLOCK>
 	:	public TypeValues<LLSD>,
 		public BaseBlock
 	{
 	public:
-		typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t;
+		typedef ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK> self_t;
 		typedef const LLSD&	value_assignment_t;
 
 		ParamValue()
-- 
cgit v1.2.3


From 5ed0819309dcb9352de51795a0e9338fd7de844a Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Tue, 10 Apr 2012 18:03:55 +0300
Subject: CHUI-77 WIP Made per-tab filters work.

---
 indra/newview/llpanelpeople.cpp                    | 77 ++++++++++++++--------
 indra/newview/llpanelpeople.h                      |  7 +-
 .../newview/skins/default/xui/en/panel_people.xml  |  2 +-
 3 files changed, 52 insertions(+), 34 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 2d665e9bf3..aceee7cf23 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -492,9 +492,6 @@ public:
 
 LLPanelPeople::LLPanelPeople()
 	:	LLPanel(),
-		mFilterSubString(LLStringUtil::null),
-		mFilterSubStringOrig(LLStringUtil::null),
-		mFilterEditor(NULL),
 		mTabContainer(NULL),
 		mOnlineFriendList(NULL),
 		mAllFriendList(NULL),
@@ -567,11 +564,15 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LL
 
 BOOL LLPanelPeople::postBuild()
 {
-	mFilterEditor = getChild<LLFilterEditor>("filter_input");
-	mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+	getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+	getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+	getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+	getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
 
 	mTabContainer = getChild<LLTabContainer>("tabs");
 	mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
+	mSavedFilters.resize(mTabContainer->getTabCount());
+	mSavedOriginalFilters.resize(mTabContainer->getTabCount());
 
 	LLPanel* friends_tab = getChild<LLPanel>(FRIENDS_TAB_NAME);
 	// updater is active only if panel is visible to user.
@@ -680,9 +681,11 @@ void LLPanelPeople::updateFriendListHelpText()
 	if (no_friends_text->getVisible())
 	{
 		//update help text for empty lists
-		std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
+		const std::string& filter = mSavedOriginalFilters[mTabContainer->getCurrentPanelIndex()];
+
+		std::string message_name = filter.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
 		LLStringUtil::format_map_t args;
-		args["[SEARCH_TERM]"] = LLURI::escape(mFilterSubStringOrig);
+		args["[SEARCH_TERM]"] = LLURI::escape(filter);
 		no_friends_text->setText(getString(message_name, args));
 	}
 }
@@ -973,40 +976,56 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save
 
 void LLPanelPeople::onFilterEdit(const std::string& search_string)
 {
-	mFilterSubStringOrig = search_string;
-	LLStringUtil::trimHead(mFilterSubStringOrig);
+	const S32 cur_tab_idx = mTabContainer->getCurrentPanelIndex();
+	std::string& filter = mSavedOriginalFilters[cur_tab_idx];
+	std::string& saved_filter = mSavedFilters[cur_tab_idx];
+
+	filter = search_string;
+	LLStringUtil::trimHead(filter);
+
 	// Searches are case-insensitive
-	std::string search_upper = mFilterSubStringOrig;
+	std::string search_upper = filter;
 	LLStringUtil::toUpper(search_upper);
 
-	if (mFilterSubString == search_upper)
+	if (saved_filter == search_upper)
 		return;
 
-	mFilterSubString = search_upper;
+	saved_filter = search_upper;
 
-	//store accordion tabs state before any manipulation with accordion tabs
-	if(!mFilterSubString.empty())
+	// Apply new filter to the current tab.
+	const std::string cur_tab = getActiveTabName();
+	if (cur_tab == NEARBY_TAB_NAME)
 	{
-		notifyChildren(LLSD().with("action","store_state"));
+		mNearbyList->setNameFilter(filter);
 	}
+	else if (cur_tab == FRIENDS_TAB_NAME)
+	{
+		// store accordion tabs opened/closed state before any manipulation with accordion tabs
+		if (!saved_filter.empty())
+		{
+			notifyChildren(LLSD().with("action","store_state"));
+		}
 
+		mOnlineFriendList->setNameFilter(filter);
+		mAllFriendList->setNameFilter(filter);
 
-	// Apply new filter.
-	mNearbyList->setNameFilter(mFilterSubStringOrig);
-	mOnlineFriendList->setNameFilter(mFilterSubStringOrig);
-	mAllFriendList->setNameFilter(mFilterSubStringOrig);
-	mRecentList->setNameFilter(mFilterSubStringOrig);
-	mGroupList->setNameFilter(mFilterSubStringOrig);
-
-	setAccordionCollapsedByUser("tab_online", false);
-	setAccordionCollapsedByUser("tab_all", false);
+		setAccordionCollapsedByUser("tab_online", false);
+		setAccordionCollapsedByUser("tab_all", false);
+		showFriendsAccordionsIfNeeded();
 
-	showFriendsAccordionsIfNeeded();
-
-	//restore accordion tabs state _after_ all manipulations...
-	if(mFilterSubString.empty())
+		// restore accordion tabs state _after_ all manipulations
+		if(saved_filter.empty())
+		{
+			notifyChildren(LLSD().with("action","restore_state"));
+		}
+	}
+	else if (cur_tab == GROUP_TAB_NAME)
+	{
+		mGroupList->setNameFilter(filter);
+	}
+	else if (cur_tab == RECENT_TAB_NAME)
 	{
-		notifyChildren(LLSD().with("action","restore_state"));
+		mRecentList->setNameFilter(filter);
 	}
 }
 
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 684dcdeb6d..765e62ffa6 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -132,7 +132,6 @@ private:
 	bool					isAccordionCollapsedByUser(LLUICtrl* acc_tab);
 	bool					isAccordionCollapsedByUser(const std::string& name);
 
-	LLFilterEditor*			mFilterEditor;
 	LLTabContainer*			mTabContainer;
 	LLAvatarList*			mOnlineFriendList;
 	LLAvatarList*			mAllFriendList;
@@ -141,13 +140,13 @@ private:
 	LLGroupList*			mGroupList;
 	LLNetMap*				mMiniMap;
 
+	std::vector<std::string> mSavedOriginalFilters;
+	std::vector<std::string> mSavedFilters;
+
 	Updater*				mFriendListUpdater;
 	Updater*				mNearbyListUpdater;
 	Updater*				mRecentListUpdater;
 	Updater*				mButtonsUpdater;
-
-	std::string				mFilterSubString;
-	std::string				mFilterSubStringOrig;
 };
 
 #endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 5da87456f1..ad4a840106 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -365,7 +365,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              height="450"
              left="13"
              name="no_friends_help_text"
-             top="10"
+             top="37"
              width="293"
              wrap="true" />
         </panel>
-- 
cgit v1.2.3


From 60510292b08d69eb7053621ce6b3ac60d599a4fb Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 11 Apr 2012 13:04:02 -0700
Subject: CHUI-89 FIX Make nametags appear consistently next to avatar heads

---
 indra/newview/llhudnametag.cpp       | 279 ++++++------------
 indra/newview/llhudnametag.h         |   2 -
 indra/newview/llspatialpartition.cpp |   4 +-
 indra/newview/llviewermenu.cpp       |   9 -
 indra/newview/llvoavatar.cpp         | 546 +++++++++++++++--------------------
 indra/newview/llvoavatar.h           |  15 +-
 indra/newview/pipeline.cpp           |   5 -
 7 files changed, 331 insertions(+), 529 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 482294c8a6..cf55954d7d 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -187,45 +187,42 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
 
-	//if (mUseBubble)
-	{
-		LLVector3 bg_pos = render_position
-			+ (F32)mOffsetY * y_pixel_vec
-			- (width_vec / 2.f)
-			- (height_vec);
-		//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+	LLVector3 bg_pos = render_position
+		+ (F32)mOffsetY * y_pixel_vec
+		- (width_vec / 2.f)
+		- (height_vec);
+	//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
 
-		LLVector3 v[] = 
-		{
-			bg_pos,
-			bg_pos + width_vec,
-			bg_pos + width_vec + height_vec,
-			bg_pos + height_vec,
-		};
+	LLVector3 v[] = 
+	{
+		bg_pos,
+		bg_pos + width_vec,
+		bg_pos + width_vec + height_vec,
+		bg_pos + height_vec,
+	};
 
-		if (debug_render)
-		{
-			gGL.begin(LLRender::LINE_STRIP);
-			gGL.vertex3fv(v[0].mV);
-			gGL.vertex3fv(v[1].mV);
-			gGL.vertex3fv(v[2].mV);
-			gGL.vertex3fv(v[3].mV);
-			gGL.vertex3fv(v[0].mV);
-			gGL.vertex3fv(v[2].mV);
-			gGL.end();
-		}
+	if (debug_render)
+	{
+		gGL.begin(LLRender::LINE_STRIP);
+		gGL.vertex3fv(v[0].mV);
+		gGL.vertex3fv(v[1].mV);
+		gGL.vertex3fv(v[2].mV);
+		gGL.vertex3fv(v[3].mV);
+		gGL.vertex3fv(v[0].mV);
+		gGL.vertex3fv(v[2].mV);
+		gGL.end();
+	}
 
-		LLVector3 dir = end-start;
-		F32 a, b, t;
+	LLVector3 dir = end-start;
+	F32 a, b, t;
 
-		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
-			LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+	if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
+		LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+	{
+		if (t <= 1.f)
 		{
-			if (t <= 1.f)
-			{
-				intersection = start + dir*t;
-				return TRUE;
-			}
+			intersection = start + dir*t;
+			return TRUE;
 		}
 	}
 
@@ -241,12 +238,6 @@ void LLHUDNameTag::render()
 	}
 }
 
-void LLHUDNameTag::renderForSelect()
-{
-	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-	renderText(TRUE);
-}
-
 void LLHUDNameTag::renderText(BOOL for_select)
 {
 	if (!mVisible || mHidden)
@@ -336,142 +327,53 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	LLCoordGL screen_pos;
 	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
 
-	LLVector2 screen_offset;
-//	if (!mUseBubble)
-//	{
-//		screen_offset = mPositionOffset;
-//	}
-//	else
-//	{
-		screen_offset = updateScreenPos(mPositionOffset);
-//	}
+	LLVector2 screen_offset = updateScreenPos(mPositionOffset);
 
 	LLVector3 render_position = mPositionAgent  
 			+ (x_pixel_vec * screen_offset.mV[VX])
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
-//	if (mUseBubble)
+	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+	LLUI::pushMatrix();
 	{
-		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-		LLUI::pushMatrix();
-		{
-			LLVector3 bg_pos = render_position
-				+ (F32)mOffsetY * y_pixel_vec
-				- (width_vec / 2.f)
-				- (height_vec);
-			LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+		LLVector3 bg_pos = render_position
+			+ (F32)mOffsetY * y_pixel_vec
+			- (width_vec / 2.f)
+			- (height_vec);
+		LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
 
-			if (for_select)
-			{
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				S32 name = mSourceObject->mGLName;
-				LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
-				gGL.color4ubv(coloru.mV);
-				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-				LLUI::popMatrix();
-				return;
-			}
-			else
-			{
-				gGL.getTexUnit(0)->bind(imagep->getImage());
+		if (for_select)
+		{
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+			S32 name = mSourceObject->mGLName;
+			LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
+			gGL.color4ubv(coloru.mV);
+			gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
+			LLUI::popMatrix();
+			return;
+		}
+		else
+		{
+			gGL.getTexUnit(0)->bind(imagep->getImage());
 				
-				gGL.color4fv(bg_color.mV);
-				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
+			gGL.color4fv(bg_color.mV);
+			gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
 		
-				if ( mLabelSegments.size())
-				{
-					LLUI::pushMatrix();
-					{
-						gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
-						LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
-						LLVector3 label_offset = height_vec - label_height;
-						LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
-						gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
-					}
-					LLUI::popMatrix();
-				}
-			}
-
-			BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f;
-			BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f);
-
-			// draw line segments pointing to parent object
-			if (!mOffscreen && (outside_width || outside_height))
+			if ( mLabelSegments.size())
 			{
 				LLUI::pushMatrix();
 				{
-					gGL.color4fv(bg_color.mV);
-					LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec);
-					target_pos += (width_vec / 2.f);
-					target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero;
-					target_pos -= 3.f * x_pixel_vec;
-					target_pos -= 6.f * y_pixel_vec;
-					LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]);
-					gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);	
+					gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
+					LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
+					LLVector3 label_offset = height_vec - label_height;
+					LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
+					gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
 				}
 				LLUI::popMatrix();
-
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
-				
-				LLVector3 box_center_offset;
-				box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f);
-				LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
-				gGL.color4fv(bg_color.mV);
-				LLUI::setLineWidth(2.0);
-				gGL.begin(LLRender::LINES);
-				{
-					if (outside_width)
-					{
-						LLVector3 vert;
-						// draw line in x then y
-						if (mPositionOffset.mV[VX] < 0.f)
-						{
-							// start at right edge
-							vert = width_vec * 0.5f;
-							gGL.vertex3fv(vert.mV);
-						}
-						else
-						{
-							// start at left edge
-							vert = width_vec * -0.5f;
-							gGL.vertex3fv(vert.mV);
-						}
-						vert = -mPositionOffset.mV[VX] * x_pixel_vec;
-						gGL.vertex3fv(vert.mV);
-						gGL.vertex3fv(vert.mV);
-						vert -= mPositionOffset.mV[VY] * y_pixel_vec;
-						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
-						gGL.vertex3fv(vert.mV);
-					}
-					else
-					{
-						LLVector3 vert;
-						// draw line in y then x
-						if (mPositionOffset.mV[VY] < 0.f)
-						{
-							// start at top edge
-							vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
-							gGL.vertex3fv(vert.mV);
-						}
-						else
-						{
-							// start at bottom edge
-							vert = (height_vec * -0.5f)  - (mPositionOffset.mV[VX] * x_pixel_vec);
-							gGL.vertex3fv(vert.mV);
-						}
-						vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec;
-						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
-						gGL.vertex3fv(vert.mV);
-					}
-				}
-				gGL.end();
-				LLUI::setLineWidth(1.0);
-
 			}
 		}
-		LLUI::popMatrix();
 	}
+	LLUI::popMatrix();
 
 	F32 y_offset = (F32)mOffsetY;
 		
@@ -874,29 +776,26 @@ void LLHUDNameTag::updateAll()
 	for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it)
 	{
 		LLHUDNameTag* textp = (*r_it);
-//		if (textp->mUseBubble)
-//		{
-			if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
-			{
-				textp->setLOD(3);
-			}
-			else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
-			{
-				textp->setLOD(2);
-			}
-			else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
-			{
-				textp->setLOD(1);
-			}
-			else
-			{
-				textp->setLOD(0);
-			}
-			textp->updateSize();
-			// find on-screen position and initialize collision rectangle
-			textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
-			current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
-//		}
+		if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
+		{
+			textp->setLOD(3);
+		}
+		else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
+		{
+			textp->setLOD(2);
+		}
+		else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
+		{
+			textp->setLOD(1);
+		}
+		else
+		{
+			textp->setLOD(0);
+		}
+		textp->updateSize();
+		// find on-screen position and initialize collision rectangle
+		textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
+		current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
 	}
 
 	LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat();
@@ -914,20 +813,12 @@ void LLHUDNameTag::updateAll()
 		{
 			LLHUDNameTag* src_textp = (*src_it);
 
-//			if (!src_textp->mUseBubble)
-//			{
-//				continue;
-//			}
 			VisibleTextObjectIterator dst_it = src_it;
 			++dst_it;
 			for (; dst_it != sVisibleTextObjects.end(); ++dst_it)
 			{
 				LLHUDNameTag* dst_textp = (*dst_it);
 
-//				if (!dst_textp->mUseBubble)
-//				{
-//					continue;
-//				}
 				if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect))
 				{
 					LLRectf intersect_rect = src_textp->mSoftScreenRect;
@@ -976,10 +867,6 @@ void LLHUDNameTag::updateAll()
 	VisibleTextObjectIterator this_object_it;
 	for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)
 	{
-//		if (!(*this_object_it)->mUseBubble)
-//		{
-//			continue;
-//		}
 		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC));
 	}
 }
@@ -1037,10 +924,6 @@ void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list)
 	VisibleTextObjectIterator text_it;
 	for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it)
 	{
-//		if (!(*text_it)->mUseBubble)
-//		{
-//			continue;
-//		}
 		pick_list.insert((*text_it)->mSourceObject);
 	}
 }
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 3325c22def..72647d5b26 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -118,7 +118,6 @@ public:
 	/*virtual*/ void markDead();
 	friend class LLHUDObject;
 	/*virtual*/ F32 getDistance() const { return mLastDistance; }
-	//void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; }
 	S32  getLOD() { return mLOD; }
 	BOOL getVisible() { return mVisible; }
 	BOOL getHidden() const { return mHidden; }
@@ -136,7 +135,6 @@ protected:
 	LLHUDNameTag(const U8 type);
 
 	/*virtual*/ void render();
-	/*virtual*/ void renderForSelect();
 	void renderText(BOOL for_select);
 	static void updateAll();
 	void setLOD(S32 lod);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5d196a465f..1333862855 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2774,7 +2774,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 
 void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)
 {
-	gGL.diffuseColor4fv(color.mV);
+	gGL.color4fv(color.mV);
 	gGL.begin(LLRender::LINES);
 	{
 		gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
@@ -3904,7 +3904,7 @@ void renderAgentTarget(LLVOAvatar* avatar)
 	if (avatar->isSelf())
 	{
 		renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
-		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
+		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
 		renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
 		renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
 	}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 99540ccce9..ae32683c99 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3190,15 +3190,6 @@ bool enable_freeze_eject(const LLSD& avatar_id)
 	return new_value;
 }
 
-
-void login_done(S32 which, void *user)
-{
-	llinfos << "Login done " << which << llendl;
-
-	LLPanelLogin::closePanel();
-}
-
-
 bool callback_leave_group(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bc7f5a9744..ef59e366e8 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -62,6 +62,7 @@
 #include "llhudmanager.h"
 #include "llhudnametag.h"
 #include "llhudtext.h"				// for mText/mDebugText
+#include "llinitparam.h"
 #include "llkeyframefallmotion.h"
 #include "llkeyframestandmotion.h"
 #include "llkeyframewalkmotion.h"
@@ -193,6 +194,9 @@ const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN;
 const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;
 const F32 CHAT_FADE_TIME = 8.0;
 const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
+const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;
+const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
+const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.15f;
 
 const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
 
@@ -234,11 +238,11 @@ class LLVOAvatarBoneInfo
 public:
 	LLVOAvatarBoneInfo() : mIsJoint(FALSE) {}
 	~LLVOAvatarBoneInfo()
-	{
+{
 		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
 	}
 	BOOL parseXml(LLXmlTreeNode* node);
-	
+
 private:
 	std::string mName;
 	BOOL mIsJoint;
@@ -1656,7 +1660,7 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
 	// parse the file
 	//-------------------------------------------------------------------------
 	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
-
+	
 	if (!parsesuccess)
 	{
 		llerrs << "Can't parse skeleton file: " << filename << llendl;
@@ -1790,10 +1794,10 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
 	{
 		LLVOAvatarBoneInfo *info = *iter;
 		if (!setupBone(info, NULL, current_volume_num, current_joint_num))
-		{
-			llerrs << "Error parsing bone in skeleton file" << llendl;
-			return FALSE;
-		}
+	{
+		llerrs << "Error parsing bone in skeleton file" << llendl;
+		return FALSE;
+	}
 	}
 
 	return TRUE;
@@ -2922,43 +2926,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-		BOOL new_name = FALSE;
-		if (visible_chat != mVisibleChat)
-		{
-			mVisibleChat = visible_chat;
-			new_name = TRUE;
-		}
+	BOOL new_name = FALSE;
+	if (visible_chat != mVisibleChat)
+	{
+		mVisibleChat = visible_chat;
+		new_name = TRUE;
+	}
 		
-		if (sRenderGroupTitles != mRenderGroupTitles)
-		{
-			mRenderGroupTitles = sRenderGroupTitles;
-			new_name = TRUE;
-		}
+	if (sRenderGroupTitles != mRenderGroupTitles)
+	{
+		mRenderGroupTitles = sRenderGroupTitles;
+		new_name = TRUE;
+	}
 
-		// First Calculate Alpha
-		// If alpha > 0, create mNameText if necessary, otherwise delete it
-			F32 alpha = 0.f;
-			if (mAppAngle > 5.f)
+	// First Calculate Alpha
+	// If alpha > 0, create mNameText if necessary, otherwise delete it
+		F32 alpha = 0.f;
+		if (mAppAngle > 5.f)
+		{
+			const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
+			if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
 			{
-				const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
-				if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
-				{
-					alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
-				}
-				else
-				{
-					// ...not fading, full alpha
-					alpha = 1.f;
-				}
+				alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
 			}
-			else if (mAppAngle > 2.f)
+			else
 			{
-				// far away is faded out also
-				alpha = (mAppAngle-2.f)/3.f;
+				// ...not fading, full alpha
+				alpha = 1.f;
 			}
+		}
+		else if (mAppAngle > 2.f)
+		{
+			// far away is faded out also
+			alpha = (mAppAngle-2.f)/3.f;
+		}
 
 	if (alpha <= 0.f)
-			{
+	{
 		if (mNameText)
 		{
 			mNameText->markDead();
@@ -2968,31 +2972,30 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-				if (!mNameText)
-				{
+	if (!mNameText)
+	{
 		mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
 			LLHUDObject::LL_HUD_NAME_TAG) );
 		//mNameText->setMass(10.f);
-					mNameText->setSourceObject(this);
+		mNameText->setSourceObject(this);
 		mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
-					mNameText->setVisibleOffScreen(TRUE);
-					mNameText->setMaxLines(11);
-					mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
-					sNumVisibleChatBubbles++;
-					new_name = TRUE;
-				}
+		mNameText->setVisibleOffScreen(TRUE);
+		mNameText->setMaxLines(11);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+		sNumVisibleChatBubbles++;
+		new_name = TRUE;
+	}
 				
-	LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
-	mNameText->setPositionAgent(name_position);				
+	idleUpdateNameTagPosition(root_pos_last);
 	idleUpdateNameTagText(new_name);			
 	idleUpdateNameTagAlpha(new_name, alpha);
 }
 
 void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
-			{
-		LLNameValue *title = getNVPair("Title");
-		LLNameValue* firstname = getNVPair("FirstName");
-		LLNameValue* lastname = getNVPair("LastName");
+{
+	LLNameValue *title = getNVPair("Title");
+	LLNameValue* firstname = getNVPair("FirstName");
+	LLNameValue* lastname = getNVPair("LastName");
 
 	// Avatars must have a first and last name
 	if (!firstname || !lastname) return;
@@ -3006,34 +3009,29 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		is_muted = false;
 	}
 	else
-		{
+	{
 		is_muted = LLMuteList::getInstance()->isMuted(getID());
 	}
 	bool is_friend = LLAvatarTracker::instance().isBuddy(getID());
 	bool is_cloud = getIsCloud();
 
-			if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
-			{
-				if (is_appearance != mNameAppearance)
-				{
-					if (is_appearance)
-					{
-						LLSD args;
-						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
-						args["NAME"] = getFullname();
-						LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
-						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
-					}
-					else
-					{
-						LLSD args;
-						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
-						args["NAME"] = getFullname();
-						LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
-						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
-					}
-				}
-			}
+	if (gSavedSettings.getBOOL("DebugAvatarRezTime")
+		&& is_appearance != mNameAppearance)
+	{
+		LLSD args;
+		args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
+		args["NAME"] = getFullname();
+		if (is_appearance)
+		{
+			LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
+			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
+		}
+		else
+		{
+			LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
+			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
+		}
+	}
 
 	// Rebuild name tag if state change detected
 	if (mNameString.empty()
@@ -3043,39 +3041,39 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		|| is_away != mNameAway 
 		|| is_busy != mNameBusy 
 		|| is_muted != mNameMute
-				|| is_appearance != mNameAppearance 
+		|| is_appearance != mNameAppearance 
 		|| is_friend != mNameFriend
 		|| is_cloud != mNameCloud)
-				{
+	{
 		LLColor4 name_tag_color = getNameTagColor(is_friend);
 
 		clearNameTag();
 
 		if (is_away || is_muted || is_busy || is_appearance)
-				{
+		{
 			std::string line;
-					if (is_away)
-					{
-						line += LLTrans::getString("AvatarAway");
+			if (is_away)
+			{
+				line += LLTrans::getString("AvatarAway");
 				line += ", ";
-					}
-					if (is_busy)
-					{
+			}
+			if (is_busy)
+			{
 				line += LLTrans::getString("AvatarBusy");
 				line += ", ";
 			}
 			if (is_muted)
-						{
+			{
 				line += LLTrans::getString("AvatarMuted");
-							line += ", ";
-						}
+				line += ", ";
+			}
 			if (is_appearance)
 			{
 				line += LLTrans::getString("AvatarEditingAppearance");
 				line += ", ";
-					}
+			}
 			if (is_cloud)
-					{
+			{
 				line += LLTrans::getString("LoadingData");
 				line += ", ";
 			}
@@ -3087,12 +3085,12 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 
 		if (sRenderGroupTitles
 			&& title && title->getString() && title->getString()[0] != '\0')
-						{
+		{
 			std::string title_str = title->getString();
 			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
 			addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
 				LLFontGL::getFontSansSerifSmall());
-						}
+		}
 
 		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
 		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
@@ -3106,119 +3104,118 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 				// and force a rebuild
 				LLAvatarNameCache::get(getID(),
 					boost::bind(&LLVOAvatar::clearNameTag, this));
-					}
+			}
 
 			// Might be blank if name not available yet, that's OK
 			if (show_display_names)
 			{
 				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
 					LLFontGL::getFontSansSerif());
-				}
+			}
 			// Suppress SLID display if display name matches exactly (ugh)
 			if (show_usernames && !av_name.mIsDisplayNameDefault)
-				{
+			{
 				// *HACK: Desaturate the color
 				LLColor4 username_color = name_tag_color * 0.83f;
 				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
 					LLFontGL::getFontSansSerifSmall());
 			}
-				}
+		}
 		else
-				{
+		{
 			const LLFontGL* font = LLFontGL::getFontSansSerif();
-			std::string full_name =
-				LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+			std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
 			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
-				}
+		}
 
-				mNameAway = is_away;
-				mNameBusy = is_busy;
-				mNameMute = is_muted;
-				mNameAppearance = is_appearance;
-		mNameFriend = is_friend;
-				mNameCloud = is_cloud;
-				mTitle = title ? title->getString() : "";
-				LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
-				new_name = TRUE;
-			}
+		mNameAway 		= is_away;
+		mNameBusy 		= is_busy;
+		mNameMute 		= is_muted;
+		mNameAppearance = is_appearance;
+		mNameFriend 	= is_friend;
+		mNameCloud 		= is_cloud;
+		mTitle 			= title ? title->getString() : "";
+		LLStringFn::replace_ascii_controlchars(mTitle, LL_UNKNOWN_CHAR);
+		new_name = TRUE;
+	}
 
 	if (mVisibleChat)
-			{
-				mNameText->setFont(LLFontGL::getFontSansSerif());
+	{
+		mNameText->setFont(LLFontGL::getFontSansSerif());
 		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
-				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
-			
-				char line[MAX_STRING];		/* Flawfinder: ignore */
-				line[0] = '\0';
-				std::deque<LLChat>::iterator chat_iter = mChats.begin();
-				mNameText->clearString();
-
-				LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
-				LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
-				LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
-				if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
-				{
-					++chat_iter;
-				}
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
 
-				for(; chat_iter != mChats.end(); ++chat_iter)
-				{
-					F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
-					LLFontGL::StyleFlags style;
-					switch(chat_iter->mChatType)
-					{
-						case CHAT_TYPE_WHISPER:
-							style = LLFontGL::ITALIC;
-							break;
-						case CHAT_TYPE_SHOUT:
-							style = LLFontGL::BOLD;
-							break;
-						default:
-							style = LLFontGL::NORMAL;
-							break;
-					}
-					if (chat_fade_amt < 1.f)
-					{
-						F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
-						mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
-					}
-					else if (chat_fade_amt < 2.f)
-					{
-						F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
-						mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
-					}
-					else if (chat_fade_amt < 3.f)
-					{
-						// *NOTE: only remove lines down to minimum number
-						mNameText->addLine(chat_iter->mText, old_chat, style);
-					}
-				}
-				mNameText->setVisibleOffScreen(TRUE);
+		char line[MAX_STRING];		/* Flawfinder: ignore */
+		line[0] = '\0';
+		std::deque<LLChat>::iterator chat_iter = mChats.begin();
+		mNameText->clearString();
 
-				if (mTyping)
-				{
-					S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
-					switch(dot_count)
-					{
-						case 1:
-							mNameText->addLine(".", new_chat);
-							break;
-						case 2:
-							mNameText->addLine("..", new_chat);
-							break;
-						case 3:
-							mNameText->addLine("...", new_chat);
-							break;
-					}
+		LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
+		LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
+		LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
+		if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
+		{
+			++chat_iter;
+		}
 
-				}
+		for(; chat_iter != mChats.end(); ++chat_iter)
+		{
+			F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
+			LLFontGL::StyleFlags style;
+			switch(chat_iter->mChatType)
+			{
+			case CHAT_TYPE_WHISPER:
+				style = LLFontGL::ITALIC;
+				break;
+			case CHAT_TYPE_SHOUT:
+				style = LLFontGL::BOLD;
+				break;
+			default:
+				style = LLFontGL::NORMAL;
+				break;
 			}
-			else
+			if (chat_fade_amt < 1.f)
+			{
+				F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
+				mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
+			}
+			else if (chat_fade_amt < 2.f)
 			{
+				F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
+				mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
+			}
+			else if (chat_fade_amt < 3.f)
+			{
+				// *NOTE: only remove lines down to minimum number
+				mNameText->addLine(chat_iter->mText, old_chat, style);
+			}
+		}
+		mNameText->setVisibleOffScreen(TRUE);
+
+		if (mTyping)
+		{
+			S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
+			switch(dot_count)
+			{
+			case 1:
+				mNameText->addLine(".", new_chat);
+				break;
+			case 2:
+				mNameText->addLine("..", new_chat);
+				break;
+			case 3:
+				mNameText->addLine("...", new_chat);
+				break;
+			}
+
+		}
+	}
+	else
+	{
 		// ...not using chat bubbles, just names
 		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
-				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
-				mNameText->setVisibleOffScreen(FALSE);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+		mNameText->setVisibleOffScreen(FALSE);
 	}
 }
 
@@ -3241,8 +3238,8 @@ void LLVOAvatar::clearNameTag()
 {
 	mNameString.clear();
 	if (mNameText)
-				{
-					mNameText->setLabel("");
+	{
+		mNameText->setLabel("");
 		mNameText->setString( "" );
 	}
 }
@@ -3270,34 +3267,45 @@ void LLVOAvatar::invalidateNameTags()
 		if (avatar->isDead()) continue;
 
 		avatar->clearNameTag();
-
 	}
 }
 
 // Compute name tag position during idle update
-LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
+void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 {
 	LLQuaternion root_rot = mRoot.getWorldRotation();
+	LLQuaternion inv_root_rot = ~root_rot;
 	LLVector3 pixel_right_vec;
 	LLVector3 pixel_up_vec;
 	LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
 	LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
 	camera_to_av.normalize();
-	LLVector3 local_camera_at = camera_to_av * ~root_rot;
+	LLVector3 local_camera_at = camera_to_av * inv_root_rot;
 	LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
 	local_camera_up.normalize();
-	local_camera_up = local_camera_up * ~root_rot;
+	local_camera_up = local_camera_up * inv_root_rot;
+
+	LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f,
+								mBodySize.mV[VY] * 0.4f,
+								mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT);
+
+	local_camera_up.scaleVec(avatar_ellipsoid);
+	local_camera_at.scaleVec(avatar_ellipsoid);
 
-	local_camera_up.scaleVec(mBodySize * 0.5f);
-	local_camera_at.scaleVec(mBodySize * 0.5f);
+	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot.getLastWorldPosition()) * inv_root_rot;
 
-	LLVector3 name_position = mRoot.getWorldPosition();
-	name_position[VZ] -= mPelvisToFoot;
-	name_position[VZ] += (mBodySize[VZ]* 0.55f);
+	if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
+	{
+		mTargetRootToHeadOffset = head_offset;
+	}
+	
+	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f));
+
+	LLVector3 name_position = mRoot.getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
 	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	
-	name_position += pixel_up_vec * 15.f;
+	name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
 
-	return name_position;
+	mNameText->setPositionAgent(name_position);				
 }
 
 void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
@@ -3333,7 +3341,7 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
 		else
 		{
 			color_name = "NameTagMismatch";
-	}
+		}
 	}
 	else
 	{
@@ -3370,9 +3378,9 @@ bool LLVOAvatar::isVisuallyMuted()
 	static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
 	static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
 	
-	return LLMuteList::getInstance()->isMuted(getID()) ||
-			(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
-			(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
+	return LLMuteList::getInstance()->isMuted(getID()) 
+			|| (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) 
+			|| (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
 }
 
 //------------------------------------------------------------------------
@@ -3413,8 +3421,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 	}
 
-	LLVector3d root_pos_global;
-
 	if (!mIsBuilt)
 	{
 		return FALSE;
@@ -3428,7 +3434,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	{
 		mTimeVisible.reset();
 	}
-
 	
 	//--------------------------------------------------------------------
 	// the rest should only be done occasionally for far away avatars
@@ -3823,10 +3828,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 		if ( playSound )
 		{
-//			F32 gain = clamp_rescale( mSpeedAccum,
-//							AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
-//							AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
-
 			const F32 STEP_VOLUME = 0.1f;
 			const LLUUID& step_sound_id = getStepSound();
 
@@ -4043,13 +4044,6 @@ void LLVOAvatar::updateVisibility()
 		{
 			releaseMeshData();
 		}
-		// this breaks off-screen chat bubbles
-		//if (mNameText)
-		//{
-		//	mNameText->markDead();
-		//	mNameText = NULL;
-		//	sNumVisibleChatBubbles--;
-		//}
 	}
 
 	mVisible = visible;
@@ -4065,46 +4059,6 @@ bool LLVOAvatar::shouldAlphaMask()
 
 }
 
-U32 LLVOAvatar::renderSkinnedAttachments()
-{
-	/*U32 num_indices = 0;
-	
-	const U32 data_mask =	LLVertexBuffer::MAP_VERTEX | 
-							LLVertexBuffer::MAP_NORMAL | 
-							LLVertexBuffer::MAP_TEXCOORD0 |
-							LLVertexBuffer::MAP_COLOR |
-							LLVertexBuffer::MAP_WEIGHT4;
-
-	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); 
-		 iter != mAttachmentPoints.end();
-		 ++iter)
-	{
-		LLViewerJointAttachment* attachment = iter->second;
-		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-			 attachment_iter != attachment->mAttachedObjects.end();
-			 ++attachment_iter)
-		{
-			const LLViewerObject* attached_object = (*attachment_iter);
-			if (attached_object && !attached_object->isHUDAttachment())
-			{
-				const LLDrawable* drawable = attached_object->mDrawable;
-				if (drawable)
-				{
-					for (S32 i = 0; i < drawable->getNumFaces(); ++i)
-					{
-						LLFace* face = drawable->getFace(i);
-						if (face->isState(LLFace::RIGGED))
-						{
-							
-				}
-			}
-		}
-	}
-
-	return num_indices;*/
-	return 0;
-}
-
 //-----------------------------------------------------------------------------
 // renderSkinned()
 //-----------------------------------------------------------------------------
@@ -4125,11 +4079,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 	{	//LOD changed or new mesh created, allocate new vertex buffer if needed
 		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
 		{
-		updateMeshData();
+			updateMeshData();
 			mDirtyMesh = 0;
-		mNeedsSkin = TRUE;
-		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
-	}
+			mNeedsSkin = TRUE;
+			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+		}
 	}
 
 	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -5790,36 +5744,34 @@ BOOL LLVOAvatar::updateJointLODs()
 	F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
 	F32 area_scale = 0.16f;
 
+	if (isSelf())
 	{
-		if (isSelf())
-		{
-			if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
-			{
-				mAdjustedPixelArea = MAX_PIXEL_AREA;
-			}
-			else
-			{
-				mAdjustedPixelArea = mPixelArea*area_scale;
-			}
-		}
-		else if (mIsDummy)
+		if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
 		{
 			mAdjustedPixelArea = MAX_PIXEL_AREA;
 		}
 		else
 		{
-			// reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
-			mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+			mAdjustedPixelArea = mPixelArea*area_scale;
 		}
+	}
+	else if (mIsDummy)
+	{
+		mAdjustedPixelArea = MAX_PIXEL_AREA;
+	}
+	else
+	{
+		// reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
+		mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+	}
 
-		// now select meshes to render based on adjusted pixel area
-		BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
- 		if (res)
-		{
-			sNumLODChangesThisFrame++;
-			dirtyMesh(2);
-			return TRUE;
-		}
+	// now select meshes to render based on adjusted pixel area
+	BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
+ 	if (res)
+	{
+		sNumLODChangesThisFrame++;
+		dirtyMesh(2);
+		return TRUE;
 	}
 
 	return FALSE;
@@ -6109,25 +6061,18 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
 		if ( pVObj )
 		{
 			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
-			if ( pSkinData )
-			{
-				const int jointCnt = pSkinData->mJointNames.size();
-				bool fullRig = ( jointCnt>=20 ) ? true : false;
-				if ( fullRig )
+			if (pSkinData 
+				&& pSkinData->mJointNames.size() > 20				// full rig
+				&& pSkinData->mAlternateBindMatrix.size() > 0)
+			{
+				LLVOAvatar::resetJointPositionsToDefault();
+				//Need to handle the repositioning of the cam, updating rig data etc during outfit editing 
+				//This handles the case where we detach a replacement rig.
+				if ( gAgentCamera.cameraCustomizeAvatar() )
 				{
-					const int bindCnt = pSkinData->mAlternateBindMatrix.size();							
-					if ( bindCnt > 0 )
-					{
-						LLVOAvatar::resetJointPositionsToDefault();
-						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing 
-						//This handles the case where we detach a replacement rig.
-						if ( gAgentCamera.cameraCustomizeAvatar() )
-						{
-							gAgent.unpauseAnimation();
-							//Still want to refocus on head bone
-							gAgentCamera.changeCameraToCustomizeAvatar();
-						}
-					}
+					gAgent.unpauseAnimation();
+					//Still want to refocus on head bone
+					gAgentCamera.changeCameraToCustomizeAvatar();
 				}
 			}				
 		}
@@ -6281,11 +6226,7 @@ void LLVOAvatar::getOffObject()
 		at_axis.mV[VZ] = 0.f;
 		at_axis.normalize();
 		gAgent.resetAxes(at_axis);
-
-		//reset orientation
-//		mRoot.setRotation(avWorldRot);
 		gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
-
 		gAgentCamera.setSitCamera(LLUUID::null);
 	}
 }
@@ -6335,7 +6276,6 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
 	}
 	else
 	{
-//		return LLColor4( .5f, .5f, .5f, .5f );
 		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
 	}
 }
@@ -7067,10 +7007,6 @@ LLBBox LLVOAvatar::getHUDBBox() const
 	return bbox;
 }
 
-void LLVOAvatar::rebuildHUD()
-{
-}
-
 //-----------------------------------------------------------------------------
 // onFirstTEMessageReceived()
 //-----------------------------------------------------------------------------
@@ -7192,7 +7128,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 			&& baked_index != BAKED_SKIRT)
 		{
 			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, 
-				LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+						LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, 
+																TRUE, 
+																LLViewerTexture::BOOST_NONE, 
+																LLViewerTexture::LOD_TEXTURE));
 		}
 	}
 
@@ -7483,11 +7422,6 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_
 // Called when baked texture is loaded and also when we start up with a baked texture
 void LLVOAvatar::useBakedTexture( const LLUUID& id )
 {
-	/* if(id == head_baked->getID())
-		 mHeadBakedLoaded = TRUE;
-		 mLastHeadBakedID = id;
-		 mHeadMesh0.setTexture( head_baked );
-		 mHeadMesh1.setTexture( head_baked ); */
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
 		LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index dd0317f555..e84acd51ff 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -66,8 +66,9 @@ class LLVoiceVisualizer;
 class LLHUDNameTag;
 class LLHUDEffectSpiral;
 class LLTexGlobalColor;
-class LLVOAvatarBoneInfo;
-class LLVOAvatarSkeletonInfo;
+struct LLVOAvatarBoneInfo;
+struct LLVOAvatarChildJoint;
+struct LLVOAvatarSkeletonInfo;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLVOAvatar
@@ -232,7 +233,7 @@ public:
 	void 			idleUpdateWindEffect();
 	void 			idleUpdateNameTag(const LLVector3& root_pos_last);
 	void			idleUpdateNameTagText(BOOL new_name);
-	LLVector3		idleUpdateNameTagPosition(const LLVector3& root_pos_last);
+	void			idleUpdateNameTagPosition(const LLVector3& root_pos_last);
 	void			idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
 	LLColor4		getNameTagColor(bool is_friend);
 	void			clearNameTag();
@@ -317,6 +318,8 @@ public:
 	F32					mLastPelvisToFoot;
 	F32					mPelvisFixup;
 	F32					mLastPelvisFixup;
+	LLVector3			mCurRootToHeadOffset;
+	LLVector3			mTargetRootToHeadOffset;
 
 	LLVector3			mHeadOffset; // current head position
 	LLViewerJoint		mRoot;
@@ -325,7 +328,7 @@ protected:
 	void				buildCharacter();
 	virtual BOOL		loadAvatar();
 
-	BOOL				setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+	BOOL				setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
 	BOOL				buildSkeleton(const LLVOAvatarSkeletonInfo *info);
 private:
 	BOOL				mIsBuilt; // state of deferred character building
@@ -369,7 +372,7 @@ public:
 	//--------------------------------------------------------------------
 private:
 	static LLXmlTree 	sXMLTree; // avatar config file
-	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file
+	static LLXMLNodePtr	sSkeletonXMLTree; // avatar skeleton file
 
 /**                    Skeleton
  **                                                                            **
@@ -387,7 +390,6 @@ public:
 	U32 		renderRigid();
 	U32 		renderSkinned(EAvatarRenderPass pass);
 	F32			getLastSkinTime() { return mLastSkinTime; }
-	U32			renderSkinnedAttachments();
 	U32 		renderTransparent(BOOL first_pass);
 	void 		renderCollisionVolumes();
 	static void	deleteCachedImages(bool clearAll=true);
@@ -735,7 +737,6 @@ public:
 public:
 	BOOL 				hasHUDAttachment() const;
 	LLBBox 				getHUDBBox() const;
-	void 				rebuildHUD();
 	void 				resetHUDAttachments();
 	BOOL				canAttachMoreObjects() const;
 	BOOL				canAttachMoreObjects(U32 n) const;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c523a78b22..fc499bfe9c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4678,11 +4678,6 @@ void LLPipeline::rebuildPools()
 		}
 		max_count--;
 	}
-
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->rebuildHUD();
-	}
 }
 
 void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
-- 
cgit v1.2.3


From d88491d55843b62e4206e7a28614d5dcc4ed6b9e Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 11 Apr 2012 14:00:26 -0700
Subject: rolled back accidental merge of wip code

---
 indra/newview/llvoavatar.h | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index e84acd51ff..599d7e66b4 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -66,9 +66,8 @@ class LLVoiceVisualizer;
 class LLHUDNameTag;
 class LLHUDEffectSpiral;
 class LLTexGlobalColor;
-struct LLVOAvatarBoneInfo;
-struct LLVOAvatarChildJoint;
-struct LLVOAvatarSkeletonInfo;
+class LLVOAvatarBoneInfo;
+class LLVOAvatarSkeletonInfo;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLVOAvatar
@@ -328,7 +327,7 @@ protected:
 	void				buildCharacter();
 	virtual BOOL		loadAvatar();
 
-	BOOL				setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+	BOOL				setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
 	BOOL				buildSkeleton(const LLVOAvatarSkeletonInfo *info);
 private:
 	BOOL				mIsBuilt; // state of deferred character building
@@ -372,7 +371,7 @@ public:
 	//--------------------------------------------------------------------
 private:
 	static LLXmlTree 	sXMLTree; // avatar config file
-	static LLXMLNodePtr	sSkeletonXMLTree; // avatar skeleton file
+	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file
 
 /**                    Skeleton
  **                                                                            **
-- 
cgit v1.2.3


From 571a929040d2303f4b0917337d4900229a08f99e Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 11 Apr 2012 19:07:14 -0700
Subject: CHUI-89 FIX Make nametags appear consistently next to avatar heads
 tweaked nametag positioning

---
 indra/newview/llvoavatar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index ef59e366e8..0ae95c6eff 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -196,7 +196,7 @@ const F32 CHAT_FADE_TIME = 8.0;
 const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
 const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;
 const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
-const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.15f;
+const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;
 
 const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
 
-- 
cgit v1.2.3


From a3d08c2355e35758b27b0fb7dca926959c440e63 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 12 Apr 2012 11:26:38 -0700
Subject: fixed broken unit tests

---
 indra/llui/tests/llurlentry_stub.cpp | 2 +-
 indra/llui/tests/llurlmatch_test.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index c75df86891..20bac5ff55 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -113,7 +113,7 @@ namespace LLInitParam
 		mEnclosingBlockOffset = (U16)(my_addr - block_addr);
 	}
 
-	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
+	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name){}
 	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
 	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
 	
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 7183413463..9119e7d1fe 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -74,7 +74,7 @@ namespace LLInitParam
 						S32 max_count){}
 	ParamDescriptor::~ParamDescriptor() {}
 
-	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}
+	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name){}
 	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}
 	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}
 
-- 
cgit v1.2.3


From bc4702a7c74977d4f685902b1d6f5d3cb07318d4 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Thu, 12 Apr 2012 23:25:12 +0300
Subject: CHUI-90 WIP Removed all buttons and menus from avatar inspectors.

---
 indra/newview/llinspectavatar.cpp                  | 572 +--------------------
 .../skins/default/xui/en/inspect_avatar.xml        | 105 ----
 .../default/xui/en/menu_inspect_avatar_gear.xml    | 143 ------
 .../default/xui/en/menu_inspect_self_gear.xml      | 252 ---------
 4 files changed, 2 insertions(+), 1070 deletions(-)
 delete mode 100644 indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
 delete mode 100644 indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml

(limited to 'indra')

diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index b2a8c6e3e6..bf71a5c5c5 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -28,38 +28,20 @@
 #include "llinspectavatar.h"
 
 // viewer files
-#include "llagent.h"
-#include "llagentdata.h"
-#include "llavataractions.h"
+#include "llavatariconctrl.h"
 #include "llavatarnamecache.h"
 #include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
 #include "lldateutil.h"
-#include "llfloaterreporter.h"
-#include "llfloaterworldmap.h"
-#include "llimview.h"
 #include "llinspect.h"
-#include "llmutelist.h"
-#include "llpanelblockedlist.h"
 #include "llstartup.h"
-#include "llspeakers.h"
-#include "llviewermenu.h"
-#include "llvoiceclient.h"
-#include "llviewerobjectlist.h"
 #include "lltransientfloatermgr.h"
-#include "llnotificationsutil.h"
 
 // Linden libraries
 #include "llfloater.h"
 #include "llfloaterreg.h"
-#include "llmenubutton.h"
 #include "lltextbox.h"
-#include "lltoggleablemenu.h"
 #include "lltooltip.h"	// positionViewNearMouse()
 #include "lltrans.h"
-#include "lluictrl.h"
-
-#include "llavatariconctrl.h"
 
 class LLFetchAvatarData;
 
@@ -81,22 +63,13 @@ public:
 	LLInspectAvatar(const LLSD& avatar_id);
 	virtual ~LLInspectAvatar();
 	
-	/*virtual*/ BOOL postBuild(void);
-	
 	// Because floater is single instance, need to re-parse data on each spawn
 	// (for example, inspector about same avatar but in different position)
 	/*virtual*/ void onOpen(const LLSD& avatar_id);
 
-	// When closing they should close their gear menu 
-	/*virtual*/ void onClose(bool app_quitting);
-	
 	// Update view based on information from avatar properties processor
 	void processAvatarData(LLAvatarData* data);
 	
-	// override the inspector mouse leave so timer is only paused if 
-	// gear menu is not open
-	/* virtual */ void onMouseLeave(S32 x, S32 y, MASK mask);
-	
 	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
 
 private:
@@ -104,47 +77,6 @@ private:
 	// Used on construction and if avatar id changes.
 	void requestUpdate();
 	
-	// Set the volume slider to this user's current client-side volume setting,
-	// hiding/disabling if the user is not nearby.
-	void updateVolumeSlider();
-
-	// Shows/hides moderator panel depending on voice state 
-	void updateModeratorPanel();
-
-	// Moderator ability to enable/disable voice chat for avatar
-	void toggleSelectedVoice(bool enabled);
-	
-	// Button callbacks
-	void onClickAddFriend();
-	void onClickViewProfile();
-	void onClickIM();
-	void onClickCall();
-	void onClickTeleport();
-	void onClickInviteToGroup();
-	void onClickPay();
-	void onClickShare();
-	void onToggleMute();
-	void onClickReport();
-	void onClickFreeze();
-	void onClickEject();
-	void onClickKick();
-	void onClickCSR();
-	void onClickZoomIn();  
-	void onClickFindOnMap();
-	bool onVisibleFindOnMap();
-	bool onVisibleEject();
-	bool onVisibleFreeze();
-	bool onVisibleZoomIn();
-	void onClickMuteVolume();
-	void onVolumeChange(const LLSD& data);
-	bool enableMute();
-	bool enableUnmute();
-	bool enableTeleportOffer();
-	bool godModeEnabled();
-
-	// Is used to determine if "Add friend" option should be enabled in gear menu
-	bool isNotFriend();
-	
 	void onAvatarNameCache(const LLUUID& agent_id,
 						   const LLAvatarName& av_name);
 	
@@ -209,39 +141,8 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
 	mAvatarName(),
 	mPropertiesRequest(NULL)
 {
-	mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile",	boost::bind(&LLInspectAvatar::onClickViewProfile, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.AddFriend",	boost::bind(&LLInspectAvatar::onClickAddFriend, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.IM",
-		boost::bind(&LLInspectAvatar::onClickIM, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Call",		boost::bind(&LLInspectAvatar::onClickCall, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Teleport",	boost::bind(&LLInspectAvatar::onClickTeleport, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.InviteToGroup",	boost::bind(&LLInspectAvatar::onClickInviteToGroup, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Pay",	boost::bind(&LLInspectAvatar::onClickPay, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Share",	boost::bind(&LLInspectAvatar::onClickShare, this));
-	mCommitCallbackRegistrar.add("InspectAvatar.ToggleMute",	boost::bind(&LLInspectAvatar::onToggleMute, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Freeze", boost::bind(&LLInspectAvatar::onClickFreeze, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Eject", boost::bind(&LLInspectAvatar::onClickEject, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Kick", boost::bind(&LLInspectAvatar::onClickKick, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.CSR", boost::bind(&LLInspectAvatar::onClickCSR, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Report",	boost::bind(&LLInspectAvatar::onClickReport, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap",	boost::bind(&LLInspectAvatar::onClickFindOnMap, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this));
-	mCommitCallbackRegistrar.add("InspectAvatar.DisableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, false));
-	mCommitCallbackRegistrar.add("InspectAvatar.EnableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, true));
-
-	mEnableCallbackRegistrar.add("InspectAvatar.EnableGod",	boost::bind(&LLInspectAvatar::godModeEnabled, this));	
-	mEnableCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap",	boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));	
-	mEnableCallbackRegistrar.add("InspectAvatar.VisibleEject",	boost::bind(&LLInspectAvatar::onVisibleEject, this));	
-	mEnableCallbackRegistrar.add("InspectAvatar.VisibleFreeze",	boost::bind(&LLInspectAvatar::onVisibleFreeze, this));	
-	mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn", boost::bind(&LLInspectAvatar::onVisibleZoomIn, this));
-	mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this));
-	mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall));
-	mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableTeleportOffer", boost::bind(&LLInspectAvatar::enableTeleportOffer, this));
-	mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this));
-	mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this));
-
 	// can't make the properties request until the widgets are constructed
-	// as it might return immediately, so do it in postBuild.
+	// as it might return immediately, so do it in onOpen.
 
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
 	LLTransientFloater::init(this);
@@ -257,25 +158,6 @@ LLInspectAvatar::~LLInspectAvatar()
 	LLTransientFloaterMgr::getInstance()->removeControlView(this);
 }
 
-/*virtual*/
-BOOL LLInspectAvatar::postBuild(void)
-{
-	getChild<LLUICtrl>("add_friend_btn")->setCommitCallback(
-		boost::bind(&LLInspectAvatar::onClickAddFriend, this) );
-
-	getChild<LLUICtrl>("view_profile_btn")->setCommitCallback(
-		boost::bind(&LLInspectAvatar::onClickViewProfile, this) );
-
-	getChild<LLUICtrl>("mute_btn")->setCommitCallback(
-		boost::bind(&LLInspectAvatar::onClickMuteVolume, this) );
-
-	getChild<LLUICtrl>("volume_slider")->setCommitCallback(
-		boost::bind(&LLInspectAvatar::onVolumeChange, this, _2));
-
-	return TRUE;
-}
-
-
 // Multiple calls to showInstance("inspect_avatar", foo) will provide different
 // LLSD for foo, which we will catch here.
 //virtual
@@ -287,11 +169,6 @@ void LLInspectAvatar::onOpen(const LLSD& data)
 	// Extract appropriate avatar id
 	mAvatarID = data["avatar_id"];
 
-	BOOL self = mAvatarID == gAgent.getID();
-	
-	getChild<LLUICtrl>("gear_self_btn")->setVisible(self);
-	getChild<LLUICtrl>("gear_btn")->setVisible(!self);
-
 	// Position the inspector relative to the mouse cursor
 	// Similar to how tooltips are positioned
 	// See LLToolTipMgr::createToolTip
@@ -306,18 +183,8 @@ void LLInspectAvatar::onOpen(const LLSD& data)
 
 	// can't call from constructor as widgets are not built yet
 	requestUpdate();
-
-	updateVolumeSlider();
-
-	updateModeratorPanel();
 }
 
-// virtual
-void LLInspectAvatar::onClose(bool app_quitting)
-{  
-  getChild<LLMenuButton>("gear_btn")->hideMenu();
-}	
-
 void LLInspectAvatar::requestUpdate()
 {
 	// Don't make network requests when spawning from the debug menu at the
@@ -344,25 +211,6 @@ void LLInspectAvatar::requestUpdate()
 	delete mPropertiesRequest;
 	mPropertiesRequest = new LLFetchAvatarData(mAvatarID, this);
 
-	// You can't re-add someone as a friend if they are already your friend
-	bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
-	bool is_self = (mAvatarID == gAgentID);
-	if (is_self)
-	{
-		getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
-		getChild<LLUICtrl>("im_btn")->setVisible(false);
-	}
-	else if (is_friend)
-	{
-		getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
-		getChild<LLUICtrl>("im_btn")->setVisible(true);
-	}
-	else
-	{
-		getChild<LLUICtrl>("add_friend_btn")->setVisible(true);
-		getChild<LLUICtrl>("im_btn")->setVisible(false);
-	}
-
 	// Use an avatar_icon even though the image id will come down with the
 	// avatar properties because the avatar_icon code maintains a cache of icons
 	// and this may result in the image being visible sooner.
@@ -405,213 +253,6 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)
 	mPropertiesRequest = NULL;
 }
 
-// For the avatar inspector, we only want to unpause the fade timer 
-// if neither the gear menu or self gear menu are open
-void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	LLToggleableMenu* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu();
-	LLToggleableMenu* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu();
-	if ( gear_menu && gear_menu->getVisible() &&
-		 gear_menu_self && gear_menu_self->getVisible() )
-	{
-		return;
-	}
-
-	if(childHasVisiblePopupMenu())
-	{
-		return;
-	}
-
-	mOpenTimer.unpause();
-}
-
-void LLInspectAvatar::updateModeratorPanel()
-{
-	bool enable_moderator_panel = false;
-
-    if (LLVoiceChannel::getCurrentVoiceChannel() &&
-		mAvatarID != gAgent.getID())
-    {
-		LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
-
-		if (session_id != LLUUID::null)
-		{
-			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
-
-			if (speaker_mgr)
-			{
-				LLPointer<LLSpeaker> self_speakerp = speaker_mgr->findSpeaker(gAgent.getID());
-				LLPointer<LLSpeaker> selected_speakerp = speaker_mgr->findSpeaker(mAvatarID);
-				
-				if(speaker_mgr->isVoiceActive() && selected_speakerp && 
-					selected_speakerp->isInVoiceChannel() &&
-					((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike()))
-				{
-					getChild<LLUICtrl>("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice);
-					getChild<LLUICtrl>("disable_voice")->setVisible(!selected_speakerp->mModeratorMutedVoice);
-
-					enable_moderator_panel = true;
-				}
-			}
-		}
-	}
-
-	if (enable_moderator_panel)
-	{
-		if (!getChild<LLUICtrl>("moderator_panel")->getVisible())
-		{
-			getChild<LLUICtrl>("moderator_panel")->setVisible(true);
-			// stretch the floater so it can accommodate the moderator panel
-			reshape(getRect().getWidth(), getRect().getHeight() + getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
-		}
-	}
-	else if (getChild<LLUICtrl>("moderator_panel")->getVisible())
-	{
-		getChild<LLUICtrl>("moderator_panel")->setVisible(false);
-		// shrink the inspector floater back to original size
-		reshape(getRect().getWidth(), getRect().getHeight() - getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());					
-	}
-}
-
-void LLInspectAvatar::toggleSelectedVoice(bool enabled)
-{
-	LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
-	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
-
-	if (speaker_mgr)
-	{
-		if (!gAgent.getRegion())
-			return;
-
-		std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
-		LLSD data;
-		data["method"] = "mute update";
-		data["session-id"] = session_id;
-		data["params"] = LLSD::emptyMap();
-		data["params"]["agent_id"] = mAvatarID;
-		data["params"]["mute_info"] = LLSD::emptyMap();
-		// ctrl value represents ability to type, so invert
-		data["params"]["mute_info"]["voice"] = !enabled;
-
-		class MuteVoiceResponder : public LLHTTPClient::Responder
-		{
-		public:
-			MuteVoiceResponder(const LLUUID& session_id)
-			{
-				mSessionID = session_id;
-			}
-
-			virtual void error(U32 status, const std::string& reason)
-			{
-				llwarns << status << ": " << reason << llendl;
-
-				if ( gIMMgr )
-				{
-					//403 == you're not a mod
-					//should be disabled if you're not a moderator
-					if ( 403 == status )
-					{
-						gIMMgr->showSessionEventError(
-							"mute",
-							"not_a_moderator",
-							mSessionID);
-					}
-					else
-					{
-						gIMMgr->showSessionEventError(
-							"mute",
-							"generic",
-							mSessionID);
-					}
-				}
-			}
-
-		private:
-			LLUUID mSessionID;
-		};
-
-		LLHTTPClient::post(
-			url,
-			data,
-			new MuteVoiceResponder(speaker_mgr->getSessionID()));
-	}
-
-	closeFloater();
-
-}
-
-void LLInspectAvatar::updateVolumeSlider()
-{
-	bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID);
-
-	// Do not display volume slider and mute button if it 
-	// is ourself or we are not in a voice channel together
-	if (!voice_enabled || (mAvatarID == gAgent.getID()))
-	{
-		getChild<LLUICtrl>("mute_btn")->setVisible(false);
-		getChild<LLUICtrl>("volume_slider")->setVisible(false);
-	}
-
-	else 
-	{
-		getChild<LLUICtrl>("mute_btn")->setVisible(true);
-		getChild<LLUICtrl>("volume_slider")->setVisible(true);
-
-		// By convention, we only display and toggle voice mutes, not all mutes
-		bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
-
-		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
-
-		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
-
-		mute_btn->setEnabled( !is_linden);
-		mute_btn->setValue( is_muted );
-
-		LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
-		volume_slider->setEnabled( !is_muted );
-
-		F32 volume;
-		
-		if (is_muted)
-		{
-			// it's clearer to display their volume as zero
-			volume = 0.f;
-		}
-		else
-		{
-			// actual volume
-			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
-		}
-		volume_slider->setValue( (F64)volume );
-	}
-
-}
-
-void LLInspectAvatar::onClickMuteVolume()
-{
-	// By convention, we only display and toggle voice mutes, not all mutes
-	LLMuteList* mute_list = LLMuteList::getInstance();
-	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
-
-	LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT);
-	if (!is_muted)
-	{
-		mute_list->add(mute, LLMute::flagVoiceChat);
-	}
-	else
-	{
-		mute_list->remove(mute, LLMute::flagVoiceChat);
-	}
-
-	updateVolumeSlider();
-}
-
-void LLInspectAvatar::onVolumeChange(const LLSD& data)
-{
-	F32 volume = (F32)data.asReal();
-	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
-}
-
 void LLInspectAvatar::onAvatarNameCache(
 		const LLUUID& agent_id,
 		const LLAvatarName& av_name)
@@ -639,215 +280,6 @@ void LLInspectAvatar::onAvatarNameCache(
 	}
 }
 
-void LLInspectAvatar::onClickAddFriend()
-{
-	LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName.getLegacyName());
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickViewProfile()
-{
-	LLAvatarActions::showProfile(mAvatarID);
-	closeFloater();
-}
-
-bool LLInspectAvatar::isNotFriend()
-{
-	return !LLAvatarActions::isFriend(mAvatarID);
-}
-
-bool LLInspectAvatar::onVisibleFindOnMap()
-{
-	return gAgent.isGodlike() || is_agent_mappable(mAvatarID);
-}
-
-bool LLInspectAvatar::onVisibleEject()
-{
-	return enable_freeze_eject( LLSD(mAvatarID) );
-}
-
-bool LLInspectAvatar::onVisibleFreeze()
-{
-	// either user is a god and can do long distance freeze
-	// or check for target proximity and permissions
-	return gAgent.isGodlike() || enable_freeze_eject(LLSD(mAvatarID));
-}
-
-bool LLInspectAvatar::onVisibleZoomIn()
-{
-	return gObjectList.findObject(mAvatarID);
-}
-
-void LLInspectAvatar::onClickIM()
-{ 
-	LLAvatarActions::startIM(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickCall()
-{ 
-	LLAvatarActions::startCall(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickTeleport()
-{
-	LLAvatarActions::offerTeleport(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickInviteToGroup()
-{
-	LLAvatarActions::inviteToGroup(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickPay()
-{
-	LLAvatarActions::pay(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickShare()
-{
-	LLAvatarActions::share(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onToggleMute()
-{
-	LLMute mute(mAvatarID, mAvatarName.mDisplayName, LLMute::AGENT);
-
-	if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
-	{
-		LLMuteList::getInstance()->remove(mute);
-	}
-	else
-	{
-		LLMuteList::getInstance()->add(mute);
-	}
-
-	LLPanelBlockedList::showPanelAndSelect(mute.mID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickReport()
-{
-	LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getCompleteName());
-	closeFloater();
-}
-
-bool godlike_freeze(const LLSD& notification, const LLSD& response)
-{
-	LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
-	switch (option)
-	{
-	case 0:
-		LLAvatarActions::freeze(avatar_id);
-		break;
-	case 1:
-		LLAvatarActions::unfreeze(avatar_id);
-		break;
-	default:
-		break;
-	}
-
-	return false;
-}
-
-void LLInspectAvatar::onClickFreeze()
-{
-	if (gAgent.isGodlike())
-	{
-		// use godlike freeze-at-a-distance, with confirmation
-		LLNotificationsUtil::add("FreezeAvatar",
-			LLSD(),
-			LLSD().with("avatar_id", mAvatarID),
-			godlike_freeze);
-	}
-	else
-	{
-		// use default "local" version of freezing that requires avatar to be in range
-		handle_avatar_freeze( LLSD(mAvatarID) );
-	}
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickEject()
-{
-	handle_avatar_eject( LLSD(mAvatarID) );
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickKick()
-{
-	LLAvatarActions::kick(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickCSR()
-{
-	std::string name;
-	gCacheName->getFullName(mAvatarID, name);
-	LLAvatarActions::csr(mAvatarID, name);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickZoomIn() 
-{
-	handle_zoom_to_object(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickFindOnMap()
-{
-	gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName.mDisplayName);
-	LLFloaterReg::showInstance("world_map");
-}
-
-
-bool LLInspectAvatar::enableMute()
-{
-		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
-		bool is_self = mAvatarID == gAgent.getID();
-
-		if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName()))
-		{
-			return true;
-		}
-		else
-		{
-			return false;
-		}
-}
-
-bool LLInspectAvatar::enableUnmute()
-{
-		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
-		bool is_self = mAvatarID == gAgent.getID();
-
-		if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName()))
-		{
-			return true;
-		}
-		else
-		{
-			return false;
-		}
-}
-
-bool LLInspectAvatar::enableTeleportOffer()
-{
-	return LLAvatarActions::canOfferTeleport(mAvatarID);
-}
-
-bool LLInspectAvatar::godModeEnabled()
-{
-	return gAgent.isGodlike();
-}
-
 //////////////////////////////////////////////////////////////////////////////
 // LLInspectAvatarUtil
 //////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index bc3bcd331b..866d54e4f8 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -94,32 +94,6 @@
      use_ellipses="true"
      width="220">This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot
     </text>
-    <slider
-     follows="top|left"
-     height="23"
-     increment="0.01"
-     left="1"
-     max_val="0.95"
-     min_val="0.05"
-     name="volume_slider"
-     show_text="false"
-     tool_tip="Voice volume"
-     top_pad="0"
-     value="0.5"
-     width="200" />
-    <button
-     follows="top|left"
-     height="16"
-     image_disabled="Audio_Off"
-     image_disabled_selected="AudioMute_Off"
-     image_hover_selected="AudioMute_Over"
-     image_selected="AudioMute_Off"
-     image_unselected="Audio_Off"
-     is_toggle="true"
-     left_pad="0"
-     top_delta="4"
-     name="mute_btn"
-     width="16" />
     <avatar_icon
      follows="top|left"
      height="38"
@@ -130,83 +104,4 @@
      name="avatar_icon"
      top="10"
      width="38" />
-<!-- Overlapping buttons for default actions
-    llinspectavatar.cpp makes visible the most likely default action 
--->
-    <button
-     follows="top|left"
-     height="20"
-     label="Add Friend"
-     left="8"
-     top="135"
-     name="add_friend_btn"
-     width="90" />
-    <button
-     follows="top|left"
-     height="20"
-     label="IM"
-     left_delta="0"
-     top_delta="0"
-     name="im_btn"
-     width="80"
-     commit_callback.function="InspectAvatar.IM"/>
-	<button
-     follows="top|left"
-     height="20"
-     label="Profile"
-     layout="topleft"
-     name="view_profile_btn"
-     left_delta="96"
-     top_delta="0"
-     tab_stop="false"
-     width="80" />
-      <!--  gear buttons here -->
-  <menu_button
-     follows="top|left"
-     height="20"
-     layout="topleft"
-     image_overlay="OptionsMenu_Off"
-     menu_filename="menu_inspect_avatar_gear.xml"
-     name="gear_btn"
-     right="-5"
-     top_delta="0"
-     width="35" />
-	<menu_button
-     follows="top|left"
-     height="20"
-     image_overlay="OptionsMenu_Off"
-     menu_filename="menu_inspect_self_gear.xml"
-     name="gear_self_btn"
-     right="-5"
-     top_delta="0"
-     width="35" />
-  <panel 
-    follows="top|left" 
-    top="164" 
-    left="0" 
-    height="60" 
-    width="228" 
-    visible="false"
-    background_visible="true"
-    name="moderator_panel"
-    background_opaque="true" 
-    bg_opaque_color="MouseGray">
-    <button
-      name="disable_voice"
-      label="Disable Voice"
-      top="20"
-      width="95"
-      height="20"
-      left="10"
-      commit_callback.function="InspectAvatar.DisableVoice"/>
-    <button
-      name="enable_voice"
-      label="Enable Voice"
-      top="20"
-      width="95"
-      height="20"
-      left="10"
-      visible="false" 
-      commit_callback.function="InspectAvatar.EnableVoice"/>
-  </panel>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
deleted file mode 100644
index 76b188220d..0000000000
--- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
+++ /dev/null
@@ -1,143 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<toggleable_menu
-         create_jump_keys="true"
-         layout="topleft"
-         mouse_opaque="false"
-         visible="false"
-         name="Gear Menu">
-  <menu_item_call
-   label="View Profile"
-   enabled="true" 
-   name="view_profile">
-    <menu_item_call.on_click
-     function="InspectAvatar.ViewProfile"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Add Friend"
-   name="add_friend">
-    <menu_item_call.on_click
-     function="InspectAvatar.AddFriend"/>
-    <menu_item_call.on_enable
-     function="InspectAvatar.Gear.Enable"/>
-  </menu_item_call>
-  <menu_item_call
-   label="IM"
-   name="im">
-    <menu_item_call.on_click
-     function="InspectAvatar.IM"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Call"
-   enabled="true"
-   name="call">
-    <menu_item_call.on_click
-     function="InspectAvatar.Call"/>
-    <menu_item_call.on_enable
-     function="InspectAvatar.Gear.EnableCall"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Teleport"
-   name="teleport">
-    <menu_item_call.on_click
-     function="InspectAvatar.Teleport"/>
-    <menu_item_call.on_enable
-     function="InspectAvatar.Gear.EnableTeleportOffer"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Invite to Group"
-   name="invite_to_group">
-    <menu_item_call.on_click
-     function="InspectAvatar.InviteToGroup"/>
-  </menu_item_call>
-  <menu_item_separator />
-  <menu_item_call
-   label="Block"
-   name="block">
-    <menu_item_call.on_click
-     function="InspectAvatar.ToggleMute"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.EnableMute" />
-  </menu_item_call>
-  <menu_item_call
-   label="Unblock"
-   name="unblock">
-    <menu_item_call.on_click
-     function="InspectAvatar.ToggleMute"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.EnableUnmute" />
-  </menu_item_call>
-  <menu_item_call
-   label="Report"
-   name="report">
-    <menu_item_call.on_click
-     function="InspectAvatar.Report"/>
-  </menu_item_call>  
-  <menu_item_call
-   label="Freeze"
-   name="freeze">
-    <menu_item_call.on_click
-     function="InspectAvatar.Freeze"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.VisibleFreeze"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Eject"
-   name="eject">
-    <menu_item_call.on_click
-     function="InspectAvatar.Eject"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.VisibleEject"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Kick"
-   name="kick">
-    <menu_item_call.on_click
-     function="InspectAvatar.Kick"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.EnableGod"/>
-  </menu_item_call>
-  <menu_item_call
-  label="CSR"
-  name="csr">
-    <menu_item_call.on_click
-     function="InspectAvatar.CSR" />
-    <menu_item_call.on_visible
-     function="InspectAvatar.EnableGod" />
-  </menu_item_call>
-  <menu_item_call
-   label="Debug Textures"
-   name="debug">
-    <menu_item_call.on_click
-     function="Avatar.Debug"/>
-    <menu_item_call.on_visible
-     function="IsGodCustomerService"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Find On Map"
-   name="find_on_map">
-    <menu_item_call.on_click
-     function="InspectAvatar.FindOnMap"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.VisibleFindOnMap"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Zoom In"
-   name="zoom_in">
-    <menu_item_call.on_click
-     function="InspectAvatar.ZoomIn"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.VisibleZoomIn"/>
-  </menu_item_call>  
-  <menu_item_call
-   label="Pay"
-   name="pay">
-    <menu_item_call.on_click
-     function="InspectAvatar.Pay"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Share"
-   name="share">
-    <menu_item_call.on_click
-     function="InspectAvatar.Share"/>
-  </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml
deleted file mode 100644
index 5e7b16ed4a..0000000000
--- a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml
+++ /dev/null
@@ -1,252 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- layout="topleft"
- name="Self Pie">
-  <menu_item_call
-   label="Sit Down"
-   layout="topleft"
-   name="Sit Down Here">
-    <menu_item_call.on_click
-     function="Self.SitDown"
-     parameter="" />
-    <menu_item_call.on_enable
-     function="Self.EnableSitDown" />
-  </menu_item_call>
-  <menu_item_call
-   label="Stand Up"
-   layout="topleft"
-   name="Stand Up">
-    <menu_item_call.on_click
-     function="Self.StandUp"
-     parameter="" />
-    <menu_item_call.on_enable
-     function="Self.EnableStandUp" />
-  </menu_item_call>
-  <context_menu
-   label="Take Off"
-   layout="topleft"
-   name="Take Off &gt;">
-    <context_menu
-     label="Clothes"
-     layout="topleft"
-     name="Clothes &gt;">
-      <menu_item_call
-       enabled="false"
-       label="Shirt"
-       layout="topleft"
-       name="Shirt">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="shirt" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="shirt" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Pants"
-       layout="topleft"
-       name="Pants">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="pants" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="pants" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Skirt"
-       layout="topleft"
-       name="Skirt">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="skirt" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="skirt" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Shoes"
-       layout="topleft"
-       name="Shoes">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="shoes" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="shoes" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Socks"
-       layout="topleft"
-       name="Socks">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="socks" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="socks" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Jacket"
-       layout="topleft"
-       name="Jacket">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="jacket" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="jacket" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Gloves"
-       layout="topleft"
-       name="Gloves">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="gloves" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="gloves" />
-      </menu_item_call>
-      <menu_item_call
-            enabled="false"
-            label="Undershirt"
-            layout="topleft"
-            name="Self Undershirt">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="undershirt" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="undershirt" />
-      </menu_item_call>
-      <menu_item_call
-        enabled="false"
-        label="Underpants"
-        layout="topleft"
-        name="Self Underpants">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="underpants" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="underpants" />
-      </menu_item_call>
-      <menu_item_call
-        enabled="false"
-        label="Tattoo"
-        layout="topleft"
-        name="Self Tattoo">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="tattoo" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="tattoo" />
-      </menu_item_call>
-      <menu_item_call
-        enabled="false"
-        label="Alpha"
-        layout="topleft"
-        name="Self Alpha">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="alpha" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="alpha" />
-      </menu_item_call>
-      <menu_item_separator
-       layout="topleft" />
-      <menu_item_call
-       label="All Clothes"
-       layout="topleft"
-       name="All Clothes">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="all" />
-      </menu_item_call>
-    </context_menu>
-    <context_menu
-     label="HUD"
-     layout="topleft"
-     name="Object Detach HUD" />
-    <context_menu
-     label="Detach"
-     layout="topleft"
-     name="Object Detach" />
-    <menu_item_call
-     label="Detach All"
-     layout="topleft"
-     name="Detach All">
-      <menu_item_call.on_click
-       function="Self.RemoveAllAttachments"
-       parameter="" />
-      <menu_item_call.on_enable
-       function="Self.EnableRemoveAllAttachments" />
-    </menu_item_call>
-  </context_menu>
-  <menu_item_call
-  label="Change Outfit"
-  layout="topleft"
-  name="Chenge Outfit">
-    <menu_item_call.on_click
-     function="CustomizeAvatar" />
-    <menu_item_call.on_enable
-     function="Edit.EnableCustomizeAvatar" />
-  </menu_item_call>
-  <menu_item_call label="Edit My Outfit"
-  layout="topleft"
-  name="Edit Outfit">
-    <menu_item_call.on_click
-     function="EditOutfit" />
-    <menu_item_call.on_enable
-     function="Edit.EnableCustomizeAvatar" />
-  </menu_item_call>
-  <menu_item_call label="Edit My Shape"
-  layout="topleft"
-  name="Edit My Shape">
-    <menu_item_call.on_click
-     function="EditShape" />
-    <menu_item_call.on_enable
-     function="Edit.EnableEditShape" />
-  </menu_item_call>
-  <menu_item_call
-    label="My Friends"
-    layout="topleft"
-    name="Friends...">
-    <menu_item_call.on_click
-     function="SideTray.PanelPeopleTab"
-     parameter="friends_panel" />
-  </menu_item_call>
-  <menu_item_call
-   label="My Groups"
-   layout="topleft"
-   name="Groups...">
-    <menu_item_call.on_click
-     function="SideTray.PanelPeopleTab"
-     parameter="groups_panel" />
-  </menu_item_call>
-  <menu_item_call
-    label="My Profile"
-    layout="topleft"
-    name="Profile...">
-    <menu_item_call.on_click
-     function="ShowAgentProfile"
-     parameter="agent" />
-  </menu_item_call>
-  <menu_item_call
-   label="Debug Textures"
-       name="Debug...">
-    <menu_item_call.on_click
-     function="Avatar.Debug" />
-    <menu_item_call.on_visible
-     function="IsGodCustomerService"/>
-  </menu_item_call>
-</toggleable_menu>
-- 
cgit v1.2.3


From 1e74372f50a2cb2ed3364e79344b0408e7e8d89b Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Fri, 13 Apr 2012 00:26:33 +0300
Subject: CHUI-90 WIP Added "View full profile" link to avatar inspectors.

---
 indra/newview/llinspectavatar.cpp                     |  4 ++++
 indra/newview/skins/default/xui/en/inspect_avatar.xml | 13 ++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index bf71a5c5c5..8a15cd279f 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -33,6 +33,7 @@
 #include "llavatarpropertiesprocessor.h"
 #include "lldateutil.h"
 #include "llinspect.h"
+#include "llslurl.h"
 #include "llstartup.h"
 #include "lltransientfloatermgr.h"
 
@@ -181,6 +182,9 @@ void LLInspectAvatar::onOpen(const LLSD& data)
 		LLUI::positionViewNearMouse(this);
 	}
 
+	// Generate link to avatar profile.
+	getChild<LLUICtrl>("avatar_profile_link")->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString());
+
 	// can't call from constructor as widgets are not built yet
 	requestUpdate();
 }
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index 866d54e4f8..c3481e6d4c 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -9,7 +9,7 @@
  bg_opaque_image="Inspector_Background"
  can_close="false"
  can_minimize="false"
- height="164"
+ height="130"
  layout="topleft"
  name="inspect_avatar"
  single_instance="true"
@@ -94,6 +94,17 @@
      use_ellipses="true"
      width="220">This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot
     </text>
+    <text
+     follows="top|left"
+     height="16"
+     left="8"
+     name="avatar_profile_link"
+     font="SansSerifSmall"
+     text_color="White"
+     top_pad="5"
+     translate="false"
+     value="[[LINK] View full profile]"
+     width="175" />
     <avatar_icon
      follows="top|left"
      height="38"
-- 
cgit v1.2.3


From 855fbc0bf331c116d20d402f427535f060f70345 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 12 Apr 2012 17:18:34 -0700
Subject: fixed UI not working at all due to bad param blocks

---
 indra/llui/llloadingindicator.cpp |   2 +-
 indra/llui/llloadingindicator.h   |   6 +-
 indra/llxuixml/llinitparam.h      | 391 ++++++++++++++++++++++++++------------
 indra/llxuixml/llxuiparser.cpp    |  26 +--
 indra/newview/llvoavatar.cpp      |   2 +-
 5 files changed, 284 insertions(+), 143 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
index 6ac38f5ad4..1ede5b706f 100644
--- a/indra/llui/llloadingindicator.cpp
+++ b/indra/llui/llloadingindicator.cpp
@@ -52,7 +52,7 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
 
 void LLLoadingIndicator::initFromParams(const Params& p)
 {
-	BOOST_FOREACH(LLUIImage* image, p.images.image)
+	BOOST_FOREACH(LLUIImage* image, p.images().image)
 	{
 		mImages.push_back(image);
 	}
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
index c1f979c111..4998a57263 100644
--- a/indra/llui/llloadingindicator.h
+++ b/indra/llui/llloadingindicator.h
@@ -51,7 +51,7 @@ class LLLoadingIndicator
 	LOG_CLASS(LLLoadingIndicator);
 public:
 
-	struct Images : public LLInitParam::BatchBlock<Images>
+	struct Images : public LLInitParam::Block<Images>
 	{
 		Multiple<LLUIImage*>	image;
 
@@ -62,8 +62,8 @@ public:
 
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
-		Optional<F32>			images_per_sec;
-		Optional<Images>		images;
+		Optional<F32>				images_per_sec;
+		Optional<Batch<Images> >	images;
 
 		Params()
 		:	images_per_sec("images_per_sec", 1.0f),
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index dbf2fdaa73..0c53b36bad 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -390,15 +390,19 @@ namespace LLInitParam
 	class BaseBlock
 	{
 	public:
-		typedef IS_BLOCK IS_BLOCK;
-		typedef NOT_BLOCK NOT_BLOCK;
+		// lift block tags into baseblock namespace so derived classes do not need to qualify them
+		typedef LLInitParam::IS_BLOCK IS_BLOCK;
+		typedef LLInitParam::NOT_BLOCK NOT_BLOCK;
+
+		template<typename T>
+		class Batch
+		{};
 
 		//TODO: implement in terms of owned_ptr
-		template<typename T, typename BLOCK_T = IS_BLOCK>
+		template<typename T, typename BLOCK_T = IsBlock<T>::value_t >
 		class Lazy
 		{
 		public:
-			
 			Lazy()
 			:	mPtr(NULL)
 			{}
@@ -470,7 +474,7 @@ namespace LLInitParam
 				return get(); 
 			}
 
-		private:
+		private: 
 			// lazily allocate an instance of T
 			T* ensureInstance() const
 			{
@@ -642,11 +646,12 @@ namespace LLInitParam
 	{
 	public:
 		typedef const T&							value_assignment_t;
+		typedef T									default_value_t;
 		typedef T									value_t;
 		typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK>	self_t;
 
 		ParamValue(): mValue() {}
-		ParamValue(value_assignment_t other) : mValue(other) {}
+		ParamValue(const default_value_t& other) : mValue(other) {}
 
 		void setValue(value_assignment_t val)
 		{
@@ -699,6 +704,7 @@ namespace LLInitParam
 	{
 	public:
 		typedef const T&							value_assignment_t;
+		typedef T									default_value_t;
 		typedef T									value_t;
 		typedef ParamValue<T, NAME_VALUE_LOOKUP, IS_BLOCK>	self_t;
 
@@ -707,7 +713,7 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		ParamValue(value_assignment_t other)
+		ParamValue(const default_value_t& other)
 		:	T(other),
 			mValidated(false)
 		{}
@@ -762,11 +768,12 @@ namespace LLInitParam
 	{
 	public:
 		typedef const std::string&	value_assignment_t;
+		typedef std::string			default_value_t;
 		typedef std::string			value_t;
 		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, NOT_BLOCK>	self_t;
 
 		ParamValue(): mValue() {}
-		ParamValue(value_assignment_t other) : mValue(other) {}
+		ParamValue(const default_value_t& other) : mValue(other) {}
 
 		void setValue(value_assignment_t val)
 		{
@@ -808,8 +815,8 @@ namespace LLInitParam
 	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 	struct ParamIterator
 	{
-		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator;
-		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator;
+		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t> >::const_iterator		const_iterator;
+		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t> >::iterator			iterator;
 	};
 
 	// specialize for custom parsing/decomposition of specific classes
@@ -817,19 +824,20 @@ namespace LLInitParam
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
-			typename	VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
+			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t> >::value_t>
 	class TypedParam 
 	:	public Param, 
-		public ParamValue<T, NAME_VALUE_LOOKUP>
+		public ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t>
 	{
 	public:
-		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>		self_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP>											param_value_t;
-		typedef typename param_value_t::value_assignment_t									value_assignment_t;
+		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t;
+		typedef ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t>										param_value_t;
+		typedef typename param_value_t::value_assignment_t								value_assignment_t;
+		typedef typename param_value_t::default_value_t									default_value_t;
 
 		using param_value_t::operator();
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, const T& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr),
 			param_value_t(value)
 		{
@@ -862,6 +870,7 @@ namespace LLInitParam
 					if (parser.readValue(name))
 					{
 						// try to parse a per type named value
+
 						if (param_value_t::getValueFromName(name, typed_param.getValue()))
 						{
 							typed_param.setValueName(name);
@@ -974,16 +983,17 @@ namespace LLInitParam
 	template <typename T, typename NAME_VALUE_LOOKUP>
 	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK> 
 	:	public Param,
-		public ParamValue<T, NAME_VALUE_LOOKUP>
+	public ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t>
 	{
 	public:
-		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;
+		typedef ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t>				param_value_t;
 		typedef typename param_value_t::value_assignment_t		value_assignment_t;
+		typedef typename param_value_t::default_value_t			default_value_t;
 		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK>	self_t;
 
 		using param_value_t::operator();
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, const T& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr),
 			param_value_t(value)
 		{
@@ -1149,13 +1159,14 @@ namespace LLInitParam
 	{
 	public:
 		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t;
-		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>					param_value_t;
+		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP, typename IsBlock<VALUE_TYPE>::value_t>					param_value_t;
 		typedef typename std::vector<param_value_t>							container_t;
 		typedef const container_t&											value_assignment_t;
+		typedef container_t													default_value_t;
 
 		typedef typename param_value_t::value_t								value_t;
 		
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, const container_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), std::back_inserter(mValues));
@@ -1348,12 +1359,13 @@ namespace LLInitParam
 	{
 	public:
 		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_BLOCK>	self_t;
-		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>				param_value_t;
+		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP, typename IsBlock<VALUE_TYPE>::value_t>				param_value_t;
 		typedef typename std::vector<param_value_t>						container_t;
 		typedef const container_t&										value_assignment_t;
 		typedef typename param_value_t::value_t							value_t;
+		typedef container_t												default_value_t;
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, const container_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), back_inserter(mValues));
@@ -1617,13 +1629,14 @@ namespace LLInitParam
 		public:
 			friend class ChoiceBlock<DERIVED_BLOCK>;
 
-			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t;
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, typename IsBlock<T>::value_t>		super_t;
-			typedef typename super_t::value_assignment_t								value_assignment_t;
+			typedef Alternative<T, NAME_VALUE_LOOKUP>		self_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>	super_t;
+			typedef typename super_t::value_assignment_t	value_assignment_t;
+			typedef typename super_t::default_value_t		default_value_t;
 
 			using super_t::operator =;
 
-			explicit Alternative(const char* name = "", const T& val = defaultValue<T>())
+			explicit Alternative(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
 			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),
 				mOriginalValue(val)
 			{
@@ -1736,13 +1749,14 @@ namespace LLInitParam
 		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, typename IsBlock<T>::value_t>	super_t;
-			typedef typename super_t::value_assignment_t									value_assignment_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
+			typedef typename super_t::value_assignment_t		value_assignment_t;
+			typedef typename super_t::default_value_t			default_value_t;
 
 			using super_t::operator();
 			using super_t::operator =;
 			
-			explicit Optional(const char* name = "", const T& val = defaultValue<T>())
+			explicit Optional(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
 			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)
 			{
 				//#pragma message("Parsing LLInitParam::Block::Optional")
@@ -1765,15 +1779,16 @@ namespace LLInitParam
 		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, typename IsBlock<T>::value_t>		super_t;
-			typedef Mandatory<T, NAME_VALUE_LOOKUP>										self_t;
-			typedef typename super_t::value_assignment_t								value_assignment_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
+			typedef Mandatory<T, NAME_VALUE_LOOKUP>				self_t;
+			typedef typename super_t::value_assignment_t		value_assignment_t;
+			typedef typename super_t::default_value_t			default_value_t;
 
 			using super_t::operator();
 			using super_t::operator =;
 
 			// mandatory parameters require a name to be parseable
-			explicit Mandatory(const char* name = "", const T& val = defaultValue<T>())
+			explicit Mandatory(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
 			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)
 			{}
 
@@ -1801,12 +1816,12 @@ namespace LLInitParam
 		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
 		{
 		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, typename IsBlock<T>::value_t>	super_t;
-			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>							self_t;
-			typedef typename super_t::container_t									container_t;
-			typedef typename super_t::value_assignment_t							value_assignment_t;
-			typedef typename super_t::iterator										iterator;
-			typedef typename super_t::const_iterator								const_iterator;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;
+			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>	self_t;
+			typedef typename super_t::container_t			container_t;
+			typedef typename super_t::value_assignment_t	value_assignment_t;
+			typedef typename super_t::iterator				iterator;
+			typedef typename super_t::const_iterator		const_iterator;
 
 			explicit Multiple(const char* name = "")
 			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
@@ -1888,136 +1903,158 @@ namespace LLInitParam
 
 	};
 	
-	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
-	class BatchBlock
-	:	public Block<DERIVED_BLOCK, BASE_BLOCK>
+	template<typename T, typename BLOCK_T>
+	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_BLOCK>, TypeValues<BaseBlock::Lazy<T, BaseBlock::IS_BLOCK> >, BLOCK_T >, void>
 	{
-	public:
-		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
-		typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
-
-		BatchBlock()
-		{}
+		typedef IS_BLOCK value_t;
+	};
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
-		{
-			if (new_name)
-			{
-				// reset block
-				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
-			}
-			return super_t::deserializeBlock(p, name_stack_range, new_name);
-		}
+	template<typename T, typename BLOCK_T>
+	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_BLOCK>, TypeValues<BaseBlock::Lazy<T, BaseBlock::NOT_BLOCK> >, BLOCK_T >, void>
+	{
+		typedef NOT_BLOCK value_t;
+	};
 
-		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
-		{
-			if (overwrite)
-			{
-				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
-				// merge individual parameters into destination
-				return super_t::mergeBlock(super_t::getBlockDescriptor(), other, overwrite);
-			}
-			return false;
-		}
-	protected:
-		static const DERIVED_BLOCK& defaultBatchValue()
-		{
-			static DERIVED_BLOCK default_value;
-			return default_value;
-		}
+	template<typename T, typename BLOCK_IDENTIFIER>
+	struct IsBlock<ParamValue<BaseBlock::Batch<T>, TypeValues<BaseBlock::Batch<T> >, typename IsBlock<BaseBlock::Batch<T> >::value_t >, BLOCK_IDENTIFIER>
+	{
+		typedef typename IsBlock<ParamValue<T, TypeValues<T>, typename IsBlock<T>::value_t > >::value_t value_t;
 	};
 
-	// FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class
-	// and not the derived class with the actual params
-	template<typename DERIVED_BLOCK,
-			typename BASE_BLOCK,
-			typename NAME_VALUE_LOOKUP>
-	class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
-					NAME_VALUE_LOOKUP,
-					IS_BLOCK>
-	:	public NAME_VALUE_LOOKUP,
-		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
+	template<typename T, typename BLOCK_T>
+	class ParamValue <BaseBlock::Batch<T>,
+		TypeValues<BaseBlock::Batch<T> >,
+		BLOCK_T>
+	:	public TypeValues<T>
 	{
 	public:
-		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
-		typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>&	value_assignment_t;
-		typedef block_t value_t;
+		typedef ParamValue <BaseBlock::Batch<T>, TypeValues<BaseBlock::Batch<T> >, BLOCK_T> self_t;
+		typedef ParamValue<T, TypeValues<T>, typename IsBlock<T>::value_t > param_value_t;
+		typedef const T& value_assignment_t;
+		typedef T value_t;
+		typedef T default_value_t;
 
 		ParamValue()
-		:	block_t(),
+		:	mValue(),
 			mValidated(false)
 		{}
 
-		ParamValue(value_assignment_t other)
-		:	block_t(other),
+		ParamValue(const default_value_t& value)
+		:	mValue(value),
 			mValidated(false)
-		{
-		}
+		{}
 
 		void setValue(value_assignment_t val)
 		{
-			*this = val;
+			mValue.setValue(val);
 		}
 
-		value_assignment_t getValue() const
+		const T& getValue() const
 		{
-			return *this;
+			return mValue.getValue();
 		}
 
-		BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue()
+		T& getValue()
 		{
-			return *this;
+			return mValue;
 		}
 
 		operator value_assignment_t() const
 		{
-			return *this;
+			return mValue;
 		}
 
 		value_assignment_t operator()() const
 		{
+			return mValue;
+		}
+
+		void operator ()(const typename TypeValues<T>::name_t& name)
+		{
+			*this = name;
+		}
+
+		self_t& operator =(const typename TypeValues<T>::name_t& name)
+		{
+			mValue = name;
+
 			return *this;
 		}
 
-	protected:
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+		{
+			if (new_name)
+			{
+				// reset block
+				mValue = defaultBatchValue();
+			}
+			return mValue.deserializeBlock(p, name_stack_range, new_name);
+		}
+
+		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+		{
+			const BaseBlock* base_block = diff_block
+				? &(diff_block->mValue)
+				: NULL;
+			mValue.serializeBlock(p, name_stack, base_block);
+		}
+
+		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+		{
+			return mValue.inspectBlock(p, name_stack, min_count, max_count);
+		}
+
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+		{
+			if (overwrite)
+			{
+				mValue = defaultBatchValue();
+				return mValue.mergeBlock(block_data, source, overwrite);
+			}
+			return false;
+		}
+
+		bool validateBlock(bool emit_errors = true) const
+		{
+			return mValue.validateBlock(emit_errors);
+		}
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			return T::getBlockDescriptor();
+		}
+
+
 		mutable bool 	mValidated; // lazy validation flag
-	};
 
-	template<typename T, typename BLOCK_IDENTIFIER>
-	struct IsBlock<BaseBlock::Lazy<T, IS_BLOCK>, BLOCK_IDENTIFIER>
-	{
-		typedef IS_BLOCK value_t;
-	};
+	private:
+		static const T& defaultBatchValue()
+		{
+			static T default_value;
+			return default_value;
+		}
 
-	template<typename T, typename BLOCK_IDENTIFIER>
-	struct IsBlock<BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_IDENTIFIER>
-	{
-		typedef NOT_BLOCK value_t;
+		T	mValue;
 	};
 
-	//template<typename T, typename BLOCK_IDENTIFIER>
-	//struct IsBlock<BaseBlock::Lazy<T, void>, BLOCK_IDENTIFIER>
-	//{
-	//	typedef typename IsBlock<T>::value_t value_t;
-	//};
-
-	template<typename T>
+	template<typename T, typename BLOCK_T>
 	class ParamValue <BaseBlock::Lazy<T, IS_BLOCK>,
 					TypeValues<BaseBlock::Lazy<T, IS_BLOCK> >,
-					IS_BLOCK>
+					BLOCK_T> 
 	:	public TypeValues<T>
 	{
 	public:
-		typedef ParamValue <BaseBlock::Lazy<T, IS_BLOCK>, TypeValues<BaseBlock::Lazy<T, IS_BLOCK> >, IS_BLOCK> self_t;
+		typedef ParamValue <BaseBlock::Lazy<T, IS_BLOCK>, TypeValues<BaseBlock::Lazy<T, IS_BLOCK> >, BLOCK_T> self_t;
 		typedef const T& value_assignment_t;
 		typedef T value_t;
+		typedef BaseBlock::Lazy<T, IS_BLOCK> default_value_t;
 	
 		ParamValue()
 		:	mValue(),
 			mValidated(false)
 		{}
 
-		ParamValue(const BaseBlock::Lazy<T, IS_BLOCK>& other)
+		ParamValue(const default_value_t& other)
 		:	mValue(other),
 			mValidated(false)
 		{}
@@ -2052,6 +2089,21 @@ namespace LLInitParam
 			return mValue.get();
 		}
 
+		void operator ()(const typename TypeValues<T>::name_t& name)
+		{
+			*this = name;
+		}
+
+		self_t& operator =(const typename TypeValues<T>::name_t& name)
+		{
+			if (TypeValues<T>::getValueFromName(name, mValue.get()))
+			{
+				setValueName(name);
+			}
+
+			return *this;
+		}
+
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
 		{
 			return mValue.get().deserializeBlock(p, name_stack_range, new_name);
@@ -2074,7 +2126,7 @@ namespace LLInitParam
 
 		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
 		{
-			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(),  overwrite);
+			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source,  overwrite);
 		}
 
 		bool validateBlock(bool emit_errors = true) const
@@ -2094,6 +2146,79 @@ namespace LLInitParam
 		BaseBlock::Lazy<T, IS_BLOCK>	mValue;
 	};
 
+	template<typename T, typename BLOCK_T>
+	class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>,
+		TypeValues<BaseBlock::Lazy<T, NOT_BLOCK> >,
+		BLOCK_T>
+		:	public TypeValues<T>
+	{
+	public:
+		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, TypeValues<BaseBlock::Lazy<T, NOT_BLOCK> >, BLOCK_T> self_t;
+		typedef const T& value_assignment_t;
+		typedef T value_t;
+		typedef BaseBlock::Lazy<T, NOT_BLOCK> default_value_t;
+
+		ParamValue()
+		:	mValue(),
+			mValidated(false)
+		{}
+
+		ParamValue(const default_value_t& other)
+		:	mValue(other),
+			mValidated(false)
+		{}
+
+		ParamValue(const T& value)
+		:	mValue(value),
+			mValidated(false)
+		{}
+
+		void setValue(value_assignment_t val)
+		{
+			mValue.set(val);
+		}
+
+		value_assignment_t getValue() const
+		{
+			return mValue.get();
+		}
+
+		T& getValue()
+		{
+			return mValue.get();
+		}
+
+		operator value_assignment_t() const
+		{
+			return mValue.get();
+		}
+
+		value_assignment_t operator()() const
+		{
+			return mValue.get();
+		}
+
+		void operator ()(const typename TypeValues<T>::name_t& name)
+		{
+			*this = name;
+		}
+
+		self_t& operator =(const typename TypeValues<T>::name_t& name)
+		{
+			if (TypeValues<T>::getValueFromName(name, mValue.get()))
+			{
+				setValueName(name);
+			}
+
+			return *this;
+		}
+
+		mutable bool 	mValidated; // lazy validation flag
+
+	private:
+		BaseBlock::Lazy<T, NOT_BLOCK>	mValue;
+	};
+
 	template <>
 	class ParamValue <LLSD,
 					TypeValues<LLSD>,
@@ -2104,12 +2229,13 @@ namespace LLInitParam
 	public:
 		typedef ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK> self_t;
 		typedef const LLSD&	value_assignment_t;
+		typedef LLSD default_value_t;
 
 		ParamValue()
 		:	mValidated(false)
 		{}
 
-		ParamValue(value_assignment_t other)
+		ParamValue(const default_value_t& other)
 		:	mValue(other),
 			mValidated(false)
 		{}
@@ -2122,7 +2248,6 @@ namespace LLInitParam
 		operator value_assignment_t() const { return mValue; }
 		value_assignment_t operator()() const { return mValue; }
 		
-
 		// block param interface
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
@@ -2143,7 +2268,7 @@ namespace LLInitParam
 
 	template<typename T>
 	class CustomParamValue
-	:	public Block<ParamValue<T, TypeValues<T> > >,
+	:	public Block<ParamValue<T, TypeValues<T>, typename IsBlock<T>::value_t > >,
 		public TypeValues<T>
 	{
 	public:
@@ -2154,14 +2279,16 @@ namespace LLInitParam
 			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative
 		} EValueAge;
 
-		typedef ParamValue<T, TypeValues<T> >	derived_t;
+		typedef ParamValue<T, TypeValues<T>, typename IsBlock<T>::value_t >	derived_t;
 		typedef CustomParamValue<T>				self_t;
 		typedef Block<derived_t>				block_t;
 		typedef const T&						value_assignment_t;
+		typedef T								default_value_t;
 		typedef T								value_t;
+		typedef void							baseblock_base_class_t;
 
 
-		CustomParamValue(const T& value = T())
+		CustomParamValue(const default_value_t& value = T())
 		:	mValue(value),
 			mValueAge(VALUE_AUTHORITATIVE),
 			mValidated(false)
@@ -2316,6 +2443,20 @@ namespace LLInitParam
 			return getValue();
 		}
 
+		void operator ()(const typename TypeValues<T>::name_t& name)
+		{
+			*this = name;
+		}
+
+		self_t& operator =(const typename TypeValues<T>::name_t& name)
+		{
+			if (TypeValues<T>::getValueFromName(name, mValue))
+			{
+				setValueName(name);
+			}
+
+			return *this;
+		}
 	protected:
 
 		// use this from within updateValueFromBlock() to set the value without making it authoritative
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 3c89fa3aaf..ce8c8411ea 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -130,7 +130,7 @@ struct Any : public LLInitParam::Block<Any, Occurs>
 
 struct All : public LLInitParam::Block<All, Occurs>
 {
-	Multiple< Lazy<Element> > elements;
+	Multiple< Lazy<Element, IS_BLOCK> > elements;
 
 	All()
 	:	elements("element")
@@ -141,11 +141,11 @@ struct All : public LLInitParam::Block<All, Occurs>
 
 struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
 {
-	Alternative< Lazy<Element> >	element;
-	Alternative< Lazy<Group> >		group;
-	Alternative< Lazy<Choice> >		choice;
-	Alternative< Lazy<Sequence> >	sequence;
-	Alternative< Lazy<Any> >		any;
+	Alternative< Lazy<Element, IS_BLOCK> >	element;
+	Alternative< Lazy<Group, IS_BLOCK> >		group;
+	Alternative< Lazy<Choice, IS_BLOCK> >		choice;
+	Alternative< Lazy<Sequence, IS_BLOCK> >	sequence;
+	Alternative< Lazy<Any, IS_BLOCK> >		any;
 
 	Choice()
 	:	element("element"),
@@ -159,11 +159,11 @@ struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
 
 struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
 {
-	Alternative< Lazy<Element> >	element;
-	Alternative< Lazy<Group> >		group;
-	Alternative< Lazy<Choice> >		choice;
-	Alternative< Lazy<Sequence> >	sequence;
-	Alternative< Lazy<Any> >		any;
+	Alternative< Lazy<Element, IS_BLOCK> >	element;
+	Alternative< Lazy<Group, IS_BLOCK> >		group;
+	Alternative< Lazy<Choice, IS_BLOCK> >		choice;
+	Alternative< Lazy<Sequence, IS_BLOCK> >	sequence;
+	Alternative< Lazy<Any, IS_BLOCK> >		any;
 };
 
 struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
@@ -248,7 +248,7 @@ struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>
 	Optional<bool>					mixed;
 
 	Multiple<Attribute>				attribute;
-	Multiple< Lazy<Element> >			elements;
+	Multiple< Lazy<Element, IS_BLOCK > >			elements;
 
 	ComplexType()
 	:	name("name"),
@@ -343,7 +343,7 @@ void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, cons
 {
 	Schema schema(xml_namespace);
 
-	schema.root_element.name = type_name;
+	schema.root_element.super_t::param_value_t::name = type_name;
 	Choice& choice = schema.root_element.complexType.choice;
 
 	choice.minOccurs = 0;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f47cce9a4d..c483aa58c9 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -248,7 +248,7 @@ struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarColli
 
 struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
 {
-	Alternative<Lazy<struct LLVOAvatarBoneInfo> >	bone;
+	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_BLOCK> >	bone;
 	Alternative<LLVOAvatarCollisionVolumeInfo>		collision_volume;
 
 	LLVOAvatarChildJoint()
-- 
cgit v1.2.3


From fc780921c1e3c411014fe22a31a0fe4d0fd0b2cf Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 12 Apr 2012 18:14:00 -0700
Subject: attempted fix of gcc build

---
 indra/llxuixml/llinitparam.h | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 0c53b36bad..75c09125eb 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -399,7 +399,7 @@ namespace LLInitParam
 		{};
 
 		//TODO: implement in terms of owned_ptr
-		template<typename T, typename BLOCK_T = IsBlock<T>::value_t >
+		template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
 		class Lazy
 		{
 		public:
@@ -815,8 +815,8 @@ namespace LLInitParam
 	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 	struct ParamIterator
 	{
-		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t> >::const_iterator		const_iterator;
-		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t> >::iterator			iterator;
+		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator;
+		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator;
 	};
 
 	// specialize for custom parsing/decomposition of specific classes
@@ -824,14 +824,14 @@ namespace LLInitParam
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
-			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t> >::value_t>
+			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value_t>
 	class TypedParam 
 	:	public Param, 
-		public ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t>
+		public ParamValue<T, NAME_VALUE_LOOKUP>
 	{
 	public:
 		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t>										param_value_t;
+		typedef ParamValue<T, NAME_VALUE_LOOKUP>										param_value_t;
 		typedef typename param_value_t::value_assignment_t								value_assignment_t;
 		typedef typename param_value_t::default_value_t									default_value_t;
 
@@ -983,10 +983,10 @@ namespace LLInitParam
 	template <typename T, typename NAME_VALUE_LOOKUP>
 	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK> 
 	:	public Param,
-	public ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t>
+	public ParamValue<T, NAME_VALUE_LOOKUP>
 	{
 	public:
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, typename IsBlock<T>::value_t>				param_value_t;
+		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;
 		typedef typename param_value_t::value_assignment_t		value_assignment_t;
 		typedef typename param_value_t::default_value_t			default_value_t;
 		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK>	self_t;
@@ -1918,7 +1918,7 @@ namespace LLInitParam
 	template<typename T, typename BLOCK_IDENTIFIER>
 	struct IsBlock<ParamValue<BaseBlock::Batch<T>, TypeValues<BaseBlock::Batch<T> >, typename IsBlock<BaseBlock::Batch<T> >::value_t >, BLOCK_IDENTIFIER>
 	{
-		typedef typename IsBlock<ParamValue<T, TypeValues<T>, typename IsBlock<T>::value_t > >::value_t value_t;
+		typedef typename IsBlock<ParamValue<T, TypeValues<T> > >::value_t value_t;
 	};
 
 	template<typename T, typename BLOCK_T>
@@ -1929,7 +1929,7 @@ namespace LLInitParam
 	{
 	public:
 		typedef ParamValue <BaseBlock::Batch<T>, TypeValues<BaseBlock::Batch<T> >, BLOCK_T> self_t;
-		typedef ParamValue<T, TypeValues<T>, typename IsBlock<T>::value_t > param_value_t;
+		typedef ParamValue<T, TypeValues<T> > param_value_t;
 		typedef const T& value_assignment_t;
 		typedef T value_t;
 		typedef T default_value_t;
@@ -2268,7 +2268,7 @@ namespace LLInitParam
 
 	template<typename T>
 	class CustomParamValue
-	:	public Block<ParamValue<T, TypeValues<T>, typename IsBlock<T>::value_t > >,
+	:	public Block<ParamValue<T, TypeValues<T> > >,
 		public TypeValues<T>
 	{
 	public:
@@ -2279,7 +2279,7 @@ namespace LLInitParam
 			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative
 		} EValueAge;
 
-		typedef ParamValue<T, TypeValues<T>, typename IsBlock<T>::value_t >	derived_t;
+		typedef ParamValue<T, TypeValues<T> >	derived_t;
 		typedef CustomParamValue<T>				self_t;
 		typedef Block<derived_t>				block_t;
 		typedef const T&						value_assignment_t;
-- 
cgit v1.2.3


From 61d202a15d70ec56e46bca2edadd49cfd5cbb956 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 13 Apr 2012 11:48:37 -0700
Subject: renamed Lazy to Atomic

---
 indra/llui/llloadingindicator.h |  2 +-
 indra/llxuixml/llinitparam.h    | 19 +++++++++----------
 2 files changed, 10 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
index 4998a57263..ffcb329f42 100644
--- a/indra/llui/llloadingindicator.h
+++ b/indra/llui/llloadingindicator.h
@@ -63,7 +63,7 @@ public:
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
 		Optional<F32>				images_per_sec;
-		Optional<Batch<Images> >	images;
+		Optional<Atomic<Images> >	images;
 
 		Params()
 		:	images_per_sec("images_per_sec", 1.0f),
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 75c09125eb..dcbbf9f0a7 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -395,7 +395,7 @@ namespace LLInitParam
 		typedef LLInitParam::NOT_BLOCK NOT_BLOCK;
 
 		template<typename T>
-		class Batch
+		class Atomic
 		{};
 
 		//TODO: implement in terms of owned_ptr
@@ -1916,19 +1916,19 @@ namespace LLInitParam
 	};
 
 	template<typename T, typename BLOCK_IDENTIFIER>
-	struct IsBlock<ParamValue<BaseBlock::Batch<T>, TypeValues<BaseBlock::Batch<T> >, typename IsBlock<BaseBlock::Batch<T> >::value_t >, BLOCK_IDENTIFIER>
+	struct IsBlock<ParamValue<BaseBlock::Atomic<T>, TypeValues<BaseBlock::Atomic<T> >, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER>
 	{
 		typedef typename IsBlock<ParamValue<T, TypeValues<T> > >::value_t value_t;
 	};
 
 	template<typename T, typename BLOCK_T>
-	class ParamValue <BaseBlock::Batch<T>,
-		TypeValues<BaseBlock::Batch<T> >,
+	class ParamValue <BaseBlock::Atomic<T>,
+		TypeValues<BaseBlock::Atomic<T> >,
 		BLOCK_T>
 	:	public TypeValues<T>
 	{
 	public:
-		typedef ParamValue <BaseBlock::Batch<T>, TypeValues<BaseBlock::Batch<T> >, BLOCK_T> self_t;
+		typedef ParamValue <BaseBlock::Atomic<T>, TypeValues<BaseBlock::Atomic<T> >, BLOCK_T> self_t;
 		typedef ParamValue<T, TypeValues<T> > param_value_t;
 		typedef const T& value_assignment_t;
 		typedef T value_t;
@@ -1985,8 +1985,7 @@ namespace LLInitParam
 		{
 			if (new_name)
 			{
-				// reset block
-				mValue = defaultBatchValue();
+				resetToDefault();
 			}
 			return mValue.deserializeBlock(p, name_stack_range, new_name);
 		}
@@ -2008,7 +2007,7 @@ namespace LLInitParam
 		{
 			if (overwrite)
 			{
-				mValue = defaultBatchValue();
+				resetToDefault();
 				return mValue.mergeBlock(block_data, source, overwrite);
 			}
 			return false;
@@ -2028,10 +2027,10 @@ namespace LLInitParam
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
-		static const T& defaultBatchValue()
+		void resetToDefault()
 		{
 			static T default_value;
-			return default_value;
+			mValue = default_value;
 		}
 
 		T	mValue;
-- 
cgit v1.2.3


From 5b4990ce6a7fbf5d757e86362d134061fa54a1e9 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 13 Apr 2012 12:51:34 -0700
Subject: more LLInitParam cleanup cleaned up typedefs, and hid those that
 aren't part of the interface

---
 indra/llxuixml/llinitparam.h   | 387 ++++++++++++++++++++---------------------
 indra/llxuixml/llxuiparser.cpp |   2 +-
 2 files changed, 193 insertions(+), 196 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index dcbbf9f0a7..09617209a8 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -387,111 +387,112 @@ namespace LLInitParam
 		typedef IS_BLOCK value_t;
 	};
 
-	class BaseBlock
+	//TODO: implement in terms of owned_ptr
+	template<typename T>
+	class LazyValue
 	{
 	public:
-		// lift block tags into baseblock namespace so derived classes do not need to qualify them
-		typedef LLInitParam::IS_BLOCK IS_BLOCK;
-		typedef LLInitParam::NOT_BLOCK NOT_BLOCK;
+		LazyValue()
+			:	mPtr(NULL)
+		{}
 
-		template<typename T>
-		class Atomic
-		{};
+		~LazyValue()
+		{
+			delete mPtr;
+		}
 
-		//TODO: implement in terms of owned_ptr
-		template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
-		class Lazy
+		LazyValue(const T& value)
 		{
-		public:
-			Lazy()
-			:	mPtr(NULL)
-			{}
+			mPtr = new T(value);
+		}
 
-			~Lazy()
+		LazyValue(const LazyValue& other)
+		{
+			if (other.mPtr)
 			{
-				delete mPtr;
+				mPtr = new T(*other.mPtr);
 			}
-
-			Lazy(const T& value)
+			else
 			{
-				mPtr = new T(value);
+				mPtr = NULL;
 			}
+		}
 
-			Lazy(const Lazy& other)
+		LazyValue& operator = (const LazyValue& other)
+		{
+			if (other.mPtr)
 			{
-				if (other.mPtr)
-				{
-					mPtr = new T(*other.mPtr);
-				}
-				else
-				{
-					mPtr = NULL;
-				}
+				mPtr = new T(*other.mPtr);
 			}
-
-			Lazy& operator = (const Lazy& other)
+			else
 			{
-				if (other.mPtr)
-				{
-					mPtr = new T(*other.mPtr);
-				}
-				else
-				{
-					mPtr = NULL;
-				}
-				return *this;
+				mPtr = NULL;
 			}
+			return *this;
+		}
 
-			bool operator==(const Lazy& other) const
-			{
-				if (empty() || other.empty()) return false;
-				return *mPtr == *other.mPtr;
-			}
+		bool operator==(const LazyValue& other) const
+		{
+			if (empty() || other.empty()) return false;
+			return *mPtr == *other.mPtr;
+		}
 
-			bool empty() const
-			{
-				return mPtr == NULL;
-			}
+		bool empty() const
+		{
+			return mPtr == NULL;
+		}
 
-			void set(const T& other)
-			{
-				delete mPtr;
-				mPtr = new T(other);
-			}
+		void set(const T& other)
+		{
+			delete mPtr;
+			mPtr = new T(other);
+		}
 
-			const T& get() const
-			{
-				return *ensureInstance();
-			}
+		const T& get() const
+		{
+			return *ensureInstance();
+		}
 
-			T& get()
-			{
-				return *ensureInstance();
-			}
+		T& get()
+		{
+			return *ensureInstance();
+		}
 
-			operator const T&() const
-			{ 
-				return get(); 
-			}
+		operator const T&() const
+		{ 
+			return get(); 
+		}
 
-		private: 
-			// lazily allocate an instance of T
-			T* ensureInstance() const
+	private: 
+		// lazily allocate an instance of T
+		T* ensureInstance() const
+		{
+			if (mPtr == NULL)
 			{
-				if (mPtr == NULL)
-				{
-					mPtr = new T();
-				}
-				return mPtr;
+				mPtr = new T();
 			}
+			return mPtr;
+		}
 
-		private:
-			// if you get a compilation error with this, that means you are using a forward declared struct for T
-			// unfortunately, the type traits we rely on don't work with forward declared typed
-			//static const int dummy = sizeof(T);
+	private:
 
-			mutable T* mPtr;
-		};
+		mutable T* mPtr;
+	};
+
+	class BaseBlock
+	{
+	public:
+		// lift block tags into baseblock namespace so derived classes do not need to qualify them
+		typedef LLInitParam::IS_BLOCK IS_BLOCK;
+		typedef LLInitParam::NOT_BLOCK NOT_BLOCK;
+
+		template<typename T>
+		class Atomic
+		{};
+
+		template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
+		class Lazy
+		{};
 
 		// "Multiple" constraint types, put here in root class to avoid ambiguity during use
 		struct AnyAmount
@@ -644,21 +645,21 @@ namespace LLInitParam
 	template<typename T, typename NAME_VALUE_LOOKUP, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
 	class ParamValue : public NAME_VALUE_LOOKUP
 	{
+		typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK>	self_t;
+
 	public:
-		typedef const T&							value_assignment_t;
 		typedef T									default_value_t;
 		typedef T									value_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK>	self_t;
 
 		ParamValue(): mValue() {}
 		ParamValue(const default_value_t& other) : mValue(other) {}
 
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
 			mValue = val;
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
 			return mValue;
 		}
@@ -668,12 +669,12 @@ namespace LLInitParam
 			return mValue;
 		}
 
-		operator value_assignment_t() const
+		operator const value_t&() const
 		{
 			return mValue;
 		}
 
-		value_assignment_t operator()() const
+		const value_t& operator()() const
 		{
 			return mValue;
 		}
@@ -702,11 +703,10 @@ namespace LLInitParam
 	:	public T,
 		public NAME_VALUE_LOOKUP
 	{
+		typedef ParamValue<T, NAME_VALUE_LOOKUP, IS_BLOCK>	self_t;
 	public:
-		typedef const T&							value_assignment_t;
 		typedef T									default_value_t;
 		typedef T									value_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, IS_BLOCK>	self_t;
 
 		ParamValue() 
 		:	T(),
@@ -718,12 +718,12 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
 			*this = val;
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
 			return *this;
 		}
@@ -733,12 +733,12 @@ namespace LLInitParam
 			return *this;
 		}
 
-		operator value_assignment_t() const
+		operator const value_t&() const
 		{
 			return *this;
 		}
 		
-		value_assignment_t operator()() const
+		const value_t& operator()() const
 		{
 			return *this;
 		}
@@ -766,16 +766,15 @@ namespace LLInitParam
 	class ParamValue<std::string, NAME_VALUE_LOOKUP, NOT_BLOCK>
 	: public NAME_VALUE_LOOKUP
 	{
+		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, NOT_BLOCK>	self_t;
 	public:
-		typedef const std::string&	value_assignment_t;
 		typedef std::string			default_value_t;
 		typedef std::string			value_t;
-		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, NOT_BLOCK>	self_t;
 
 		ParamValue(): mValue() {}
 		ParamValue(const default_value_t& other) : mValue(other) {}
 
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
 			if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue))
 			{
@@ -787,7 +786,7 @@ namespace LLInitParam
 			}
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
 			return mValue;
 		}
@@ -797,12 +796,12 @@ namespace LLInitParam
 			return mValue;
 		}
 
-		operator value_assignment_t() const
+		operator const value_t&() const
 		{
 			return mValue;
 		}
 
-		value_assignment_t operator()() const
+		const value_t& operator()() const
 		{
 			return mValue;
 		}
@@ -829,12 +828,12 @@ namespace LLInitParam
 	:	public Param, 
 		public ParamValue<T, NAME_VALUE_LOOKUP>
 	{
-	public:
+	protected:
 		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t;
 		typedef ParamValue<T, NAME_VALUE_LOOKUP>										param_value_t;
-		typedef typename param_value_t::value_assignment_t								value_assignment_t;
+		typedef typename param_value_t::value_t											value_t;
 		typedef typename param_value_t::default_value_t									default_value_t;
-
+	public:
 		using param_value_t::operator();
 
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
@@ -930,7 +929,7 @@ namespace LLInitParam
 			}
 		}
 
-		void set(value_assignment_t val, bool flag_as_provided = true)
+		void set(const value_t& val, bool flag_as_provided = true)
 		{
 			param_value_t::clearValueName();
 			setValue(val);
@@ -985,12 +984,12 @@ namespace LLInitParam
 	:	public Param,
 	public ParamValue<T, NAME_VALUE_LOOKUP>
 	{
-	public:
-		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;
-		typedef typename param_value_t::value_assignment_t		value_assignment_t;
-		typedef typename param_value_t::default_value_t			default_value_t;
+	protected:
+		typedef ParamValue<T, NAME_VALUE_LOOKUP>					param_value_t;
+		typedef typename param_value_t::value_t						value_t;
+		typedef typename param_value_t::default_value_t				default_value_t;
 		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK>	self_t;
-
+	public:
 		using param_value_t::operator();
 
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
@@ -1078,7 +1077,7 @@ namespace LLInitParam
 		}
 
 		// assign block contents to this param-that-is-a-block
-		void set(value_assignment_t val, bool flag_as_provided = true)
+		void set(const value_t& val, bool flag_as_provided = true)
 		{
 			setValue(val);
 			param_value_t::clearValueName();
@@ -1157,15 +1156,14 @@ namespace LLInitParam
 	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> 
 	:	public Param
 	{
-	public:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t;
-		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP, typename IsBlock<VALUE_TYPE>::value_t>					param_value_t;
-		typedef typename std::vector<param_value_t>							container_t;
-		typedef const container_t&											value_assignment_t;
-		typedef container_t													default_value_t;
-
-		typedef typename param_value_t::value_t								value_t;
+	protected:
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>							self_t;
+		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP, typename IsBlock<VALUE_TYPE>::value_t>	param_value_t;
+		typedef typename std::vector<param_value_t>													container_t;
+		typedef container_t																			default_value_t;
+		typedef typename param_value_t::value_t														value_t;
 		
+	public:
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
@@ -1259,7 +1257,7 @@ namespace LLInitParam
 			}
 		}
 
-		void set(value_assignment_t val, bool flag_as_provided = true)
+		void set(const container_t& val, bool flag_as_provided = true)
 		{
 			mValues = val;
 			setProvided(flag_as_provided);
@@ -1293,9 +1291,9 @@ namespace LLInitParam
 		}
 
 		// implicit conversion
-		operator value_assignment_t() const { return mValues; } 
+		operator const container_t&() const { return mValues; } 
 		// explicit conversion		
-		value_assignment_t operator()() const { return mValues; }
+		const container_t& operator()() const { return mValues; }
 
 		typedef typename container_t::iterator iterator;
 		typedef typename container_t::const_iterator const_iterator;
@@ -1357,14 +1355,15 @@ namespace LLInitParam
 	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_BLOCK> 
 	:	public Param
 	{
+	protected:
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_BLOCK>							self_t;
+		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP, typename IsBlock<VALUE_TYPE>::value_t>	param_value_t;
+		typedef typename std::vector<param_value_t>													container_t;
+		typedef typename param_value_t::value_t														value_t;
+		typedef container_t																			default_value_t;
+		typedef typename container_t::iterator														iterator;
+		typedef typename container_t::const_iterator												const_iterator;
 	public:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_BLOCK>	self_t;
-		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP, typename IsBlock<VALUE_TYPE>::value_t>				param_value_t;
-		typedef typename std::vector<param_value_t>						container_t;
-		typedef const container_t&										value_assignment_t;
-		typedef typename param_value_t::value_t							value_t;
-		typedef container_t												default_value_t;
-
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
@@ -1453,7 +1452,7 @@ namespace LLInitParam
 			param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);
 		}
 
-		void set(value_assignment_t val, bool flag_as_provided = true)
+		void set(const container_t& val, bool flag_as_provided = true)
 		{
 			mValues = val;
 			setProvided(flag_as_provided);
@@ -1485,12 +1484,10 @@ namespace LLInitParam
 		}
 
 		// implicit conversion
-		operator value_assignment_t() const { return mValues; } 
+		operator const container_t&() const { return mValues; } 
 		// explicit conversion
-		value_assignment_t operator()() const { return mValues; }
+		const container_t& operator()() const { return mValues; }
 
-		typedef typename container_t::iterator iterator;
-		typedef typename container_t::const_iterator const_iterator;
 		iterator begin() { return mValues.begin(); }
 		iterator end() { return mValues.end(); }
 		const_iterator begin() const { return mValues.begin(); }
@@ -1626,14 +1623,13 @@ namespace LLInitParam
 		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 		class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
-		public:
-			friend class ChoiceBlock<DERIVED_BLOCK>;
-
-			typedef Alternative<T, NAME_VALUE_LOOKUP>		self_t;
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>	super_t;
-			typedef typename super_t::value_assignment_t	value_assignment_t;
+			typedef typename super_t::value_t				value_t;
 			typedef typename super_t::default_value_t		default_value_t;
 
+		public:
+			friend class ChoiceBlock<DERIVED_BLOCK>;
+
 			using super_t::operator =;
 
 			explicit Alternative(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
@@ -1656,27 +1652,27 @@ namespace LLInitParam
 				static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
 			}
 
-			void chooseAs(value_assignment_t val)
+			void chooseAs(const value_t& val)
 			{
 				super_t::set(val);
 			}
 
-			void operator =(value_assignment_t val)
+			void operator =(const value_t& val)
 			{
 				super_t::set(val);
 			}
 
-			void operator()(typename super_t::value_assignment_t val) 
+			void operator()(typename const value_t& val) 
 			{ 
 				super_t::set(val);
 			}
 
-			operator value_assignment_t() const 
+			operator const value_t&() const 
 			{
 				return (*this)();
 			} 
 
-			value_assignment_t operator()() const 
+			const value_t& operator()() const 
 			{ 
 				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
 				{
@@ -1691,7 +1687,7 @@ namespace LLInitParam
 			}
 		
 		private:
-			T			mOriginalValue;
+			default_value_t mOriginalValue;
 		};
 
 	public:
@@ -1715,6 +1711,8 @@ namespace LLInitParam
 	:	public BASE_BLOCK
 	{
 		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	self_t;
+
+	protected:
 		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	block_t;
 
 	public:
@@ -1748,11 +1746,11 @@ namespace LLInitParam
 		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
-		public:
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
-			typedef typename super_t::value_assignment_t		value_assignment_t;
+			typedef typename super_t::value_t					value_t;
 			typedef typename super_t::default_value_t			default_value_t;
 
+		public:
 			using super_t::operator();
 			using super_t::operator =;
 			
@@ -1762,13 +1760,13 @@ namespace LLInitParam
 				//#pragma message("Parsing LLInitParam::Block::Optional")
 			}
 
-			Optional& operator =(value_assignment_t val)
+			Optional& operator =(const value_t& val)
 			{
 				set(val);
 				return *this;
 			}
 
-			DERIVED_BLOCK& operator()(value_assignment_t val)
+			DERIVED_BLOCK& operator()(const value_t& val)
 			{
 				super_t::set(val);
 				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1778,12 +1776,12 @@ namespace LLInitParam
 		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
-		public:
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
 			typedef Mandatory<T, NAME_VALUE_LOOKUP>				self_t;
-			typedef typename super_t::value_assignment_t		value_assignment_t;
+			typedef typename super_t::value_t					value_t;
 			typedef typename super_t::default_value_t			default_value_t;
 
+		public:
 			using super_t::operator();
 			using super_t::operator =;
 
@@ -1792,13 +1790,13 @@ namespace LLInitParam
 			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)
 			{}
 
-			Mandatory& operator =(value_assignment_t val)
+			Mandatory& operator =(const value_t& val)
 			{
 				set(val);
 				return *this;
 			}
 
-			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+			DERIVED_BLOCK& operator()(typename const value_t& val)
 			{
 				super_t::set(val);
 				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1815,25 +1813,27 @@ namespace LLInitParam
 		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
 		{
-		public:
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;
 			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>	self_t;
 			typedef typename super_t::container_t			container_t;
-			typedef typename super_t::value_assignment_t	value_assignment_t;
-			typedef typename super_t::iterator				iterator;
-			typedef typename super_t::const_iterator		const_iterator;
+			typedef typename super_t::value_t				value_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;
+
+		public:
+			typedef typename super_t::iterator			iterator;
+			typedef typename super_t::const_iterator	const_iterator;
 
 			explicit Multiple(const char* name = "")
 			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
 			{}
 
-			Multiple& operator =(value_assignment_t val)
+			Multiple& operator =(const container_t& val)
 			{
 				set(val);
 				return *this;
 			}
 
-			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+			DERIVED_BLOCK& operator()(typename const container_t& val)
 			{
 				super_t::set(val);
 				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1893,7 +1893,7 @@ namespace LLInitParam
 	protected:
 		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, typename is_block>
 		void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param, 
-			typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
+			const typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_t& value)
 		{
 			if (!param.isProvided())
 			{
@@ -1927,12 +1927,11 @@ namespace LLInitParam
 		BLOCK_T>
 	:	public TypeValues<T>
 	{
-	public:
 		typedef ParamValue <BaseBlock::Atomic<T>, TypeValues<BaseBlock::Atomic<T> >, BLOCK_T> self_t;
-		typedef ParamValue<T, TypeValues<T> > param_value_t;
-		typedef const T& value_assignment_t;
-		typedef T value_t;
-		typedef T default_value_t;
+
+	public:
+		typedef T								value_t;
+		typedef T								default_value_t;
 
 		ParamValue()
 		:	mValue(),
@@ -1944,7 +1943,7 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
 			mValue.setValue(val);
 		}
@@ -1959,12 +1958,12 @@ namespace LLInitParam
 			return mValue;
 		}
 
-		operator value_assignment_t() const
+		operator const value_t&() const
 		{
 			return mValue;
 		}
 
-		value_assignment_t operator()() const
+		const value_t& operator()() const
 		{
 			return mValue;
 		}
@@ -2042,11 +2041,11 @@ namespace LLInitParam
 					BLOCK_T> 
 	:	public TypeValues<T>
 	{
-	public:
 		typedef ParamValue <BaseBlock::Lazy<T, IS_BLOCK>, TypeValues<BaseBlock::Lazy<T, IS_BLOCK> >, BLOCK_T> self_t;
-		typedef const T& value_assignment_t;
-		typedef T value_t;
-		typedef BaseBlock::Lazy<T, IS_BLOCK> default_value_t;
+
+	public:
+		typedef T				value_t;
+		typedef LazyValue<T>	default_value_t;
 	
 		ParamValue()
 		:	mValue(),
@@ -2063,12 +2062,12 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
 			mValue.set(val);
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
 			return mValue.get();
 		}
@@ -2078,12 +2077,12 @@ namespace LLInitParam
 			return mValue.get();
 		}
 
-		operator value_assignment_t() const
+		operator const value_t&() const
 		{
 			return mValue.get();
 		}
 
-		value_assignment_t operator()() const
+		const value_t& operator()() const
 		{
 			return mValue.get();
 		}
@@ -2142,7 +2141,7 @@ namespace LLInitParam
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
-		BaseBlock::Lazy<T, IS_BLOCK>	mValue;
+		LazyValue<T>	mValue;
 	};
 
 	template<typename T, typename BLOCK_T>
@@ -2151,11 +2150,11 @@ namespace LLInitParam
 		BLOCK_T>
 		:	public TypeValues<T>
 	{
-	public:
 		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, TypeValues<BaseBlock::Lazy<T, NOT_BLOCK> >, BLOCK_T> self_t;
-		typedef const T& value_assignment_t;
-		typedef T value_t;
-		typedef BaseBlock::Lazy<T, NOT_BLOCK> default_value_t;
+
+	public:
+		typedef T				value_t;
+		typedef LazyValue<T>	default_value_t;
 
 		ParamValue()
 		:	mValue(),
@@ -2172,12 +2171,12 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
 			mValue.set(val);
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
 			return mValue.get();
 		}
@@ -2187,12 +2186,12 @@ namespace LLInitParam
 			return mValue.get();
 		}
 
-		operator value_assignment_t() const
+		operator const value_t&() const
 		{
 			return mValue.get();
 		}
 
-		value_assignment_t operator()() const
+		const value_t& operator()() const
 		{
 			return mValue.get();
 		}
@@ -2215,7 +2214,7 @@ namespace LLInitParam
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
-		BaseBlock::Lazy<T, NOT_BLOCK>	mValue;
+		LazyValue<T>	mValue;
 	};
 
 	template <>
@@ -2226,9 +2225,8 @@ namespace LLInitParam
 		public BaseBlock
 	{
 	public:
-		typedef ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK> self_t;
-		typedef const LLSD&	value_assignment_t;
-		typedef LLSD default_value_t;
+		typedef LLSD			value_t;
+		typedef LLSD			default_value_t;
 
 		ParamValue()
 		:	mValidated(false)
@@ -2239,13 +2237,13 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		void setValue(value_assignment_t val) { mValue = val; }
+		void setValue(const value_t& val) { mValue = val; }
 
-		value_assignment_t getValue() const { return mValue; }
+		const value_t& getValue() const { return mValue; }
 		LLSD& getValue() { return mValue; }
 
-		operator value_assignment_t() const { return mValue; }
-		value_assignment_t operator()() const { return mValue; }
+		operator const value_t&() const { return mValue; }
+		const value_t& operator()() const { return mValue; }
 		
 		// block param interface
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
@@ -2281,7 +2279,6 @@ namespace LLInitParam
 		typedef ParamValue<T, TypeValues<T> >	derived_t;
 		typedef CustomParamValue<T>				self_t;
 		typedef Block<derived_t>				block_t;
-		typedef const T&						value_assignment_t;
 		typedef T								default_value_t;
 		typedef T								value_t;
 		typedef void							baseblock_base_class_t;
@@ -2410,7 +2407,7 @@ namespace LLInitParam
 			}
 		}
 			
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
 			derived_t& typed_param = static_cast<derived_t&>(*this);
 			// set param version number to be up to date, so we ignore block contents
@@ -2420,7 +2417,7 @@ namespace LLInitParam
 			static_cast<derived_t*>(this)->updateBlockFromValue(false);
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
 			validateBlock(true);
 			return mValue;
@@ -2432,12 +2429,12 @@ namespace LLInitParam
 			return mValue;
 		}
 
-		operator value_assignment_t() const
+		operator const value_t&() const
 		{
 			return getValue();
 		}
 
-		value_assignment_t operator()() const
+		const value_t& operator()() const
 		{
 			return getValue();
 		}
@@ -2459,7 +2456,7 @@ namespace LLInitParam
 	protected:
 
 		// use this from within updateValueFromBlock() to set the value without making it authoritative
-		void updateValue(value_assignment_t value)
+		void updateValue(const value_t& value)
 		{
 			mValue = value;
 		}
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index ce8c8411ea..2e1f8888d0 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -343,7 +343,7 @@ void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, cons
 {
 	Schema schema(xml_namespace);
 
-	schema.root_element.super_t::param_value_t::name = type_name;
+	schema.root_element.name = type_name;
 	Choice& choice = schema.root_element.complexType.choice;
 
 	choice.minOccurs = 0;
-- 
cgit v1.2.3


From 3fdcb8751a1f36dbce9d7a3fd1d785160d356d3a Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Fri, 13 Apr 2012 23:31:01 +0300
Subject: CHUI-91 FIXED Moved block list to a separate People floater tab.

---
 indra/newview/llchathistory.cpp                    |  3 ++-
 indra/newview/llfloaterpreference.cpp              |  3 ++-
 indra/newview/llfloatersidepanelcontainer.cpp      |  5 +---
 indra/newview/llpanelblockedlist.cpp               | 16 ++-----------
 indra/newview/llpanelblockedlist.h                 |  1 -
 indra/newview/llpanelpeople.cpp                    | 18 +++++---------
 .../skins/default/xui/en/floater_people.xml        | 10 ++------
 .../default/xui/en/menu_people_friends_view.xml    |  4 ----
 .../default/xui/en/menu_people_nearby_view.xml     |  9 -------
 .../default/xui/en/menu_people_recent_view.xml     |  4 ----
 .../default/xui/en/panel_block_list_sidetray.xml   | 28 ++--------------------
 .../newview/skins/default/xui/en/panel_people.xml  | 28 +++++++++++++++++++++-
 12 files changed, 44 insertions(+), 85 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index f530d10ddc..5bdfb5adbc 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -143,7 +143,8 @@ public:
 		{
 			LLMuteList::getInstance()->add(LLMute(getAvatarId(), mFrom, LLMute::OBJECT));
 
-			LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with("blocked_to_select", getAvatarId()));
+			LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+				LLSD().with("people_panel_tab_name", "blocked_panel").with("blocked_to_select", getAvatarId()));
 		}
 	}
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index a333989e7e..caf4a305b3 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1501,7 +1501,8 @@ void LLFloaterPreference::onChangeMaturity()
 // but the UI for this will still be enabled
 void LLFloaterPreference::onClickBlockList()
 {
-	LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
+	LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+		LLSD().with("people_panel_tab_name", "blocked_panel"));
 }
 
 void LLFloaterPreference::onClickProxySettings()
diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp
index be7a53491d..977fdbbc46 100644
--- a/indra/newview/llfloatersidepanelcontainer.cpp
+++ b/indra/newview/llfloatersidepanelcontainer.cpp
@@ -66,10 +66,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na
 	LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent());
 	if (container)
 	{
-		LLSD new_params = params;
-		new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name;
-		container->onOpen(new_params);
-
+		container->openPanel(panel_name, params);
 		panel = container->getCurrentPanel();
 	}
 	else if ((panel = dynamic_cast<LLPanel*>(view)) != NULL)
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 5c85ec438c..d2dff63948 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -69,8 +69,6 @@ BOOL LLPanelBlockedList::postBuild()
 	mBlockedList = getChild<LLScrollListCtrl>("blocked");
 	mBlockedList->setCommitOnSelectionChange(TRUE);
 
-	childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL);
-
 	LLMuteList::getInstance()->addObserver(this);
 	
 	refreshBlockedList();
@@ -99,7 +97,8 @@ void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)
 
 void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)
 {
-	LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with(BLOCKED_PARAM_NAME, idToSelect));
+	LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+		LLSD().with("people_panel_tab_name", "blocked_panel").with(BLOCKED_PARAM_NAME, idToSelect));
 }
 
 
@@ -130,17 +129,6 @@ void LLPanelBlockedList::updateButtons()
 	getChildView("Unblock")->setEnabled(hasSelected);
 }
 
-
-
-void LLPanelBlockedList::onBackBtnClick()
-{
-	LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
-	if(parent)
-	{
-		parent->openPreviousPanel();
-	}
-}
-
 void LLPanelBlockedList::onRemoveBtnClick()
 {
 	std::string name = mBlockedList->getSelectedItemLabel();
diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h
index 74ad82e32d..97236ecdbf 100644
--- a/indra/newview/llpanelblockedlist.h
+++ b/indra/newview/llpanelblockedlist.h
@@ -68,7 +68,6 @@ private:
 	void updateButtons();
 
 	// UI callbacks
-	void onBackBtnClick();
 	void onRemoveBtnClick();
 	void onPickBtnClick();
 	void onBlockByNameClick();
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index aceee7cf23..1c63b2a930 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -72,6 +72,7 @@ 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 const std::string BLOCKED_TAB_NAME	= "blocked_panel"; // blocked avatars
 
 static const std::string COLLAPSED_BY_USER  = "collapsed_by_user";
 
@@ -886,6 +887,9 @@ LLUUID LLPanelPeople::getCurrentItemID() const
 	if (cur_tab == GROUP_TAB_NAME)
 		return mGroupList->getSelectedUUID();
 
+	if (cur_tab == BLOCKED_TAB_NAME)
+		return LLUUID::null; // FIXME?
+
 	llassert(0 && "unknown tab selected");
 	return LLUUID::null;
 }
@@ -906,6 +910,8 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const
 		mRecentList->getSelectedUUIDs(selected_uuids);
 	else if (cur_tab == GROUP_TAB_NAME)
 		mGroupList->getSelectedUUIDs(selected_uuids);
+	else if (cur_tab == BLOCKED_TAB_NAME)
+		selected_uuids.clear(); // FIXME?
 	else
 		llassert(0 && "unknown tab selected");
 
@@ -1228,10 +1234,6 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
 		mAllFriendList->showPermissions(show_permissions);
 		mOnlineFriendList->showPermissions(show_permissions);
 	}
-	else if (chosen_item == "panel_block_list_sidetray")
-	{
-		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
-	}
 }
 
 void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata)
@@ -1264,10 +1266,6 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
 	{
 		setSortOrder(mNearbyList, E_SORT_BY_DISTANCE);
 	}
-	else if (chosen_item == "panel_block_list_sidetray")
-	{
-		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
-	}
 }
 
 bool LLPanelPeople::onNearbyViewSortMenuItemCheck(const LLSD& userdata)
@@ -1301,10 +1299,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
 	{
 		mRecentList->toggleIcons();
 	}
-	else if (chosen_item == "panel_block_list_sidetray")
-	{
-		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
-	}
 }
 
 bool LLPanelPeople::onFriendsViewSortMenuItemCheck(const LLSD& userdata) 
diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index d6d8431150..029e4464ea 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -14,13 +14,13 @@
   single_instance="true"
   reuse_instance="true"
   title="PEOPLE"
-  width="333">
+  width="390">
     <panel_container
       default_panel_name="panel_people"
       follows="all"
       height="570"
       name="main_panel"
-      width="333">
+      width="390">
       <panel
         class="panel_people"
         name="panel_people"
@@ -31,11 +31,5 @@
         filename="panel_group_info_sidetray.xml"
         label="Group Profile"
         font="SansSerifBold"/>
-      <panel
-        class="panel_block_list_sidetray"
-        name="panel_block_list_sidetray"
-        filename="panel_block_list_sidetray.xml"
-        label="Blocked Residents &amp; Objects"
-        font="SansSerifBold"/>
     </panel_container>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
index be23e91587..14a3e1f13d 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -19,8 +19,4 @@
      function="CheckControl"
      parameter="FriendsListShowPermissions" />
   </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
-    <menu_item_call.on_click function="People.Friends.ViewSort.Action" parameter="panel_block_list_sidetray" />
-  </menu_item_call>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
index 187dd3bcb5..4c94cf53af 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
@@ -19,13 +19,4 @@
          function="ToggleControl"
          parameter="NearbyListShowMap" />
     </menu_item_check>
-    <menu_item_separator
-     layout="topleft" />
-    <menu_item_call
-     name="show_blocked_list"
-     label="Show Blocked Residents &amp; Objects">
-        <menu_item_call.on_click
-         function="People.Nearby.ViewSort.Action"
-         userdata="panel_block_list_sidetray" />
-    </menu_item_call>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
index 5520bc993c..0eaca47d9a 100644
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
@@ -11,8 +11,4 @@
      function="CheckControl"
      parameter="RecentListShowIcons" />
   </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
-    <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="panel_block_list_sidetray" />
-  </menu_item_call>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index 1e6a31d388..84b772d256 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -9,38 +9,14 @@
  min_height="350"
  min_width="240"
  width="280">
-        <button
-     follows="top|left"
-     height="24"
-     image_hover_unselected="BackButton_Over"
-     image_pressed="BackButton_Press"
-     image_unselected="BackButton_Off"
-     layout="topleft"
-     name="back"
-     left="4"
-     tab_stop="false"
-     top="1"
-     width="30"/>
-    <text
-     follows="top|left|right"
-     font="SansSerifLargeBold"
-     height="20"
-     layout="topleft"
-     left_pad="10"
-     name="title_text"
-     text_color="white"
-     top="5"
-     width="250">
-        Block List
-     </text>
     <scroll_list
      follows="all"
-     height="190"
+     height="220"
      layout="topleft"
      left="5"
      name="blocked"
      tool_tip="List of currently blocked Residents"
-     top="30"
+     top="0"
      width="270">
         <scroll_list.columns
          name="item_name" />
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index ad4a840106..03b6c4fb8b 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -66,7 +66,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      tab_position="top"
      top="0"
      halign="center"
-     width="319">
+     right="-5">
 
 <!-- ================================= NEARBY tab =========================== -->
 
@@ -606,6 +606,32 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              top_pad="0"
              width="307" />
         </panel>
+
+<!-- ================================= BLOCKED tab ========================== -->
+
+        <panel
+         background_opaque="true"
+         background_visible="true"
+         bg_alpha_color="DkGray"
+         bg_opaque_color="DkGray"
+         follows="all"
+         height="383"
+         label="BLOCKED"
+         layout="topleft"
+         left="0"
+         help_topic="people_blocked_tab"
+         name="blocked_panel"
+         top="0"
+         width="313">
+          <panel
+           class="panel_block_list_sidetray"
+           height="383"
+           name="panel_block_list_sidetray"
+           filename="panel_block_list_sidetray.xml"
+           label="Blocked Residents &amp; Objects"
+           font="SansSerifBold"
+           width="313" />
+        </panel>
     </tab_container>
     <panel
      follows="bottom|left|right"
-- 
cgit v1.2.3


From 82c9b0fbbca6f61e57464a6126ae36a59b13d6ed Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 13 Apr 2012 23:07:48 -0700
Subject: fixed build all param values now support named values uniformly

---
 indra/llui/llui.cpp                  |  24 +-
 indra/llui/llui.h                    |   8 +-
 indra/llui/lluiimage.cpp             |   4 +-
 indra/llui/lluiimage.h               |   2 +-
 indra/llui/tests/llurlentry_stub.cpp |  16 +-
 indra/llui/tests/llurlmatch_test.cpp |  16 +-
 indra/llxuixml/llinitparam.h         | 690 +++++++++++++++--------------------
 indra/llxuixml/llxuiparser.cpp       |  24 +-
 indra/newview/llvoavatar.cpp         |   2 +-
 9 files changed, 345 insertions(+), 441 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 6b74c5a6be..b52b0355fe 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -2107,7 +2107,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
 
 namespace LLInitParam
 {
-	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
 	:	super_t(color),
 		red("red"),
 		green("green"),
@@ -2118,7 +2118,7 @@ namespace LLInitParam
 		updateBlockFromValue(false);
 	}
 
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+	void ParamValue<LLUIColor>::updateValueFromBlock()
 	{
 		if (control.isProvided() && !control().empty())
 		{
@@ -2130,7 +2130,7 @@ namespace LLInitParam
 		}
 	}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<LLUIColor>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		LLColor4 color = getValue();
 		red.set(color.mV[VRED], make_block_authoritative);
@@ -2146,7 +2146,7 @@ namespace LLInitParam
 			&& !(b->getFontDesc() < a->getFontDesc());
 	}
 
-	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
 	:	super_t(fontp),
 		name("name"),
 		size("size"),
@@ -2160,7 +2160,7 @@ namespace LLInitParam
 		updateBlockFromValue(false);
 	}
 
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+	void ParamValue<const LLFontGL*>::updateValueFromBlock()
 	{
 		const LLFontGL* res_fontp = LLFontGL::getFontByName(name);
 		if (res_fontp)
@@ -2183,7 +2183,7 @@ namespace LLInitParam
 		}
 	}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		if (getValue())
 		{
@@ -2193,7 +2193,7 @@ namespace LLInitParam
 		}
 	}
 
-	ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect)
+	ParamValue<LLRect>::ParamValue(const LLRect& rect)
 	:	super_t(rect),
 		left("left"),
 		top("top"),
@@ -2205,7 +2205,7 @@ namespace LLInitParam
 		updateBlockFromValue(false);
 	}
 
-	void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()
+	void ParamValue<LLRect>::updateValueFromBlock()
 	{
 		LLRect rect;
 
@@ -2269,7 +2269,7 @@ namespace LLInitParam
 		updateValue(rect);
 	}
 	
-	void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<LLRect>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		// because of the ambiguity in specifying a rect by position and/or dimensions
 		// we use the lowest priority pairing so that any valid pairing in xui 
@@ -2286,7 +2286,7 @@ namespace LLInitParam
 		height.set(value.getHeight(), make_block_authoritative);
 	}
 
-	ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord)
+	ParamValue<LLCoordGL>::ParamValue(const LLCoordGL& coord)
 	:	super_t(coord),
 		x("x"),
 		y("y")
@@ -2294,12 +2294,12 @@ namespace LLInitParam
 		updateBlockFromValue(false);
 	}
 
-	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()
+	void ParamValue<LLCoordGL>::updateValueFromBlock()
 	{
 		updateValue(LLCoordGL(x, y));
 	}
 	
-	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<LLCoordGL>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		x.set(getValue().mX, make_block_authoritative);
 		y.set(getValue().mY, make_block_authoritative);
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 28e84fa444..618ed2fc42 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -512,7 +512,7 @@ public:
 namespace LLInitParam
 {
 	template<>
-	class ParamValue<LLRect, TypeValues<LLRect> > 
+	class ParamValue<LLRect> 
 	:	public CustomParamValue<LLRect>
 	{
         typedef CustomParamValue<LLRect> super_t;
@@ -531,7 +531,7 @@ namespace LLInitParam
 	};
 
 	template<>
-	class ParamValue<LLUIColor, TypeValues<LLUIColor> > 
+	class ParamValue<LLUIColor> 
 	:	public CustomParamValue<LLUIColor>
 	{
         typedef CustomParamValue<LLUIColor> super_t;
@@ -549,7 +549,7 @@ namespace LLInitParam
 	};
 
 	template<>
-	class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> > 
+	class ParamValue<const LLFontGL*> 
 	:	public CustomParamValue<const LLFontGL* >
 	{
         typedef CustomParamValue<const LLFontGL*> super_t;
@@ -589,7 +589,7 @@ namespace LLInitParam
 
 
 	template<>
-	class ParamValue<LLCoordGL, TypeValues<LLCoordGL> >
+	class ParamValue<LLCoordGL>
 	:	public CustomParamValue<LLCoordGL>
 	{
 		typedef CustomParamValue<LLCoordGL> super_t;
diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
index 1d9ce29ba9..6ae42c8852 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llui/lluiimage.cpp
@@ -155,7 +155,7 @@ void LLUIImage::onImageLoaded()
 
 namespace LLInitParam
 {
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+	void ParamValue<LLUIImage*>::updateValueFromBlock()
 	{
 		// The keyword "none" is specifically requesting a null image
 		// do not default to current value. Used to overwrite template images. 
@@ -172,7 +172,7 @@ namespace LLInitParam
 		}
 	}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<LLUIImage*>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		if (getValue() == NULL)
 		{
diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h
index b9b90fee71..b86ea67505 100644
--- a/indra/llui/lluiimage.h
+++ b/indra/llui/lluiimage.h
@@ -92,7 +92,7 @@ protected:
 namespace LLInitParam
 {
 	template<>
-	class ParamValue<LLUIImage*, TypeValues<LLUIImage*>, NOT_BLOCK > 
+	class ParamValue<LLUIImage*> 
 	:	public CustomParamValue<LLUIImage*>
 	{
 		typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type	T_const_ref;
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index 20bac5ff55..9cb6a89eee 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -127,14 +127,14 @@ namespace LLInitParam
 	bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
 	bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
 
-	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
 	:	super_t(color)
 	{}
 
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock() 
+	void ParamValue<LLUIColor>::updateValueFromBlock() 
 	{}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
+	void ParamValue<LLUIColor>::updateBlockFromValue(bool)
 	{}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -142,14 +142,14 @@ namespace LLInitParam
 		return false;
 	}
 
-	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
 	:	super_t(fontp)
 	{}
 
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+	void ParamValue<const LLFontGL*>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
+	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)
 	{}
 
 	void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -161,10 +161,10 @@ namespace LLInitParam
 	void TypeValues<LLFontGL::ShadowType>::declareValues()
 	{}
 
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+	void ParamValue<LLUIImage*>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
+	void ParamValue<LLUIImage*>::updateBlockFromValue(bool)
 	{}
 
 	
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 9119e7d1fe..36402f5b27 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -97,14 +97,14 @@ namespace LLInitParam
 	bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
 	bool BaseBlock::validateBlock(bool emit_errors) const { return true; }
 
-	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
 	:	super_t(color)
 	{}
 
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+	void ParamValue<LLUIColor>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
+	void ParamValue<LLUIColor>::updateBlockFromValue(bool)
 	{}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -113,14 +113,14 @@ namespace LLInitParam
 	}
 
 
-	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
 	:	super_t(fontp)
 	{}
 
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+	void ParamValue<const LLFontGL*>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
+	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)
 	{}
 
 	void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -132,10 +132,10 @@ namespace LLInitParam
 	void TypeValues<LLFontGL::ShadowType>::declareValues()
 	{}
 
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+	void ParamValue<LLUIImage*>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
+	void ParamValue<LLUIImage*>::updateBlockFromValue(bool)
 	{}
 	
 	bool ParamCompare<LLUIImage*, false>::equals(
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 09617209a8..7e2dd3989a 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -77,24 +77,118 @@ namespace LLInitParam
 
 	// helper functions and classes
 	typedef ptrdiff_t param_handle_t;
+	struct IS_A_BLOCK {};
+	struct NOT_BLOCK {};
+
+	// these templates allow us to distinguish between template parameters
+	// that derive from BaseBlock and those that don't
+	template<typename T, typename BLOCK_IDENTIFIER = void>
+	struct IsBlock
+	{
+		typedef NOT_BLOCK value_t;
+	};
+
+	template<typename T>
+	struct IsBlock<T, typename T::baseblock_base_class_t>
+	{
+		typedef IS_A_BLOCK value_t;
+	};
+
+
+	template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
+	class ParamValue
+	{
+		typedef ParamValue<T, VALUE_IS_BLOCK>	self_t;
+
+	public:
+		typedef T	default_value_t;
+		typedef T	value_t;
+
+		ParamValue(): mValue() {}
+		ParamValue(const default_value_t& other) : mValue(other) {}
+
+		void setValue(const value_t& val)
+		{
+			mValue = val;
+		}
+
+		const value_t& getValue() const
+		{
+			return mValue;
+		}
+
+		T& getValue()
+		{
+			return mValue;
+		}
+
+	protected:
+		T mValue;
+	};
+
+	template<typename T>
+	class ParamValue<T, IS_A_BLOCK> 
+		:	public T
+	{
+		typedef ParamValue<T, IS_A_BLOCK>	self_t;
+	public:
+		typedef T	default_value_t;
+		typedef T	value_t;
+
+		ParamValue() 
+			:	T(),
+			mValidated(false)
+		{}
+
+		ParamValue(const default_value_t& other)
+			:	T(other),
+			mValidated(false)
+		{}
+
+		void setValue(const value_t& val)
+		{
+			*this = val;
+		}
+
+		const value_t& getValue() const
+		{
+			return *this;
+		}
+
+		T& getValue()
+		{
+			return *this;
+		}
+
+	protected:
+		mutable bool 	mValidated; // lazy validation flag
+	};
+
 
 	// empty default implementation of key cache
 	// leverages empty base class optimization
 	template <typename T>
 	class TypeValues
+	:	public ParamValue<T>
 	{
 	private:
 		struct Inaccessable{};
+		typedef typename ParamValue<T>::value_t	value_t;
 	public:
 		typedef std::map<std::string, T> value_name_map_t;
 		typedef Inaccessable name_t;
+		typedef TypeValues<T> type_value_t;
+
+		TypeValues(const value_t& val)
+		:	ParamValue(val)
+		{}
 
 		void setValueName(const std::string& key) {}
 		std::string getValueName() const { return ""; }
-		std::string calcValueName(const T& value) const { return ""; }
+		std::string calcValueName(const value_t& value) const { return ""; }
 		void clearValueName() const {}
 
-		static bool getValueFromName(const std::string& name, T& value)
+		static bool getValueFromName(const std::string& name, value_t& value)
 		{
 			return false;
 		}
@@ -109,15 +203,36 @@ namespace LLInitParam
 			return NULL;
 		}
 
+		void assignNamedValue(const Inaccessable& name)
+		{}
+
+		operator const value_t&() const
+		{
+			return getValue();
+		}
+
+		const value_t& operator()() const
+		{
+			return getValue();
+		}
+
 		static value_name_map_t* getValueNames() {return NULL;}
 	};
 
-	template <typename T, typename DERIVED_TYPE = TypeValues<T> >
+	template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >
 	class TypeValuesHelper
+	:	public ParamValue<T>
 	{
+		typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;
+		typedef typename ParamValue<T>::value_t	value_t;
 	public:
 		typedef typename std::map<std::string, T> value_name_map_t;
 		typedef std::string name_t;
+		typedef self_t type_value_t;
+
+		TypeValuesHelper(const value_t& val)
+		:	ParamValue(val)
+		{}
 
 		//TODO: cache key by index to save on param block size
 		void setValueName(const std::string& value_name) 
@@ -130,7 +245,7 @@ namespace LLInitParam
 			return mValueName; 
 		}
 
-		std::string calcValueName(const T& value) const
+		std::string calcValueName(const value_t& value) const
 		{
 			value_name_map_t* map = getValueNames();
 			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
@@ -151,7 +266,7 @@ namespace LLInitParam
 			mValueName.clear();
 		}
 
-		static bool getValueFromName(const std::string& name, T& value)
+		static bool getValueFromName(const std::string& name, value_t& value)
 		{
 			value_name_map_t* map = getValueNames();
 			typename value_name_map_t::iterator found_it = map->find(name);
@@ -193,18 +308,80 @@ namespace LLInitParam
 			return &sValues;
 		}
 
-		static void declare(const std::string& name, const T& value)
+		static void declare(const std::string& name, const value_t& value)
 		{
 			(*getValueNames())[name] = value;
 		}
 
+		void operator ()(const std::string& name)
+		{
+			*this = name;
+		}
+
+		void assignNamedValue(const std::string& name)
+		{
+			if (getValueFromName(name, getValue()))
+			{
+				setValueName(name);
+			}
+		}
+
+		operator const value_t&() const
+		{
+			return getValue();
+		}
+
+		const value_t& operator()() const
+		{
+			return getValue();
+		}
+
 	protected:
-		static void getName(const std::string& name, const T& value)
+		static void getName(const std::string& name, const value_t& value)
 		{}
 
 		mutable std::string	mValueName;
 	};
 
+	template <typename DERIVED_TYPE>
+	class TypeValuesHelper<std::string, DERIVED_TYPE, true>
+	:	public TypeValuesHelper<std::string, DERIVED_TYPE, false>
+	{
+	public:
+		TypeValuesHelper(const std::string& val)
+		:	TypeValuesHelper(val)
+		{}
+
+		void operator ()(const std::string& name)
+		{
+			*this = name;
+		}
+
+		self_t& operator =(const std::string& name)
+		{
+			if (getValueFromName(name, getValue()))
+			{
+				setValueName(name);
+			}
+			else
+			{
+				setValue(name);
+			}
+			return *this;
+		}
+		
+		operator const value_t&() const
+		{
+			return getValue();
+		}
+
+		const value_t& operator()() const
+		{
+			return getValue();
+		}
+
+	};
+
 	class Parser
 	{
 		LOG_CLASS(Parser);
@@ -370,23 +547,6 @@ namespace LLInitParam
 		class BaseBlock*				mCurrentBlockPtr;		// pointer to block currently being constructed
 	};
 
-	struct IS_BLOCK {};
-	struct NOT_BLOCK {};
-
-	// these templates allow us to distinguish between template parameters
-	// that derive from BaseBlock and those that don't
-	template<typename T, typename BLOCK_IDENTIFIER = void>
-	struct IsBlock
-	{
-		typedef NOT_BLOCK value_t;
-	};
-
-	template<typename T>
-	struct IsBlock<T, typename T::baseblock_base_class_t>
-	{
-		typedef IS_BLOCK value_t;
-	};
-
 	//TODO: implement in terms of owned_ptr
 	template<typename T>
 	class LazyValue
@@ -483,8 +643,8 @@ namespace LLInitParam
 	{
 	public:
 		// lift block tags into baseblock namespace so derived classes do not need to qualify them
-		typedef LLInitParam::IS_BLOCK IS_BLOCK;
-		typedef LLInitParam::NOT_BLOCK NOT_BLOCK;
+		typedef LLInitParam::IS_A_BLOCK IS_A_BLOCK;
+		typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK;
 
 		template<typename T>
 		class Atomic
@@ -640,182 +800,12 @@ namespace LLInitParam
 		U32		mIsProvided:1;
 
 	};
-
-
-	template<typename T, typename NAME_VALUE_LOOKUP, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
-	class ParamValue : public NAME_VALUE_LOOKUP
-	{
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK>	self_t;
-
-	public:
-		typedef T									default_value_t;
-		typedef T									value_t;
-
-		ParamValue(): mValue() {}
-		ParamValue(const default_value_t& other) : mValue(other) {}
-
-		void setValue(const value_t& val)
-		{
-			mValue = val;
-		}
-
-		const value_t& getValue() const
-		{
-			return mValue;
-		}
-
-		T& getValue()
-		{
-			return mValue;
-		}
-
-		operator const value_t&() const
-		{
-			return mValue;
-		}
-
-		const value_t& operator()() const
-		{
-			return mValue;
-		}
-
-		void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
-		{
-			*this = name;
-		}
-
-		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
-		{
-			if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue))
-			{
-				setValueName(name);
-			}
-
-			return *this;
-		}
-
-	protected:
-		T mValue;
-	};
-
-	template<typename T, typename NAME_VALUE_LOOKUP>
-	class ParamValue<T, NAME_VALUE_LOOKUP, IS_BLOCK> 
-	:	public T,
-		public NAME_VALUE_LOOKUP
-	{
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, IS_BLOCK>	self_t;
-	public:
-		typedef T									default_value_t;
-		typedef T									value_t;
-
-		ParamValue() 
-		:	T(),
-			mValidated(false)
-		{}
-
-		ParamValue(const default_value_t& other)
-		:	T(other),
-			mValidated(false)
-		{}
-
-		void setValue(const value_t& val)
-		{
-			*this = val;
-		}
-
-		const value_t& getValue() const
-		{
-			return *this;
-		}
-
-		T& getValue()
-		{
-			return *this;
-		}
-
-		operator const value_t&() const
-		{
-			return *this;
-		}
-		
-		const value_t& operator()() const
-		{
-			return *this;
-		}
-
-		void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
-		{
-			*this = name;
-		}
-
-		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
-		{
-			if (NAME_VALUE_LOOKUP::getValueFromName(name, *this))
-			{
-				setValueName(name);
-			}
-
-			return *this;
-		}
-
-	protected:
-		mutable bool 	mValidated; // lazy validation flag
-	};
-
-	template<typename NAME_VALUE_LOOKUP>
-	class ParamValue<std::string, NAME_VALUE_LOOKUP, NOT_BLOCK>
-	: public NAME_VALUE_LOOKUP
-	{
-		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, NOT_BLOCK>	self_t;
-	public:
-		typedef std::string			default_value_t;
-		typedef std::string			value_t;
-
-		ParamValue(): mValue() {}
-		ParamValue(const default_value_t& other) : mValue(other) {}
-
-		void setValue(const value_t& val)
-		{
-			if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue))
-			{
-				NAME_VALUE_LOOKUP::setValueName(val);
-			}
-			else
-			{
-				mValue = val;
-			}
-		}
-
-		const value_t& getValue() const
-		{
-			return mValue;
-		}
-
-		std::string& getValue()
-		{
-			return mValue;
-		}
-
-		operator const value_t&() const
-		{
-			return mValue;
-		}
-
-		const value_t& operator()() const
-		{
-			return mValue;
-		}
-
-	protected:
-		std::string mValue;
-	};
-
-
+	
 	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 	struct ParamIterator
 	{
-		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator;
-		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator;
+		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::const_iterator	const_iterator;
+		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::iterator			iterator;
 	};
 
 	// specialize for custom parsing/decomposition of specific classes
@@ -823,22 +813,23 @@ namespace LLInitParam
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
-			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value_t>
+			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<T> >::value_t>
 	class TypedParam 
 	:	public Param, 
-		public ParamValue<T, NAME_VALUE_LOOKUP>
+		public NAME_VALUE_LOOKUP::type_value_t
 	{
 	protected:
 		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP>										param_value_t;
+		typedef ParamValue<T>															param_value_t;
 		typedef typename param_value_t::value_t											value_t;
 		typedef typename param_value_t::default_value_t									default_value_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t								named_value_t;
 	public:
-		using param_value_t::operator();
+		using named_value_t::operator();
 
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr),
-			param_value_t(value)
+			named_value_t(value)
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
@@ -862,7 +853,7 @@ namespace LLInitParam
 				}
 				
 				// try to parse a known named value
-				if(param_value_t::valueNamesExist())
+				if(named_value_t::valueNamesExist())
 				{
 					// try to parse a known named value
 					std::string name;
@@ -870,7 +861,7 @@ namespace LLInitParam
 					{
 						// try to parse a per type named value
 
-						if (param_value_t::getValueFromName(name, typed_param.getValue()))
+						if (named_value_t::getValueFromName(name, typed_param.getValue()))
 						{
 							typed_param.setValueName(name);
 							typed_param.setProvided();
@@ -923,22 +914,23 @@ namespace LLInitParam
 			// tell parser about our actual type
 			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
 			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
-			if (param_value_t::getPossibleValues())
+			if (named_value_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, param_value_t::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
 			}
 		}
 
 		void set(const value_t& val, bool flag_as_provided = true)
 		{
-			param_value_t::clearValueName();
+			named_value_t::clearValueName();
 			setValue(val);
 			setProvided(flag_as_provided);
 		}
 
-		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+		self_t& operator =(const typename named_value_t::name_t& name)
 		{
-			return static_cast<self_t&>(param_value_t::operator =(name));
+			named_value_t::assignNamedValue(name);
+			return *this;
 		}
 
 	protected:
@@ -980,21 +972,22 @@ namespace LLInitParam
 
 	// parameter that is a block
 	template <typename T, typename NAME_VALUE_LOOKUP>
-	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK> 
+	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> 
 	:	public Param,
-	public ParamValue<T, NAME_VALUE_LOOKUP>
+		public NAME_VALUE_LOOKUP::type_value_t
 	{
 	protected:
-		typedef ParamValue<T, NAME_VALUE_LOOKUP>					param_value_t;
+		typedef ParamValue<T>										param_value_t;
 		typedef typename param_value_t::value_t						value_t;
 		typedef typename param_value_t::default_value_t				default_value_t;
-		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_BLOCK>	self_t;
+		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>	self_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t			named_value_t;
 	public:
-		using param_value_t::operator();
+		using named_value_t::operator();
 
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr),
-			param_value_t(value)
+			named_value_t(value)
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
@@ -1013,14 +1006,14 @@ namespace LLInitParam
 				return true;
 			}
 
-			if(param_value_t::valueNamesExist())
+			if(named_value_t::valueNamesExist())
 			{
 				// try to parse a known named value
 				std::string name;
 				if (parser.readValue(name))
 				{
 					// try to parse a per type named value
-					if (param_value_t::getValueFromName(name, typed_param.getValue()))
+					if (named_value_t::getValueFromName(name, typed_param.getValue()))
 					{
 						typed_param.setValueName(name);
 						typed_param.setProvided();
@@ -1045,9 +1038,9 @@ namespace LLInitParam
 			std::string key = typed_param.getValueName();
 			if (!key.empty())
 			{
-				if (!parser.writeValue(key, name_stack))
+				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
 				{
-					return;
+					parser.writeValue(key, name_stack);
 				}
 			}
 			else
@@ -1058,8 +1051,16 @@ namespace LLInitParam
 
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
-			// I am a param that is also a block, so just recurse into my contents
 			const self_t& typed_param = static_cast<const self_t&>(param);
+
+			// tell parser about our actual type
+			parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+			if (named_value_t::getPossibleValues())
+			{
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+			}
+
 			typed_param.inspectBlock(parser, name_stack, min_count, max_count);
 		}
 
@@ -1080,29 +1081,31 @@ namespace LLInitParam
 		void set(const value_t& val, bool flag_as_provided = true)
 		{
 			setValue(val);
-			param_value_t::clearValueName();
+			named_value_t::clearValueName();
 			// force revalidation of block
 			// next call to isProvided() will update provision status based on validity
 			param_value_t::mValidated = false;
 			setProvided(flag_as_provided);
 		}
 
-		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+		self_t& operator =(const typename named_value_t::name_t& name)
 		{
-			return static_cast<self_t&>(param_value_t::operator =(name));
+			named_value_t::assignNamedValue(name);
+			return *this;
 		}
 
 		// propagate changed status up to enclosing block
 		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
 		{ 
 			param_value_t::paramChanged(changed_param, user_provided);
+			named_value_t::clearValueName();
+
 			if (user_provided)
 			{
 				// a child param has been explicitly changed
 				// so *some* aspect of this block is now provided
 				param_value_t::mValidated = false;
 				setProvided();
-				param_value_t::clearValueName();
 			}
 			else
 			{
@@ -1157,11 +1160,12 @@ namespace LLInitParam
 	:	public Param
 	{
 	protected:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>							self_t;
-		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP, typename IsBlock<VALUE_TYPE>::value_t>	param_value_t;
-		typedef typename std::vector<param_value_t>													container_t;
-		typedef container_t																			default_value_t;
-		typedef typename param_value_t::value_t														value_t;
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>	self_t;
+		typedef ParamValue<VALUE_TYPE>										param_value_t;
+		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;
+		typedef container_t													default_value_t;
+		typedef typename param_value_t::value_t								value_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t					named_value_t;
 		
 	public:
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
@@ -1193,14 +1197,14 @@ namespace LLInitParam
 				}
 				
 				// try to parse a known named value
-				if(param_value_t::valueNamesExist())
+				if(named_value_t::valueNamesExist())
 				{
 					// try to parse a known named value
 					std::string name;
 					if (parser.readValue(name))
 					{
 						// try to parse a per type named value
-						if (param_value_t::getValueFromName(name, value))
+						if (named_value_t::getValueFromName(name, value))
 						{
 							typed_param.add(value);
 							typed_param.mValues.back().setValueName(name);
@@ -1251,9 +1255,9 @@ namespace LLInitParam
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
 			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
-			if (param_value_t::getPossibleValues())
+			if (named_value_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, param_value_t::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
 			}
 		}
 
@@ -1265,25 +1269,23 @@ namespace LLInitParam
 
 		param_value_t& add()
 		{
-			mValues.push_back(param_value_t(value_t()));
+			mValues.push_back(value_t());
 			Param::setProvided();
 			return mValues.back();
 		}
 
 		void add(const value_t& item)
 		{
-			param_value_t param_value;
-			param_value.setValue(item);
-			mValues.push_back(param_value);
+			mValues.push_back(item);
 			setProvided();
 		}
 
-		void add(const typename param_value_t::name_t& name)
+		void add(const typename named_value_t::name_t& name)
 		{
 			value_t value;
 
 			// try to parse a per type named value
-			if (param_value_t::getValueFromName(name, value))
+			if (named_value_t::getValueFromName(name, value))
 			{
 				add(value);
 				mValues.back().setValueName(name);
@@ -1352,17 +1354,18 @@ namespace LLInitParam
 
 	// container of block parameters
 	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
-	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_BLOCK> 
+	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> 
 	:	public Param
 	{
 	protected:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_BLOCK>							self_t;
-		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP, typename IsBlock<VALUE_TYPE>::value_t>	param_value_t;
-		typedef typename std::vector<param_value_t>													container_t;
-		typedef typename param_value_t::value_t														value_t;
-		typedef container_t																			default_value_t;
-		typedef typename container_t::iterator														iterator;
-		typedef typename container_t::const_iterator												const_iterator;
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>		self_t;
+		typedef ParamValue<VALUE_TYPE>											param_value_t;
+		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t;
+		typedef typename param_value_t::value_t									value_t;
+		typedef container_t														default_value_t;
+		typedef typename container_t::iterator									iterator;
+		typedef typename container_t::const_iterator							const_iterator;
 	public:
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
@@ -1396,14 +1399,14 @@ namespace LLInitParam
 				typed_param.setProvided();
 				return true;
 			}
-			else if(param_value_t::valueNamesExist())
+			else if(named_value_t::valueNamesExist())
 			{
 				// try to parse a known named value
 				std::string name;
 				if (parser.readValue(name))
 				{
 					// try to parse a per type named value
-					if (param_value_t::getValueFromName(name, value.getValue()))
+					if (named_value_t::getValueFromName(name, value.getValue()))
 					{
 						typed_param.mValues.back().setValueName(name);
 						typed_param.setProvided();
@@ -1448,8 +1451,17 @@ namespace LLInitParam
 
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
-			// I am a vector of blocks, so describe my contents recursively
-			param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);
+			const param_value_t& value_param = param_value_t(value_t());
+
+			// tell parser about our actual type
+			parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+			if (named_value_t::getPossibleValues())
+			{
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+			}
+
+			value_param.inspectBlock(parser, name_stack, min_count, max_count);
 		}
 
 		void set(const container_t& val, bool flag_as_provided = true)
@@ -1471,12 +1483,12 @@ namespace LLInitParam
 			setProvided();
 		}
 
-		void add(const typename param_value_t::name_t& name)
+		void add(const typename named_value_t::name_t& name)
 		{
 			value_t value;
 
 			// try to parse a per type named value
-			if (param_value_t::getValueFromName(name, value))
+			if (named_value_t::getValueFromName(name, value))
 			{
 				add(value);
 				mValues.back().setValueName(name);
@@ -1620,7 +1632,7 @@ namespace LLInitParam
 		// Alternatives are mutually exclusive wrt other Alternatives in the same block.  
 		// One alternative in a block will always have isChosen() == true.
 		// At most one alternative in a block will have isProvided() == true.
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T>::type_value_t >
 		class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>	super_t;
@@ -1662,7 +1674,7 @@ namespace LLInitParam
 				super_t::set(val);
 			}
 
-			void operator()(typename const value_t& val) 
+			void operator()(const value_t& val) 
 			{ 
 				super_t::set(val);
 			}
@@ -1743,7 +1755,7 @@ namespace LLInitParam
 		//
 		// Nested classes for declaring parameters
 		//
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T>::type_value_t >
 		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
@@ -1773,7 +1785,7 @@ namespace LLInitParam
 			}
 		};
 
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T>::type_value_t >
 		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
@@ -1796,7 +1808,7 @@ namespace LLInitParam
 				return *this;
 			}
 
-			DERIVED_BLOCK& operator()(typename const value_t& val)
+			DERIVED_BLOCK& operator()(const value_t& val)
 			{
 				super_t::set(val);
 				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1810,14 +1822,13 @@ namespace LLInitParam
 
 		};
 
-		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T>::type_value_t >
 		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
 		{
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;
 			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>	self_t;
 			typedef typename super_t::container_t			container_t;
 			typedef typename super_t::value_t				value_t;
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;
 
 		public:
 			typedef typename super_t::iterator			iterator;
@@ -1833,7 +1844,7 @@ namespace LLInitParam
 				return *this;
 			}
 
-			DERIVED_BLOCK& operator()(typename const container_t& val)
+			DERIVED_BLOCK& operator()(const container_t& val)
 			{
 				super_t::set(val);
 				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1904,30 +1915,27 @@ namespace LLInitParam
 	};
 	
 	template<typename T, typename BLOCK_T>
-	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_BLOCK>, TypeValues<BaseBlock::Lazy<T, BaseBlock::IS_BLOCK> >, BLOCK_T >, void>
+	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_A_BLOCK>, BLOCK_T >, void>
 	{
-		typedef IS_BLOCK value_t;
+		typedef IS_A_BLOCK value_t;
 	};
 
 	template<typename T, typename BLOCK_T>
-	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_BLOCK>, TypeValues<BaseBlock::Lazy<T, BaseBlock::NOT_BLOCK> >, BLOCK_T >, void>
+	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_A_BLOCK>, BLOCK_T >, void>
 	{
 		typedef NOT_BLOCK value_t;
 	};
 
 	template<typename T, typename BLOCK_IDENTIFIER>
-	struct IsBlock<ParamValue<BaseBlock::Atomic<T>, TypeValues<BaseBlock::Atomic<T> >, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER>
+	struct IsBlock<ParamValue<BaseBlock::Atomic<T>, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER>
 	{
-		typedef typename IsBlock<ParamValue<T, TypeValues<T> > >::value_t value_t;
+		typedef typename IsBlock<ParamValue<T> >::value_t value_t;
 	};
 
 	template<typename T, typename BLOCK_T>
-	class ParamValue <BaseBlock::Atomic<T>,
-		TypeValues<BaseBlock::Atomic<T> >,
-		BLOCK_T>
-	:	public TypeValues<T>
+	class ParamValue <BaseBlock::Atomic<T>, BLOCK_T>
 	{
-		typedef ParamValue <BaseBlock::Atomic<T>, TypeValues<BaseBlock::Atomic<T> >, BLOCK_T> self_t;
+		typedef ParamValue <BaseBlock::Atomic<T>, BLOCK_T> self_t;
 
 	public:
 		typedef T								value_t;
@@ -1945,12 +1953,12 @@ namespace LLInitParam
 
 		void setValue(const value_t& val)
 		{
-			mValue.setValue(val);
+			mValue = val;
 		}
 
 		const T& getValue() const
 		{
-			return mValue.getValue();
+			return mValue;
 		}
 
 		T& getValue()
@@ -1968,18 +1976,6 @@ namespace LLInitParam
 			return mValue;
 		}
 
-		void operator ()(const typename TypeValues<T>::name_t& name)
-		{
-			*this = name;
-		}
-
-		self_t& operator =(const typename TypeValues<T>::name_t& name)
-		{
-			mValue = name;
-
-			return *this;
-		}
-
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
 		{
 			if (new_name)
@@ -2036,12 +2032,9 @@ namespace LLInitParam
 	};
 
 	template<typename T, typename BLOCK_T>
-	class ParamValue <BaseBlock::Lazy<T, IS_BLOCK>,
-					TypeValues<BaseBlock::Lazy<T, IS_BLOCK> >,
-					BLOCK_T> 
-	:	public TypeValues<T>
+	class ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> 
 	{
-		typedef ParamValue <BaseBlock::Lazy<T, IS_BLOCK>, TypeValues<BaseBlock::Lazy<T, IS_BLOCK> >, BLOCK_T> self_t;
+		typedef ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> self_t;
 
 	public:
 		typedef T				value_t;
@@ -2087,21 +2080,6 @@ namespace LLInitParam
 			return mValue.get();
 		}
 
-		void operator ()(const typename TypeValues<T>::name_t& name)
-		{
-			*this = name;
-		}
-
-		self_t& operator =(const typename TypeValues<T>::name_t& name)
-		{
-			if (TypeValues<T>::getValueFromName(name, mValue.get()))
-			{
-				setValueName(name);
-			}
-
-			return *this;
-		}
-
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
 		{
 			return mValue.get().deserializeBlock(p, name_stack_range, new_name);
@@ -2145,12 +2123,9 @@ namespace LLInitParam
 	};
 
 	template<typename T, typename BLOCK_T>
-	class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>,
-		TypeValues<BaseBlock::Lazy<T, NOT_BLOCK> >,
-		BLOCK_T>
-		:	public TypeValues<T>
+	class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T>
 	{
-		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, TypeValues<BaseBlock::Lazy<T, NOT_BLOCK> >, BLOCK_T> self_t;
+		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t;
 
 	public:
 		typedef T				value_t;
@@ -2196,21 +2171,6 @@ namespace LLInitParam
 			return mValue.get();
 		}
 
-		void operator ()(const typename TypeValues<T>::name_t& name)
-		{
-			*this = name;
-		}
-
-		self_t& operator =(const typename TypeValues<T>::name_t& name)
-		{
-			if (TypeValues<T>::getValueFromName(name, mValue.get()))
-			{
-				setValueName(name);
-			}
-
-			return *this;
-		}
-
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
@@ -2218,11 +2178,8 @@ namespace LLInitParam
 	};
 
 	template <>
-	class ParamValue <LLSD,
-					TypeValues<LLSD>,
-					NOT_BLOCK>
-	:	public TypeValues<LLSD>,
-		public BaseBlock
+	class ParamValue <LLSD, NOT_BLOCK>
+	:	public BaseBlock
 	{
 	public:
 		typedef LLSD			value_t;
@@ -2265,8 +2222,7 @@ namespace LLInitParam
 
 	template<typename T>
 	class CustomParamValue
-	:	public Block<ParamValue<T, TypeValues<T> > >,
-		public TypeValues<T>
+	:	public Block<ParamValue<T> >
 	{
 	public:
 		typedef enum e_value_age
@@ -2276,12 +2232,12 @@ namespace LLInitParam
 			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative
 		} EValueAge;
 
-		typedef ParamValue<T, TypeValues<T> >	derived_t;
-		typedef CustomParamValue<T>				self_t;
-		typedef Block<derived_t>				block_t;
-		typedef T								default_value_t;
-		typedef T								value_t;
-		typedef void							baseblock_base_class_t;
+		typedef ParamValue<T>			derived_t;
+		typedef CustomParamValue<T>		self_t;
+		typedef Block<derived_t>		block_t;
+		typedef T						default_value_t;
+		typedef T						value_t;
+		typedef void					baseblock_base_class_t;
 
 
 		CustomParamValue(const default_value_t& value = T())
@@ -2301,8 +2257,6 @@ namespace LLInitParam
 					typed_param.mValueAge = VALUE_AUTHORITATIVE;
 					typed_param.updateBlockFromValue(false);
 
-					typed_param.clearValueName();
-
 					return true;
 				}
 			}
@@ -2316,18 +2270,8 @@ namespace LLInitParam
 			const derived_t& typed_param = static_cast<const derived_t&>(*this);
 			const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
 			
-			std::string key = typed_param.getValueName();
-
-			// first try to write out name of name/value pair
-			if (!key.empty())
-			{
-				if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
-				{
-					parser.writeValue(key, name_stack);
-				}
-			}
 			// then try to serialize value directly
-			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
+			if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
             {
 				
 				if (!parser.writeValue(typed_param.getValue(), name_stack)) 
@@ -2357,19 +2301,6 @@ namespace LLInitParam
 			}
 		}
 
-		bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
-		{
-			// first, inspect with actual type...
-			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
-			if (TypeValues<T>::getPossibleValues())
-			{
-				//...then inspect with possible string values...
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
-			}
-			// then recursively inspect contents...
-			return block_t::inspectBlock(parser, name_stack, min_count, max_count);
-		}
-
 		bool validateBlock(bool emit_errors = true) const
 		{
 			if (mValueAge == VALUE_NEEDS_UPDATE)
@@ -2377,7 +2308,6 @@ namespace LLInitParam
 				if (block_t::validateBlock(emit_errors))
 				{
 					// clear stale keyword associated with old value
-					TypeValues<T>::clearValueName();
 					mValueAge = BLOCK_AUTHORITATIVE;
 					static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();
 					return true;
@@ -2409,11 +2339,9 @@ namespace LLInitParam
 			
 		void setValue(const value_t& val)
 		{
-			derived_t& typed_param = static_cast<derived_t&>(*this);
 			// set param version number to be up to date, so we ignore block contents
 			mValueAge = VALUE_AUTHORITATIVE;
 			mValue = val;
-			typed_param.clearValueName();
 			static_cast<derived_t*>(this)->updateBlockFromValue(false);
 		}
 
@@ -2429,30 +2357,6 @@ namespace LLInitParam
 			return mValue;
 		}
 
-		operator const value_t&() const
-		{
-			return getValue();
-		}
-
-		const value_t& operator()() const
-		{
-			return getValue();
-		}
-
-		void operator ()(const typename TypeValues<T>::name_t& name)
-		{
-			*this = name;
-		}
-
-		self_t& operator =(const typename TypeValues<T>::name_t& name)
-		{
-			if (TypeValues<T>::getValueFromName(name, mValue))
-			{
-				setValueName(name);
-			}
-
-			return *this;
-		}
 	protected:
 
 		// use this from within updateValueFromBlock() to set the value without making it authoritative
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 2e1f8888d0..58ed24b08b 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -130,7 +130,7 @@ struct Any : public LLInitParam::Block<Any, Occurs>
 
 struct All : public LLInitParam::Block<All, Occurs>
 {
-	Multiple< Lazy<Element, IS_BLOCK> > elements;
+	Multiple< Lazy<Element, IS_A_BLOCK> > elements;
 
 	All()
 	:	elements("element")
@@ -141,11 +141,11 @@ struct All : public LLInitParam::Block<All, Occurs>
 
 struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
 {
-	Alternative< Lazy<Element, IS_BLOCK> >	element;
-	Alternative< Lazy<Group, IS_BLOCK> >		group;
-	Alternative< Lazy<Choice, IS_BLOCK> >		choice;
-	Alternative< Lazy<Sequence, IS_BLOCK> >	sequence;
-	Alternative< Lazy<Any, IS_BLOCK> >		any;
+	Alternative< Lazy<Element, IS_A_BLOCK> >	element;
+	Alternative< Lazy<Group, IS_A_BLOCK> >		group;
+	Alternative< Lazy<Choice, IS_A_BLOCK> >		choice;
+	Alternative< Lazy<Sequence, IS_A_BLOCK> >	sequence;
+	Alternative< Lazy<Any, IS_A_BLOCK> >		any;
 
 	Choice()
 	:	element("element"),
@@ -159,11 +159,11 @@ struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
 
 struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
 {
-	Alternative< Lazy<Element, IS_BLOCK> >	element;
-	Alternative< Lazy<Group, IS_BLOCK> >		group;
-	Alternative< Lazy<Choice, IS_BLOCK> >		choice;
-	Alternative< Lazy<Sequence, IS_BLOCK> >	sequence;
-	Alternative< Lazy<Any, IS_BLOCK> >		any;
+	Alternative< Lazy<Element, IS_A_BLOCK> >	element;
+	Alternative< Lazy<Group, IS_A_BLOCK> >		group;
+	Alternative< Lazy<Choice, IS_A_BLOCK> >		choice;
+	Alternative< Lazy<Sequence, IS_A_BLOCK> >	sequence;
+	Alternative< Lazy<Any, IS_A_BLOCK> >		any;
 };
 
 struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
@@ -248,7 +248,7 @@ struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>
 	Optional<bool>					mixed;
 
 	Multiple<Attribute>				attribute;
-	Multiple< Lazy<Element, IS_BLOCK > >			elements;
+	Multiple< Lazy<Element, IS_A_BLOCK > >			elements;
 
 	ComplexType()
 	:	name("name"),
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index c483aa58c9..b420812a3c 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -248,7 +248,7 @@ struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarColli
 
 struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
 {
-	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_BLOCK> >	bone;
+	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> >	bone;
 	Alternative<LLVOAvatarCollisionVolumeInfo>		collision_volume;
 
 	LLVOAvatarChildJoint()
-- 
cgit v1.2.3


From 7dc9ddff4b775bf78561ef545db281cf47f2240f Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Sun, 15 Apr 2012 20:43:55 -0700
Subject: attempted fix for gcc

---
 indra/llui/llsdparam.cpp     |  6 ++---
 indra/llxuixml/llinitparam.h | 55 +++++++++++++++++++++++++++++++-------------
 2 files changed, 42 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 828f809452..bcfb38aa11 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -313,7 +313,7 @@ namespace LLInitParam
 {
 	// LLSD specialization
 	// block param interface
-	bool ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
+	bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
 	{
 		LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
 
@@ -328,12 +328,12 @@ namespace LLInitParam
 	}
 
 	//static
-	void ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
+	void ParamValue<LLSD, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
 	{
 		p.writeValue<LLSD::String>(sd.asString(), name_stack);
 	}
 
-	void ParamValue<LLSD, TypeValues<LLSD>, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
+	void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
 	{
 		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
 		Parser::name_stack_t stack;
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 7e2dd3989a..d4d19d1c13 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -43,6 +43,8 @@ namespace LLInitParam
 
 	template<typename T> const T& defaultValue() { static T value; return value; }
 
+	// wraps comparison operator between any 2 values of the same type
+	// specialize to handle cases where equality isn't defined well, or at all
 	template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
     struct ParamCompare 
 	{
@@ -94,7 +96,11 @@ namespace LLInitParam
 		typedef IS_A_BLOCK value_t;
 	};
 
-
+	// ParamValue class directly manages the wrapped value
+	// by holding on to a copy (scalar params)
+	// or deriving from it (blocks)
+	// has specializations for custom value behavior
+	// and "tagged" values like Lazy and Atomic
 	template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
 	class ParamValue
 	{
@@ -180,7 +186,7 @@ namespace LLInitParam
 		typedef TypeValues<T> type_value_t;
 
 		TypeValues(const value_t& val)
-		:	ParamValue(val)
+		:	ParamValue<T>(val)
 		{}
 
 		void setValueName(const std::string& key) {}
@@ -208,17 +214,19 @@ namespace LLInitParam
 
 		operator const value_t&() const
 		{
-			return getValue();
+			return ParamValue<T>::getValue();
 		}
 
 		const value_t& operator()() const
 		{
-			return getValue();
+			return ParamValue<T>::getValue();
 		}
 
 		static value_name_map_t* getValueNames() {return NULL;}
 	};
 
+	// helper class to implement name value lookups
+	// and caching of last used name
 	template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >
 	class TypeValuesHelper
 	:	public ParamValue<T>
@@ -231,7 +239,7 @@ namespace LLInitParam
 		typedef self_t type_value_t;
 
 		TypeValuesHelper(const value_t& val)
-		:	ParamValue(val)
+		:	ParamValue<T>(val)
 		{}
 
 		//TODO: cache key by index to save on param block size
@@ -320,7 +328,7 @@ namespace LLInitParam
 
 		void assignNamedValue(const std::string& name)
 		{
-			if (getValueFromName(name, getValue()))
+			if (getValueFromName(name, ParamValue<T>::getValue()))
 			{
 				setValueName(name);
 			}
@@ -328,12 +336,12 @@ namespace LLInitParam
 
 		operator const value_t&() const
 		{
-			return getValue();
+			return ParamValue<T>::getValue();
 		}
 
 		const value_t& operator()() const
 		{
-			return getValue();
+			return ParamValue<T>::getValue();
 		}
 
 	protected:
@@ -343,11 +351,19 @@ namespace LLInitParam
 		mutable std::string	mValueName;
 	};
 
+	// string types can support custom named values, but need
+	// to disambiguate in code between a string that is a named value
+	// and a string that is a name
 	template <typename DERIVED_TYPE>
 	class TypeValuesHelper<std::string, DERIVED_TYPE, true>
 	:	public TypeValuesHelper<std::string, DERIVED_TYPE, false>
 	{
 	public:
+		typedef TypeValuesHelper<std::string, DERIVED_TYPE, true> self_t;
+		typedef std::string value_t;
+		typedef std::string name_t;
+		typedef self_t type_value_t;
+
 		TypeValuesHelper(const std::string& val)
 		:	TypeValuesHelper(val)
 		{}
@@ -359,7 +375,7 @@ namespace LLInitParam
 
 		self_t& operator =(const std::string& name)
 		{
-			if (getValueFromName(name, getValue()))
+			if (getValueFromName(name, ParamValue<T>::getValue()))
 			{
 				setValueName(name);
 			}
@@ -372,16 +388,17 @@ namespace LLInitParam
 		
 		operator const value_t&() const
 		{
-			return getValue();
+			return ParamValue<T>::getValue();
 		}
 
 		const value_t& operator()() const
 		{
-			return getValue();
+			return ParamValue<T>::getValue();
 		}
 
 	};
 
+	// parser base class with mechanisms for registering readers/writers/inspectors of different types
 	class Parser
 	{
 		LOG_CLASS(Parser);
@@ -639,6 +656,8 @@ namespace LLInitParam
 		mutable T* mPtr;
 	};
 
+	// root class of all parameter blocks
+
 	class BaseBlock
 	{
 	public:
@@ -808,8 +827,12 @@ namespace LLInitParam
 		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::iterator			iterator;
 	};
 
-	// specialize for custom parsing/decomposition of specific classes
-	// e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
+	// wrapper for parameter with a known type
+	// specialized to handle 4 cases:
+	// simple "scalar" value
+	// parameter that is itself a block
+	// multiple scalar values, stored in a vector
+	// multiple blocks, stored in a vector
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
@@ -1098,7 +1121,6 @@ namespace LLInitParam
 		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
 		{ 
 			param_value_t::paramChanged(changed_param, user_provided);
-			named_value_t::clearValueName();
 
 			if (user_provided)
 			{
@@ -1106,6 +1128,7 @@ namespace LLInitParam
 				// so *some* aspect of this block is now provided
 				param_value_t::mValidated = false;
 				setProvided();
+				named_value_t::clearValueName();
 			}
 			else
 			{
@@ -1472,7 +1495,7 @@ namespace LLInitParam
 
 		param_value_t& add()
 		{
-			mValues.push_back(value_t());
+			mValues.push_back(value_t())
 			setProvided();
 			return mValues.back();
 		}
@@ -1632,7 +1655,7 @@ namespace LLInitParam
 		// Alternatives are mutually exclusive wrt other Alternatives in the same block.  
 		// One alternative in a block will always have isChosen() == true.
 		// At most one alternative in a block will have isProvided() == true.
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T>::type_value_t >
+		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
 		class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>	super_t;
-- 
cgit v1.2.3


From 3547815a8541a6fcb67f652e095c8d4692ef359d Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Sun, 15 Apr 2012 20:46:55 -0700
Subject: fixed minor typo

---
 indra/llxuixml/llinitparam.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index d4d19d1c13..fdcdf81294 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -1495,7 +1495,7 @@ namespace LLInitParam
 
 		param_value_t& add()
 		{
-			mValues.push_back(value_t())
+			mValues.push_back(value_t());
 			setProvided();
 			return mValues.back();
 		}
-- 
cgit v1.2.3


From 1cbe0f68c59554e197158c9000dca617cb028056 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Sun, 15 Apr 2012 23:49:26 -0700
Subject: another round of gcc fixes

---
 indra/llxuixml/llinitparam.h | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index fdcdf81294..9135b200ab 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -360,6 +360,7 @@ namespace LLInitParam
 	{
 	public:
 		typedef TypeValuesHelper<std::string, DERIVED_TYPE, true> self_t;
+		typedef TypeValuesHelper<std::string, DERIVED_TYPE, false> base_t;
 		typedef std::string value_t;
 		typedef std::string name_t;
 		typedef self_t type_value_t;
@@ -375,25 +376,25 @@ namespace LLInitParam
 
 		self_t& operator =(const std::string& name)
 		{
-			if (getValueFromName(name, ParamValue<T>::getValue()))
+			if (base_t::getValueFromName(name, ParamValue<std::string>::getValue()))
 			{
-				setValueName(name);
+				base_t::setValueName(name);
 			}
 			else
 			{
-				setValue(name);
+				ParamValue<std::string>::setValue(name);
 			}
 			return *this;
 		}
 		
 		operator const value_t&() const
 		{
-			return ParamValue<T>::getValue();
+			return ParamValue<std::string>::getValue();
 		}
 
 		const value_t& operator()() const
 		{
-			return ParamValue<T>::getValue();
+			return ParamValue<std::string>::getValue();
 		}
 
 	};
@@ -1778,7 +1779,7 @@ namespace LLInitParam
 		//
 		// Nested classes for declaring parameters
 		//
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T>::type_value_t >
+		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
 		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
@@ -1808,7 +1809,7 @@ namespace LLInitParam
 			}
 		};
 
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T>::type_value_t >
+		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
 		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
@@ -1845,7 +1846,7 @@ namespace LLInitParam
 
 		};
 
-		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T>::type_value_t >
+		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
 		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
 		{
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;
-- 
cgit v1.2.3


From f7668cd09d300fb4ad63ac6ad8880432d2da6c7f Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 16 Apr 2012 13:50:10 -0700
Subject: more gcc build fixin

---
 indra/llxuixml/llinitparam.h | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 9135b200ab..afb6868c4b 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -179,11 +179,11 @@ namespace LLInitParam
 	{
 	private:
 		struct Inaccessable{};
-		typedef typename ParamValue<T>::value_t	value_t;
 	public:
 		typedef std::map<std::string, T> value_name_map_t;
 		typedef Inaccessable name_t;
 		typedef TypeValues<T> type_value_t;
+		typedef typename ParamValue<T>::value_t	value_t;
 
 		TypeValues(const value_t& val)
 		:	ParamValue<T>(val)
@@ -232,11 +232,11 @@ namespace LLInitParam
 	:	public ParamValue<T>
 	{
 		typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;
-		typedef typename ParamValue<T>::value_t	value_t;
 	public:
 		typedef typename std::map<std::string, T> value_name_map_t;
 		typedef std::string name_t;
 		typedef self_t type_value_t;
+		typedef typename ParamValue<T>::value_t	value_t;
 
 		TypeValuesHelper(const value_t& val)
 		:	ParamValue<T>(val)
@@ -845,10 +845,11 @@ namespace LLInitParam
 	protected:
 		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t;
 		typedef ParamValue<T>															param_value_t;
-		typedef typename param_value_t::value_t											value_t;
 		typedef typename param_value_t::default_value_t									default_value_t;
 		typedef typename NAME_VALUE_LOOKUP::type_value_t								named_value_t;
 	public:
+		typedef typename param_value_t::value_t											value_t;
+
 		using named_value_t::operator();
 
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
@@ -1002,12 +1003,12 @@ namespace LLInitParam
 	{
 	protected:
 		typedef ParamValue<T>										param_value_t;
-		typedef typename param_value_t::value_t						value_t;
 		typedef typename param_value_t::default_value_t				default_value_t;
 		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>	self_t;
 		typedef typename NAME_VALUE_LOOKUP::type_value_t			named_value_t;
 	public:
 		using named_value_t::operator();
+		typedef typename param_value_t::value_t						value_t;
 
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr),
@@ -1188,10 +1189,11 @@ namespace LLInitParam
 		typedef ParamValue<VALUE_TYPE>										param_value_t;
 		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;
 		typedef container_t													default_value_t;
-		typedef typename param_value_t::value_t								value_t;
 		typedef typename NAME_VALUE_LOOKUP::type_value_t					named_value_t;
 		
 	public:
+		typedef typename param_value_t::value_t								value_t;
+
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
@@ -1386,11 +1388,12 @@ namespace LLInitParam
 		typedef ParamValue<VALUE_TYPE>											param_value_t;
 		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;
 		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t;
-		typedef typename param_value_t::value_t									value_t;
 		typedef container_t														default_value_t;
 		typedef typename container_t::iterator									iterator;
 		typedef typename container_t::const_iterator							const_iterator;
 	public:
+		typedef typename param_value_t::value_t									value_t;
+
 		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
-- 
cgit v1.2.3


From cfb2803f1e01cc9596ba3c6dae9679adb454819e Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Sat, 14 Apr 2012 01:10:23 +0300
Subject: CHUI-78 WIP Remove bottom button bar from the people panel.

By the way, removed the "Activate" button from the Groups tab.
---
 indra/newview/llpanelpeople.cpp                    |  99 ------
 indra/newview/llpanelpeople.h                      |   9 -
 .../newview/skins/default/xui/en/panel_people.xml  | 380 ++++-----------------
 3 files changed, 71 insertions(+), 417 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 1c63b2a930..a9da9e0cbf 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -509,16 +509,8 @@ LLPanelPeople::LLPanelPeople()
 	mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
 	mCommitCallbackRegistrar.add("People.AddFriendWizard",	boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked,	this));
 	mCommitCallbackRegistrar.add("People.DelFriend",		boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked,	this));
-	mCommitCallbackRegistrar.add("People.Group.Activate",	boost::bind(&LLPanelPeople::onActivateButtonClicked,	this));
 	mCommitCallbackRegistrar.add("People.Group.Minus",		boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this));
-	mCommitCallbackRegistrar.add("People.ViewProfile",	boost::bind(&LLPanelPeople::onViewProfileButtonClicked,	this));
-	mCommitCallbackRegistrar.add("People.GroupInfo",	boost::bind(&LLPanelPeople::onGroupInfoButtonClicked,	this));
 	mCommitCallbackRegistrar.add("People.Chat",			boost::bind(&LLPanelPeople::onChatButtonClicked,		this));
-	mCommitCallbackRegistrar.add("People.IM",			boost::bind(&LLPanelPeople::onImButtonClicked,			this));
-	mCommitCallbackRegistrar.add("People.Call",			boost::bind(&LLPanelPeople::onCallButtonClicked,		this));
-	mCommitCallbackRegistrar.add("People.GroupCall",	boost::bind(&LLPanelPeople::onGroupCallButtonClicked,	this));
-	mCommitCallbackRegistrar.add("People.Teleport",		boost::bind(&LLPanelPeople::onTeleportButtonClicked,	this));
-	mCommitCallbackRegistrar.add("People.Share",		boost::bind(&LLPanelPeople::onShareButtonClicked,		this));
 
 	mCommitCallbackRegistrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2));
 	mCommitCallbackRegistrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2));
@@ -770,24 +762,9 @@ void LLPanelPeople::updateRecentList()
 	mRecentList->setDirty();
 }
 
-void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
-{
-	// To make sure we're referencing the right widget (a child of the button bar).
-	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
-	button->setVisible(visible);
-}
-
-void LLPanelPeople::buttonSetEnabled(const std::string& btn_name, bool enabled)
-{
-	// To make sure we're referencing the right widget (a child of the button bar).
-	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
-	button->setEnabled(enabled);
-}
-
 void LLPanelPeople::updateButtons()
 {
 	std::string cur_tab		= getActiveTabName();
-	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);
@@ -798,27 +775,14 @@ void LLPanelPeople::updateButtons()
 	bool item_selected = (selected_uuids.size() == 1);
 	bool multiple_selected = (selected_uuids.size() >= 1);
 
-	buttonSetVisible("group_info_btn",		group_tab_active);
-	buttonSetVisible("chat_btn",			group_tab_active);
-	buttonSetVisible("view_profile_btn",	!group_tab_active);
-	buttonSetVisible("im_btn",				!group_tab_active);
-	buttonSetVisible("call_btn",			!group_tab_active);
-	buttonSetVisible("group_call_btn",		group_tab_active);
-	buttonSetVisible("teleport_btn",		friends_tab_active);
-	buttonSetVisible("share_btn",			nearby_tab_active || friends_tab_active);
-
 	if (group_tab_active)
 	{
-		bool cur_group_active = true;
-
 		if (item_selected)
 		{
 			selected_id = mGroupList->getSelectedUUID();
-			cur_group_active = (gAgent.getGroupID() == selected_id);
 		}
 
 		LLPanel* groups_panel = mTabContainer->getCurrentPanel();
-		groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected
 		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
 	}
 	else
@@ -844,19 +808,6 @@ void LLPanelPeople::updateButtons()
 			}
 		}
 	}
-
-	bool enable_calls = LLVoiceClient::getInstance()->isVoiceWorking() && LLVoiceClient::getInstance()->voiceEnabled();
-
-	buttonSetEnabled("view_profile_btn",item_selected);
-	buttonSetEnabled("share_btn",		item_selected);
-	buttonSetEnabled("im_btn",			multiple_selected); // allow starting the friends conference for multiple selection
-	buttonSetEnabled("call_btn",		multiple_selected && enable_calls);
-	buttonSetEnabled("teleport_btn",	multiple_selected && LLAvatarActions::canOfferTeleport(selected_uuids));
-
-	bool none_group_selected = item_selected && selected_id.isNull();
-	buttonSetEnabled("group_info_btn", !none_group_selected);
-	buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls);
-	buttonSetEnabled("chat_btn", !none_group_selected);
 }
 
 std::string LLPanelPeople::getActiveTabName() const
@@ -1082,12 +1033,6 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
 	updateButtons();
 }
 
-void LLPanelPeople::onViewProfileButtonClicked()
-{
-	LLUUID id = getCurrentItemID();
-	LLAvatarActions::showProfile(id);
-}
-
 void LLPanelPeople::onAddFriendButtonClicked()
 {
 	LLUUID id = getCurrentItemID();
@@ -1141,11 +1086,6 @@ void LLPanelPeople::onDeleteFriendButtonClicked()
 	}
 }
 
-void LLPanelPeople::onGroupInfoButtonClicked()
-{
-	LLGroupActions::show(getCurrentItemID());
-}
-
 void LLPanelPeople::onChatButtonClicked()
 {
 	LLUUID group_id = getCurrentItemID();
@@ -1169,11 +1109,6 @@ void LLPanelPeople::onImButtonClicked()
 	}
 }
 
-void LLPanelPeople::onActivateButtonClicked()
-{
-	LLGroupActions::activate(mGroupList->getSelectedUUID());
-}
-
 // static
 void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
 {
@@ -1327,40 +1262,6 @@ bool LLPanelPeople::onRecentViewSortMenuItemCheck(const LLSD& userdata)
 	return false;
 }
 
-void LLPanelPeople::onCallButtonClicked()
-{
-	uuid_vec_t selected_uuids;
-	getCurrentItemIDs(selected_uuids);
-
-	if (selected_uuids.size() == 1)
-	{
-		// initiate a P2P voice chat with the selected user
-		LLAvatarActions::startCall(getCurrentItemID());
-	}
-	else if (selected_uuids.size() > 1)
-	{
-		// initiate an ad-hoc voice chat with multiple users
-		LLAvatarActions::startAdhocCall(selected_uuids);
-	}
-}
-
-void LLPanelPeople::onGroupCallButtonClicked()
-{
-	LLGroupActions::startCall(getCurrentItemID());
-}
-
-void LLPanelPeople::onTeleportButtonClicked()
-{
-	uuid_vec_t selected_uuids;
-	getCurrentItemIDs(selected_uuids);
-	LLAvatarActions::offerTeleport(selected_uuids);
-}
-
-void LLPanelPeople::onShareButtonClicked()
-{
-	LLAvatarActions::share(getCurrentItemID());
-}
-
 void LLPanelPeople::onMoreButtonClicked()
 {
 	// *TODO: not implemented yet
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 765e62ffa6..c99bc532ab 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -80,27 +80,18 @@ private:
 	std::string				getActiveTabName() const;
 	LLUUID					getCurrentItemID() const;
 	void					getCurrentItemIDs(uuid_vec_t& selected_uuids) const;
-	void					buttonSetVisible(std::string btn_name, BOOL visible);
-	void					buttonSetEnabled(const std::string& btn_name, bool enabled);
 	void					showGroupMenu(LLMenuGL* menu);
 	void					setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true);
 
 	// UI callbacks
 	void					onFilterEdit(const std::string& search_string);
 	void					onTabSelected(const LLSD& param);
-	void					onViewProfileButtonClicked();
 	void					onAddFriendButtonClicked();
 	void					onAddFriendWizButtonClicked();
 	void					onDeleteFriendButtonClicked();
-	void					onGroupInfoButtonClicked();
 	void					onChatButtonClicked();
 	void					onImButtonClicked();
-	void					onCallButtonClicked();
-	void					onGroupCallButtonClicked();
-	void					onTeleportButtonClicked();
-	void					onShareButtonClicked();
 	void					onMoreButtonClicked();
-	void					onActivateButtonClicked();
 	void					onAvatarListDoubleClicked(LLUICtrl* ctrl);
 	void					onAvatarListCommitted(LLAvatarList* list);
 	bool					onGroupPlusButtonValidate();
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 03b6c4fb8b..f2f6bdd84d 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -55,8 +55,8 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 	 name="AltMiniMapToolTipMsg"
 	 value="[REGION](Double-click to teleport, shift-drag to pan)"/>
     <tab_container
+     bottom="-10"
      follows="all"
-     height="419"
      layout="topleft"
      left="3"
      name="tabs"
@@ -75,15 +75,15 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          background_visible="true"
          bg_alpha_color="DkGray"
          bg_opaque_color="DkGray"
+         bottom="-1"
          follows="all"
-         height="383"
          label="NEARBY"
          layout="topleft"
          left="0"
          help_topic="people_nearby_tab"
          name="nearby_panel"
-         top="0"
-         width="313">
+         right="-1"
+         top="0">
             <panel
              follows="left|top|right"
              height="27"
@@ -91,20 +91,20 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              layout="topleft"
              left="0"
              name="nearby_buttons_panel"
-             top="0"
-             width="313">
+             right="-1"
+             top="0">
                 <filter_editor
                  follows="left|top|right"
                  height="23"
                  layout="topleft"
-                 left="3"
+                 left="6"
                  label="Filter People"
                  max_length_chars="300"
                  name="nearby_filter_input"
                  text_color="Black"
                  text_pad_left="10"
-                 top="2"
-                 width="167" />
+                 top="4"
+                 width="178" />
                 <menu_button
                  follows="right"
                  height="25"
@@ -113,11 +113,11 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="10"
+                 left_pad="7"
                  menu_filename="menu_people_nearby_view.xml"
                  menu_position="bottomleft"
                  name="nearby_view_btn"
-                 top="1"
+                 top="3"
                  width="31" />
                 <menu_button
                  follows="right"
@@ -131,7 +131,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_people_nearby_sort.xml"
                  menu_position="bottomleft"
                  name="nearby_sort_btn"
-                 top="1"
+                 top_delta="0"
                  width="31" />
                 <button
                  follows="right"
@@ -143,7 +143,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="2"
                  name="add_friend_btn"
-                 top="1"
+                 top_delta="0"
                  width="31">
                     <commit_callback
                      function="People.AddFriend" />
@@ -159,7 +159,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  layout="topleft"
                  name="nearby_del_btn"
-                 top="1"
+                 top_delta="0"
                  width="31">
                     <commit_callback
                      function="People.DelFriend" />
@@ -168,13 +168,13 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          <layout_stack
            clip="false"
            follows="all"
-           height="355"
+           height="410"
            layout="topleft"
            left="0"
            mouse_opaque="false"
            orientation="vertical"
-           top_pad="0"
-           width="313">
+           right="-1"
+           top_pad="0">
            <layout_panel
              height="142"
              layout="topleft"
@@ -191,16 +191,16 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                left="3"
                mouse_opaque="false"
                name="Net Map"
-               top="4"
-               width="305"/>
+               right="-1"
+               top="4" />
            </layout_panel>
            <layout_panel
              height="213"
              layout="topleft"
              min_dim="100"
              mouse_opaque="false"
-             user_resize="true"
-             width="313">
+             right="-1"
+             user_resize="true">
              <avatar_list
                allow_select="true"
                follows="all"
@@ -211,8 +211,8 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                keep_one_selected="false"
                multi_select="true"
                name="avatar_list"
-               top="2"
-               width="306" />
+               right="-1"
+               top="2" />
            </layout_panel>
          </layout_stack>
         </panel>
@@ -224,15 +224,15 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
        background_visible="true"
          bg_alpha_color="DkGray"
          bg_opaque_color="DkGray"
+         bottom="-1"
          follows="all"
-         height="383"
          label="MY FRIENDS"
          layout="topleft"
          left="0"
          help_topic="people_friends_tab"
          name="friends_panel"
-         top="0"
-         width="313">
+         right="-1"
+         top="0">
             <panel
              follows="left|top|right"
              height="27"
@@ -240,20 +240,20 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              layout="topleft"
              left="0"
              name="friends_buttons_panel"
-             top="0"
-             width="313">
+             right="-1"
+             top="0">
                 <filter_editor
                  follows="left|top|right"
                  height="23"
                  layout="topleft"
-                 left="3"
+                 left="6"
                  label="Filter People"
                  max_length_chars="300"
                  name="friends_filter_input"
                  text_color="Black"
                  text_pad_left="10"
-                 top="2"
-                 width="167" />
+                 top="4"
+                 width="177" />
                 <menu_button
                  follows="right"
                  height="25"
@@ -262,11 +262,11 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="10"
+                 left_pad="8"
                  menu_filename="menu_people_friends_view.xml"
                  menu_position="bottomleft"
                  name="friends_view_btn"
-                 top="1"
+                 top="3"
                  width="31" />
                 <menu_button
                  follows="right"
@@ -280,7 +280,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_people_friends_sort.xml"
                  menu_position="bottomleft"
                  name="friends_sort_btn"
-                 top="1"
+                 top_delta="0"
                  width="31" />
                 <button
                  follows="right"
@@ -292,7 +292,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="2"
                  name="friends_add_btn"
-                 top="1"
+                 top_delta="0"
                  width="31">
                     <commit_callback
                      function="People.AddFriendWizard" />
@@ -307,7 +307,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  layout="topleft"
                  name="friends_del_btn"
-                 top="1"
+                 top_delta="0"
                  width="31">
                     <commit_callback
                      function="People.DelFriend" />
@@ -318,12 +318,12 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
        		 bg_alpha_color="DkGray2"
        		 bg_opaque_color="DkGray2"
              follows="all"
-             height="356"
+             height="408"
              layout="topleft"
              left="3"
              name="friends_accordion"
-             top_pad="0"
-             width="307">
+             right="-2"
+             top_pad="2">
                 <accordion_tab
                  layout="topleft"
                  height="172"
@@ -365,8 +365,8 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              height="450"
              left="13"
              name="no_friends_help_text"
+             right="-13"
              top="37"
-             width="293"
              wrap="true" />
         </panel>
 
@@ -377,15 +377,15 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
        background_visible="true"
          bg_alpha_color="DkGray"
          bg_opaque_color="DkGray"
+         bottom="-1"
          follows="all"
-         height="383"
          label="MY GROUPS"
          layout="topleft"
          left="0"
          help_topic="people_groups_tab"
          name="groups_panel"
-         top="0"
-         width="313">
+         right="-1"
+         top="0">
     <!--
      *NOTE: no_groups_msg & group_list attributes are not defined as translatable in VLT. See EXT-5931
      Values are set from appropriate strings at the top of file via LLPeoplePanel::postBuild()
@@ -397,20 +397,20 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              layout="topleft"
              left="0"
              name="groups_buttons_panel"
-             top="0"
-             width="313">
+             right="-1"
+             top="0">
                 <filter_editor
                  follows="left|top|right"
                  height="23"
                  layout="topleft"
-                 left="3"
+                 left="6"
                  label="Filter Groups"
                  max_length_chars="300"
                  name="groups_filter_input"
                  text_color="Black"
                  text_pad_left="10"
-                 top="2"
-                 width="134" />
+                 top="4"
+                 width="177" />
                 <menu_button
                  follows="right"
                  height="25"
@@ -419,11 +419,11 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="10"
+                 left_pad="8"
                  menu_filename="menu_people_groups_view.xml"
                  menu_position="bottomleft"
                  name="groups_view_btn"
-                 top="1"
+                 top="3"
                  width="31" />
                 <menu_button
                  enabled="false"
@@ -436,23 +436,8 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="2"
                  name="groups_sort_btn"
-                 top="1"
+                 top_delta="0"
                  width="31" />
-                <button
-                 follows="right"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Activate_Checkmark"
-                 image_selected="Toolbar_Middle_Selected"
-                 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 left_pad="2"
-                 name="activate_btn"
-                 top="1"
-                 width="31">
-                    <commit_callback
-                     function="People.Group.Activate" />
-                </button>
                 <menu_button
                  follows="right"
                  height="25"
@@ -465,7 +450,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_group_plus.xml"
                  menu_position="bottomleft"
                  name="minus_btn"
-                 top="1"
+                 top_delta="0"
                  width="31">
                     <validate_callback
                      function="People.Group.Plus.Validate" />
@@ -480,7 +465,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  layout="topleft"
                  name="minus_btn"
-                 top="1"
+                 top_delta="0"
                  width="31">
                     <commit_callback
                      function="People.Group.Minus" />
@@ -489,12 +474,12 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
             <group_list
              allow_select="true" 
              follows="all"
-             height="356"
+             height="406"
              layout="topleft"
              left="3"
              name="group_list"
-             top_pad="0"
-             width="307" />
+             right="-2"
+             top_pad="4" />
         </panel>
 
 <!-- ================================= RECENT tab =========================== -->
@@ -511,8 +496,8 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          left="0"
          help_topic="people_recent_tab"
          name="recent_panel"
-         top="0"
-         width="313">
+         right="-1"
+         top="0">
             <panel
              follows="left|top|right"
              height="27"
@@ -520,20 +505,20 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
              layout="topleft"
              left="0"
              name="recent_buttons_panel"
-             top="0"
-             width="313">
+             right="-1"
+             top="0">
                 <filter_editor
                  follows="left|top|right"
                  height="23"
                  layout="topleft"
-                 left="3"
+                 left="6"
                  label="Filter People"
                  max_length_chars="300"
                  name="recent_filter_input"
                  text_color="Black"
                  text_pad_left="10"
-                 top="2"
-                 width="167" />
+                 top="4"
+                 width="177" />
                 <menu_button
                  follows="right"
                  height="25"
@@ -542,11 +527,11 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="10"
+                 left_pad="8"
                  menu_filename="menu_people_recent_view.xml"
                  menu_position="bottomleft"
                  name="recent_view_btn"
-                 top="1"
+                 top="3"
                  width="31" />
                 <menu_button
                  follows="right"
@@ -560,7 +545,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_people_recent_sort.xml"
                  menu_position="bottomleft"
                  name="recent_sort_btn"
-                 top="1"
+                 top_delta="0"
                  width="31" />
                 <button
                  follows="right"
@@ -572,7 +557,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="2"
                  name="add_friend_btn"
-                 top="1"
+                 top_delta="0"
                  width="31">
                     <commit_callback
                      function="People.AddFriend" />
@@ -588,7 +573,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  layout="topleft"
                  name="recent_del_btn"
-                 top="1"
+                 top_delta="0"
                  width="31">
                     <commit_callback
                      function="People.DelFriend" />
@@ -597,14 +582,14 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
             <avatar_list
              allow_select="true"
              follows="all"
-             height="356"
+             height="351"
              layout="topleft"
              left="3"
              multi_select="true"
              name="avatar_list"
              show_last_interaction_time="true"
-             top_pad="0"
-             width="307" />
+             right="-2"
+             top_pad="4" />
         </panel>
 
 <!-- ================================= BLOCKED tab ========================== -->
@@ -633,227 +618,4 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
            width="313" />
         </panel>
     </tab_container>
-    <panel
-     follows="bottom|left|right"
-     height="23"
-     layout="topleft"
-     left="8"
-     top_pad="4"
-     name="button_bar"
-     width="313">
-
-<!--********************************Profile; IM; Call, Share, Teleport********************************--> 	
-     	<layout_stack
-     	follows="bottom|left|right"
-		height="23"
-		layout="topleft"
-		name="bottom_bar_ls"
-		left="0"
-		orientation="horizontal"
-		top_pad="0"
-		width="313">
-
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left="0"
-			name="view_profile_btn_lp"
-		    auto_resize="true"
-			width="68">
-				<button
-		         follows="bottom|left|right"
-		         height="23"
-		         label="Profile"
-		         layout="topleft"
-		         left="1"
-		         name="view_profile_btn"
-		         tool_tip="Show picture, groups, and other Residents information"
-		         top="0"
-		         width="67">
-                    <commit_callback
-                     function="People.ViewProfile" />
-		        </button>
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			name="im_btn_lp"
-		    auto_resize="true"
-			width="41">
-				<button
-		         follows="bottom|left|right"
-		         left="1"
-		         height="23"
-		         label="IM"
-		         layout="topleft"
-		         name="im_btn"
-		         tool_tip="Open instant message session"
-		         top="0"
-		         width="40">
-                    <commit_callback
-                     function="People.IM" />
-		        </button>			
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			name="call_btn_lp"
-		    auto_resize="true"
-			width="52">
-				<button
-		         follows="bottom|left|right"
-		         left="1"
-		         height="23"
-		         label="Call"
-		         layout="topleft"
-		         name="call_btn"
-		         tool_tip="Call this Resident"
-		         top="0"
-		         width="51">
-                    <commit_callback
-                     function="People.Call" />
-		        </button>		
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			name="share_btn_lp"
-		    auto_resize="true"
-			width="66">
-				<button
-		         follows="bottom|left|right"
-		         left="1"
-		         height="23"
-		         label="Share"
-		         layout="topleft"
-		         name="share_btn"
-		         tool_tip="Share an inventory item"
-		         top="0"
-		         width="65">
-                    <commit_callback
-                     function="People.Share" />
-		        </button>	
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			name="teleport_btn_lp"
-		    auto_resize="true"
-			width="77">
-				<button
-		         follows="bottom|left|right"
-		         left="1"
-		         height="23"
-		         label="Teleport"
-		         layout="topleft"
-		         name="teleport_btn"
-		         tool_tip="Offer teleport"
-		         top="0"
-		         width="76">
-                    <commit_callback
-                     function="People.Teleport" />
-		        </button>
-			</layout_panel>
-		</layout_stack>
-		
-<!--********************************Group Profile; Group Chat; Group Call buttons************************-->			
-		<layout_stack
-     	follows="bottom|left|right"
-		height="23"
-		layout="topleft"
-		mouse_opaque="false"
-		name="bottom_bar_ls1"
-		left="0"
-		orientation="horizontal"
-		top="0"
-		width="313">	
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left="0"			
-			mouse_opaque="false"
-			name="group_info_btn_lp"
-		    auto_resize="true"
-			width="108">
-				<button
-		        follows="bottom|left|right"
-		        left="1"
-		        height="23"
-		        label="Group Profile"
-		        layout="topleft"
-				mouse_opaque="false"
-		        name="group_info_btn"
-		        tool_tip="Show group information"
-		        top="0"
-		        width="107">
-                    <commit_callback
-                     function="People.GroupInfo" />
-		        </button>		
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			mouse_opaque="false"
-			name="chat_btn_lp"
-		    auto_resize="true"
-			width="101">
-				<button
-		        follows="bottom|left|right"
-		        left="1"
-		        height="23"
-		        label="Group Chat"
-		        layout="topleft"
-				mouse_opaque="false"
-		        name="chat_btn"
-		        tool_tip="Open chat session"
-		        top="0"
-		        width="100">
-                    <commit_callback
-                     function="People.Chat" />
-		        </button>			
-			</layout_panel>
-		
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			mouse_opaque="false"
-			name="group_call_btn_lp"
-		    auto_resize="true"
-			width="96">
-				<button
-				follows="bottom|left|right"
-				left="1"
-				height="23"
-         		label="Group Call"
-         		layout="topleft"
-				mouse_opaque="false"
-         		name="group_call_btn"
-         		tool_tip="Call this group"
-		        top="0"
-         		width="95">
-                    <commit_callback
-                     function="People.GroupCall" />
-         	    </button>
-			</layout_panel>		
-		</layout_stack>
-    </panel>
 </panel>
-- 
cgit v1.2.3


From 33e78bfe64240f71bcc40ca34950770ce549dc69 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Sat, 14 Apr 2012 02:04:37 +0300
Subject: CHUI-78 WIP Re-combined view and sort menus in the People panel.

---
 .../default/xui/en/menu_people_friends_sort.xml    | 26 ----------------
 .../default/xui/en/menu_people_friends_view.xml    | 21 +++++++++++++
 .../skins/default/xui/en/menu_people_groups.xml    |  4 +--
 .../default/xui/en/menu_people_nearby_sort.xml     | 36 ----------------------
 .../default/xui/en/menu_people_nearby_view.xml     | 31 +++++++++++++++++++
 .../default/xui/en/menu_people_recent_sort.xml     | 26 ----------------
 .../default/xui/en/menu_people_recent_view.xml     | 21 +++++++++++++
 .../newview/skins/default/xui/en/panel_people.xml  | 35 +++++++++++----------
 8 files changed, 93 insertions(+), 107 deletions(-)
 delete mode 100644 indra/newview/skins/default/xui/en/menu_people_friends_sort.xml
 delete mode 100644 indra/newview/skins/default/xui/en/menu_people_nearby_sort.xml
 delete mode 100644 indra/newview/skins/default/xui/en/menu_people_recent_sort.xml

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_sort.xml
deleted file mode 100644
index 532e295386..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_friends_sort.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
-     name="menu_group_plus"
-     left="0" bottom="0" visible="false"
-     mouse_opaque="false">
-  <menu_item_check
-   label="Sort by Name"
-   name="sort_name">
-      <menu_item_check.on_click
-       function="People.Friends.ViewSort.Action"
-       parameter="sort_name" />
-      <menu_item_check.on_check
-       function="People.Friends.ViewSort.CheckItem"
-       parameter="sort_name" />
-  </menu_item_check>
-  <menu_item_check
-   label="Sort by Status"
-   name="sort_status">
-      <menu_item_check.on_click
-       function="People.Friends.ViewSort.Action"
-       parameter="sort_status" />
-      <menu_item_check.on_check
-       function="People.Friends.ViewSort.CheckItem"
-       parameter="sort_status" />
-  </menu_item_check>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
index 14a3e1f13d..eab7b8c085 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -3,6 +3,27 @@
      name="menu_group_plus"
      left="0" bottom="0" visible="false"
      mouse_opaque="false">
+  <menu_item_check
+   label="Sort by Name"
+   name="sort_name">
+      <menu_item_check.on_click
+       function="People.Friends.ViewSort.Action"
+       parameter="sort_name" />
+      <menu_item_check.on_check
+       function="People.Friends.ViewSort.CheckItem"
+       parameter="sort_name" />
+  </menu_item_check>
+  <menu_item_check
+   label="Sort by Status"
+   name="sort_status">
+      <menu_item_check.on_click
+       function="People.Friends.ViewSort.Action"
+       parameter="sort_status" />
+      <menu_item_check.on_check
+       function="People.Friends.ViewSort.CheckItem"
+       parameter="sort_status" />
+  </menu_item_check>
+  <menu_item_separator layout="topleft" />
   <menu_item_check name="view_icons" label="View People Icons">
     <menu_item_check.on_click
      function="People.Friends.ViewSort.Action"
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups.xml b/indra/newview/skins/default/xui/en/menu_people_groups.xml
index 8f89d37dbb..3a450258fa 100644
--- a/indra/newview/skins/default/xui/en/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_groups.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu name="menu_group_plus"
+<toggleable_menu name="menu_group_plus"
  left="0" bottom="0" visible="false"
  mouse_opaque="false" opaque="true" color="MenuDefaultBgColor">
   <menu_item_call
@@ -54,4 +54,4 @@
      function="People.Groups.Enable"
      parameter="leave" />
   </menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_sort.xml
deleted file mode 100644
index cf7f4f4fce..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_sort.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
-     name="menu_group_plus"
-     left="0" bottom="0" visible="false"
-     mouse_opaque="false">
-  <menu_item_check
-     label="Sort by Recent Speakers"
-     name="sort_by_recent_speakers">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_by_recent_speakers"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_by_recent_speakers"/>
-  </menu_item_check>
-  <menu_item_check
-     label="Sort by Name"
-     name="sort_name">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_name"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_name"/>
-  </menu_item_check>
-  <menu_item_check
-     label="Sort by Distance"
-     name="sort_distance">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_distance"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_distance"/>
-  </menu_item_check>
- </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
index 4c94cf53af..da88ca9f4d 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
@@ -3,6 +3,37 @@
  name="menu_group_plus"
  left="0" bottom="0" visible="false"
  mouse_opaque="false">
+    <menu_item_check
+       label="Sort by Recent Speakers"
+       name="sort_by_recent_speakers">
+      <menu_item_check.on_click
+         function="People.Nearby.ViewSort.Action"
+       parameter="sort_by_recent_speakers"/>
+      <menu_item_check.on_check
+         function="People.Nearby.ViewSort.CheckItem"
+         parameter="sort_by_recent_speakers"/>
+    </menu_item_check>
+    <menu_item_check
+       label="Sort by Name"
+       name="sort_name">
+      <menu_item_check.on_click
+         function="People.Nearby.ViewSort.Action"
+         parameter="sort_name"/>
+      <menu_item_check.on_check
+         function="People.Nearby.ViewSort.CheckItem"
+         parameter="sort_name"/>
+    </menu_item_check>
+    <menu_item_check
+       label="Sort by Distance"
+       name="sort_distance">
+      <menu_item_check.on_click
+         function="People.Nearby.ViewSort.Action"
+         parameter="sort_distance"/>
+      <menu_item_check.on_check
+         function="People.Nearby.ViewSort.CheckItem"
+         parameter="sort_distance"/>
+    </menu_item_check>
+    <menu_item_separator layout="topleft" />
     <menu_item_check name="view_icons" label="View People Icons">
         <menu_item_check.on_click
          function="People.Nearby.ViewSort.Action"
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_sort.xml
deleted file mode 100644
index f14be88780..0000000000
--- a/indra/newview/skins/default/xui/en/menu_people_recent_sort.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu 
-     name="menu_group_plus"
-     left="0" bottom="0" visible="false"
-     mouse_opaque="false">
-  <menu_item_check
-   label="Sort by Most Recent"
-   name="sort_most">
-      <menu_item_check.on_click
-       function="People.Recent.ViewSort.Action"
-       parameter="sort_recent" />
-      <menu_item_check.on_check
-       function="People.Recent.ViewSort.CheckItem"
-       parameter="sort_recent" />
-  </menu_item_check>
-  <menu_item_check
-   label="Sort by Name"
-   name="sort_name">
-      <menu_item_check.on_click
-       function="People.Recent.ViewSort.Action"
-       parameter="sort_name" />
-      <menu_item_check.on_check
-       function="People.Recent.ViewSort.CheckItem"
-       parameter="sort_name" />
-  </menu_item_check>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
index 0eaca47d9a..1dbc90dd2b 100644
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
@@ -3,6 +3,27 @@
      name="menu_group_plus"
      left="0" bottom="0" visible="false"
      mouse_opaque="false">
+  <menu_item_check
+   label="Sort by Most Recent"
+   name="sort_most">
+      <menu_item_check.on_click
+       function="People.Recent.ViewSort.Action"
+       parameter="sort_recent" />
+      <menu_item_check.on_check
+       function="People.Recent.ViewSort.CheckItem"
+       parameter="sort_recent" />
+  </menu_item_check>
+  <menu_item_check
+   label="Sort by Name"
+   name="sort_name">
+      <menu_item_check.on_click
+       function="People.Recent.ViewSort.Action"
+       parameter="sort_name" />
+      <menu_item_check.on_check
+       function="People.Recent.ViewSort.CheckItem"
+       parameter="sort_name" />
+  </menu_item_check>
+  <menu_item_separator layout="topleft" />
   <menu_item_check name="view_icons" label="View People Icons">
     <menu_item_check.on_click
      function="People.Recent.ViewSort.Action"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index f2f6bdd84d..ca28e3153c 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -114,9 +114,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="7"
-                 menu_filename="menu_people_nearby_view.xml"
+                 menu_filename="menu_people_nearby_gear.xml"
                  menu_position="bottomleft"
-                 name="nearby_view_btn"
+                 name="nearby_gear_btn"
                  top="3"
                  width="31" />
                 <menu_button
@@ -128,9 +128,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 menu_filename="menu_people_nearby_sort.xml"
+                 menu_filename="menu_people_nearby_view.xml"
                  menu_position="bottomleft"
-                 name="nearby_sort_btn"
+                 name="nearby_view_btn"
                  top_delta="0"
                  width="31" />
                 <button
@@ -263,9 +263,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="8"
-                 menu_filename="menu_people_friends_view.xml"
+                 menu_filename="menu_people_friends_gear.xml"
                  menu_position="bottomleft"
-                 name="friends_view_btn"
+                 name="friends_gear_btn"
                  top="3"
                  width="31" />
                 <menu_button
@@ -277,9 +277,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 menu_filename="menu_people_friends_sort.xml"
+                 menu_filename="menu_people_friends_view.xml"
                  menu_position="bottomleft"
-                 name="friends_sort_btn"
+                 name="friends_view_btn"
                  top_delta="0"
                  width="31" />
                 <button
@@ -420,13 +420,12 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="8"
-                 menu_filename="menu_people_groups_view.xml"
+                 menu_filename="menu_people_groups.xml"
                  menu_position="bottomleft"
-                 name="groups_view_btn"
+                 name="groups_gear_btn"
                  top="3"
                  width="31" />
                 <menu_button
-                 enabled="false"
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
@@ -435,7 +434,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 name="groups_sort_btn"
+                 menu_filename="menu_people_groups_view.xml"
+                 menu_position="bottomleft"
+                 name="groups_view_btn"
                  top_delta="0"
                  width="31" />
                 <menu_button
@@ -449,7 +450,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  menu_filename="menu_group_plus.xml"
                  menu_position="bottomleft"
-                 name="minus_btn"
+                 name="plus_btn"
                  top_delta="0"
                  width="31">
                     <validate_callback
@@ -528,9 +529,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="8"
-                 menu_filename="menu_people_recent_view.xml"
+                 menu_filename="menu_people_recent_gear.xml"
                  menu_position="bottomleft"
-                 name="recent_view_btn"
+                 name="recent_gear_btn"
                  top="3"
                  width="31" />
                 <menu_button
@@ -542,9 +543,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="2"
-                 menu_filename="menu_people_recent_sort.xml"
+                 menu_filename="menu_people_recent_view.xml"
                  menu_position="bottomleft"
-                 name="recent_sort_btn"
+                 name="recent_view_btn"
                  top_delta="0"
                  width="31" />
                 <button
-- 
cgit v1.2.3


From 2412401e4c705c7073be845bba74353d446bd017 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Sat, 14 Apr 2012 21:03:36 +0300
Subject: CHUI-78 WIP Minor cleanup.

---
 indra/llui/llmenubutton.cpp       | 6 +++---
 indra/newview/lllistcontextmenu.h | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 98f7e0540c..320f62d5c1 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -76,7 +76,7 @@ void LLMenuButton::hideMenu()
 {
 	if(mMenuHandle.isDead()) return;
 
-	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+	LLToggleableMenu* menu = getMenu();
 	if (menu)
 	{
 		menu->setVisible(FALSE);
@@ -132,7 +132,7 @@ BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
 		return TRUE;
 	}
 
-	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+	LLToggleableMenu* menu = getMenu();
 	if (menu && menu->getVisible() && key == KEY_ESCAPE && mask == MASK_NONE)
 	{
 		menu->setVisible(FALSE);
@@ -160,7 +160,7 @@ void LLMenuButton::toggleMenu()
 
 	if(mMenuHandle.isDead()) return;
 
-	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+	LLToggleableMenu* menu = getMenu();
 	if (!menu) return;
 
 	// Store the button rectangle to toggle menu visibility if a mouse event
diff --git a/indra/newview/lllistcontextmenu.h b/indra/newview/lllistcontextmenu.h
index fabd68ee20..04d3314829 100644
--- a/indra/newview/lllistcontextmenu.h
+++ b/indra/newview/lllistcontextmenu.h
@@ -37,7 +37,7 @@ class LLContextMenu;
 /**
  * Context menu for single or multiple list items.
  * 
- * Derived classes must implement contextMenu().
+ * Derived classes must implement createMenu().
  * 
  * Typical usage:
  * <code>
-- 
cgit v1.2.3


From 590890173216570ca834ba1ead66db1a25952247 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Sat, 14 Apr 2012 21:04:37 +0300
Subject: CHUI-78 WIP Made the gear buttons spawn the avatar list context menu.

---
 indra/newview/llpanelpeople.cpp                     | 14 ++++++++++++++
 indra/newview/llpanelpeople.h                       |  1 +
 indra/newview/skins/default/xui/en/panel_people.xml | 21 +++++++++------------
 3 files changed, 24 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index a9da9e0cbf..6c3f07920b 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -511,6 +511,7 @@ LLPanelPeople::LLPanelPeople()
 	mCommitCallbackRegistrar.add("People.DelFriend",		boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked,	this));
 	mCommitCallbackRegistrar.add("People.Group.Minus",		boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this));
 	mCommitCallbackRegistrar.add("People.Chat",			boost::bind(&LLPanelPeople::onChatButtonClicked,		this));
+	mCommitCallbackRegistrar.add("People.Gear",			boost::bind(&LLPanelPeople::onGearButtonClicked,		this, _1));
 
 	mCommitCallbackRegistrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2));
 	mCommitCallbackRegistrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2));
@@ -806,6 +807,11 @@ void LLPanelPeople::updateButtons()
 			{
 				cur_panel->getChildView("friends_del_btn")->setEnabled(multiple_selected);
 			}
+
+			if (!group_tab_active)
+			{
+				cur_panel->getChildView("gear_btn")->setEnabled(multiple_selected);
+			}
 		}
 	}
 }
@@ -1093,6 +1099,14 @@ void LLPanelPeople::onChatButtonClicked()
 		LLGroupActions::startIM(group_id);
 }
 
+void LLPanelPeople::onGearButtonClicked(LLUICtrl* btn)
+{
+	uuid_vec_t selected_uuids;
+	getCurrentItemIDs(selected_uuids);
+	// Spawn at bottom left corner of the button.
+	LLPanelPeopleMenus::gNearbyMenu.show(btn, selected_uuids, 0, 0);
+}
+
 void LLPanelPeople::onImButtonClicked()
 {
 	uuid_vec_t selected_uuids;
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index c99bc532ab..da27f83074 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -90,6 +90,7 @@ private:
 	void					onAddFriendWizButtonClicked();
 	void					onDeleteFriendButtonClicked();
 	void					onChatButtonClicked();
+	void					onGearButtonClicked(LLUICtrl* btn);
 	void					onImButtonClicked();
 	void					onMoreButtonClicked();
 	void					onAvatarListDoubleClicked(LLUICtrl* ctrl);
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index ca28e3153c..262c7cbf2c 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -105,7 +105,8 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  text_pad_left="10"
                  top="4"
                  width="178" />
-                <menu_button
+                <button
+                 commit_callback.function="People.Gear"
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
@@ -114,9 +115,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="7"
-                 menu_filename="menu_people_nearby_gear.xml"
-                 menu_position="bottomleft"
-                 name="nearby_gear_btn"
+                 name="gear_btn"
                  top="3"
                  width="31" />
                 <menu_button
@@ -254,7 +253,8 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  text_pad_left="10"
                  top="4"
                  width="177" />
-                <menu_button
+                <button
+                 commit_callback.function="People.Gear"
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
@@ -263,9 +263,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="8"
-                 menu_filename="menu_people_friends_gear.xml"
-                 menu_position="bottomleft"
-                 name="friends_gear_btn"
+                 name="gear_btn"
                  top="3"
                  width="31" />
                 <menu_button
@@ -520,7 +518,8 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  text_pad_left="10"
                  top="4"
                  width="177" />
-                <menu_button
+                <button
+                 commit_callback.function="People.Gear"
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
@@ -529,9 +528,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="8"
-                 menu_filename="menu_people_recent_gear.xml"
-                 menu_position="bottomleft"
-                 name="recent_gear_btn"
+                 name="gear_btn"
                  top="3"
                  width="31" />
                 <menu_button
-- 
cgit v1.2.3


From 3adf89351359210f6f8a0f33cef94733a815dea1 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Sat, 14 Apr 2012 22:28:49 +0300
Subject: CHU-78 WIP Subtle cleanup.

---
 indra/llui/llmenubutton.cpp | 13 +++++--------
 indra/llui/llmenugl.cpp     |  5 -----
 indra/llui/llmenugl.h       |  2 --
 3 files changed, 5 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 320f62d5c1..746ade4648 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -74,8 +74,6 @@ boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_sign
 
 void LLMenuButton::hideMenu()
 {
-	if(mMenuHandle.isDead()) return;
-
 	LLToggleableMenu* menu = getMenu();
 	if (menu)
 	{
@@ -120,7 +118,7 @@ void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_T
 
 BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
 {
-	if (mMenuHandle.isDead()) return FALSE;
+	if (!getMenu()) return FALSE;
 
 	if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
 	{
@@ -158,8 +156,6 @@ void LLMenuButton::toggleMenu()
 		return;
 	}
 
-	if(mMenuHandle.isDead()) return;
-
 	LLToggleableMenu* menu = getMenu();
 	if (!menu) return;
 
@@ -189,7 +185,8 @@ void LLMenuButton::toggleMenu()
 
 void LLMenuButton::updateMenuOrigin()
 {
-	if (mMenuHandle.isDead()) return;
+	LLToggleableMenu* menu = getMenu();
+	if (!menu) return;
 
 	LLRect rect = getRect();
 
@@ -198,12 +195,12 @@ void LLMenuButton::updateMenuOrigin()
 		case MP_TOP_LEFT:
 		{
 			mX = rect.mLeft;
-			mY = rect.mTop + mMenuHandle.get()->getRect().getHeight();
+			mY = rect.mTop + menu->getRect().getHeight();
 			break;
 		}
 		case MP_TOP_RIGHT:
 		{
-			const LLRect& menu_rect = mMenuHandle.get()->getRect();
+			const LLRect& menu_rect = menu->getRect();
 			mX = rect.mRight - menu_rect.getWidth();
 			mY = rect.mTop + menu_rect.getHeight();
 			break;
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 95ecbb1c94..62b695fedb 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -4021,11 +4021,6 @@ BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )
 	return result;
 }
 
-void LLContextMenu::draw()
-{
-	LLMenuGL::draw();
-}
-
 BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)
 {
 	
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 36f3ba34b9..c6ee5434b0 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -668,8 +668,6 @@ public:
 	// can't set visibility directly, must call show or hide
 	virtual void	setVisible			(BOOL visible);
 	
-	virtual void	draw				();
-	
 	virtual void	show				(S32 x, S32 y);
 	virtual void	hide				();
 
-- 
cgit v1.2.3


From aa4a9059037d3e75d2c93d7889b460978d41fde1 Mon Sep 17 00:00:00 2001
From: Vadim ProductEngine <vsavchuk@productengine.com>
Date: Tue, 17 Apr 2012 15:44:04 +0300
Subject: CHUI-91 ADDITIONAL_FIX Minor visual layout fixes.

---
 indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml | 9 +++++----
 indra/newview/skins/default/xui/en/panel_people.xml              | 9 ++++++---
 2 files changed, 11 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index 84b772d256..18532da593 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -4,20 +4,21 @@
  follows="left|top|right|bottom"
  height="305"
  layout="topleft"
+ left="0"
  name="block_list_panel"
  help_topic="blocked_list"
  min_height="350"
  min_width="240"
- width="280">
+ right="-1">
     <scroll_list
      follows="all"
      height="220"
      layout="topleft"
-     left="5"
+     left="3"
      name="blocked"
      tool_tip="List of currently blocked Residents"
-     top="0"
-     width="270">
+     right="-1"
+     top="1">
         <scroll_list.columns
          name="item_name" />
         <scroll_list.columns
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 262c7cbf2c..abfb9c7a36 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -604,16 +604,19 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          left="0"
          help_topic="people_blocked_tab"
          name="blocked_panel"
-         top="0"
-         width="313">
+         right="-1"
+         top="0">
           <panel
            class="panel_block_list_sidetray"
            height="383"
            name="panel_block_list_sidetray"
            filename="panel_block_list_sidetray.xml"
+           follows="all"
            label="Blocked Residents &amp; Objects"
+           left="0"
            font="SansSerifBold"
-           width="313" />
+           top="0"
+           right="-1" />
         </panel>
     </tab_container>
 </panel>
-- 
cgit v1.2.3


From 37186d452fcb94b13e34d01aa801e7db17ee353e Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 17 Apr 2012 14:13:31 -0700
Subject: CHUI-86 WIP Investigate voice-dot with name tag integration added
 draw3D to LLUIImage to encapsulate display of image in projective 3D space

---
 indra/llui/llui.cpp            | 152 +++++++++++++++++++----------------------
 indra/llui/llui.h              |   3 +-
 indra/llui/lluiimage.cpp       |  44 ++++++++++++
 indra/llui/lluiimage.h         |   4 +-
 indra/newview/llhudnametag.cpp |  96 ++++++++++++--------------
 5 files changed, 160 insertions(+), 139 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index b52b0355fe..46882850cc 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1464,144 +1464,132 @@ void gl_segmented_rect_2d_fragment_tex(const S32 left,
 	gGL.popUIMatrix();
 }
 
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, 
-							  const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
-							  const U32 edges)
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, 
+							 const LLVector3& width_vec, const LLVector3& height_vec)
 {
-	LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
-	LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
-
-	LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
-	LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
-
-
 	gGL.begin(LLRender::QUADS);
 	{
 		// draw bottom left
-		gGL.texCoord2f(0.f, 0.f);
+		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
 		gGL.vertex3f(0.f, 0.f, 0.f);
 
-		gGL.texCoord2f(border_scale.mV[VX], 0.f);
-		gGL.vertex3fv(left_border_width.mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
 
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(0.f, border_scale.mV[VY]);
-		gGL.vertex3fv(bottom_border_height.mV);
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
 
 		// draw bottom middle
-		gGL.texCoord2f(border_scale.mV[VX], 0.f);
-		gGL.vertex3fv(left_border_width.mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
-		gGL.vertex3fv((width_vec - right_border_width).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
 
 		// draw bottom right
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
-		gGL.vertex3fv((width_vec - right_border_width).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
 
-		gGL.texCoord2f(1.f, 0.f);
+		gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
 		gGL.vertex3fv(width_vec.mV);
 
-		gGL.texCoord2f(1.f, border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + bottom_border_height).mV);
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
 
 		// draw left 
-		gGL.texCoord2f(0.f, border_scale.mV[VY]);
-		gGL.vertex3fv(bottom_border_height.mV);
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((height_vec - top_border_height).mV);
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
 
 		// draw middle
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
 
 		// draw right 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(1.f, border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + bottom_border_height).mV);
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
 
-		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
 
 		// draw top left
-		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((height_vec - top_border_height).mV);
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((left_border_width + height_vec).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
 
-		gGL.texCoord2f(0.f, 1.f);
+		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
 		gGL.vertex3fv((height_vec).mV);
 
 		// draw top middle
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
 
-		gGL.texCoord2f(border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((left_border_width + height_vec).mV);
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
 
 		// draw top right
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
 
-		gGL.texCoord2f(1.f, 1.f);
+		gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
 		gGL.vertex3fv((width_vec + height_vec).mV);
 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
 	}
 	gGL.end();
 
 }
 
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec)
-{
-	gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
-}
 
 void LLUI::initClass(const settings_map_t& settings,
 					 LLImageProviderInterface* image_provider,
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 618ed2fc42..eafae10c49 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -127,8 +127,7 @@ typedef enum e_rounded_edge
 
 void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
 void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLVector3& width_vec, const LLVector3& height_vec);
 
 inline void gl_rect_2d( const LLRect& rect, BOOL filled )
 {
diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
index 6ae42c8852..a4886dabb0 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llui/lluiimage.cpp
@@ -112,6 +112,50 @@ void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4&
 	drawSolid(border_rect, color);
 }
 
+void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, 
+						const LLRect& rect, const LLColor4& color)
+{
+	F32 border_scale = 1.f;
+	F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
+	F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
+	if (rect.getHeight() < border_height || rect.getWidth() < border_width)
+	{
+		 if(border_height - rect.getHeight() > border_width - rect.getWidth())
+		 {
+			 border_scale = (F32)rect.getHeight() / border_height;
+		 }
+		 else
+		 {
+			border_scale = (F32)rect.getWidth() / border_width;
+		 }
+	}
+
+	LLUI::pushMatrix();
+	{ 
+		LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis); 
+		LLUI::translate(rect_origin.mV[VX],
+						rect_origin.mV[VY], 
+						rect_origin.mV[VZ]);
+		gGL.getTexUnit(0)->bind(getImage());
+		gGL.color4fv(color.mV);
+
+		LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
+							mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
+							mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
+							mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
+		gl_segmented_rect_3d_tex(mClipRegion,
+								center_uv_rect,
+								LLRectf(border_width * border_scale * 0.5f,
+										1.f - (border_height * border_scale * 0.5f),
+										1.f - (border_width * border_scale * 0.5f),
+										border_height * border_scale * 0.5f),
+								rect.getWidth() * x_axis, 
+								rect.getHeight() * y_axis);
+		
+	} LLUI::popMatrix();
+}
+
+
 S32 LLUIImage::getWidth() const
 { 
 	// return clipped dimensions of actual image area
diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h
index b86ea67505..7817ba1c7b 100644
--- a/indra/llui/lluiimage.h
+++ b/indra/llui/lluiimage.h
@@ -64,7 +64,9 @@ public:
 	void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
 	void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
 	void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
-	
+
+	void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
+
 	const std::string& getName() const { return mName; }
 
 	virtual S32 getWidth() const;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index cf55954d7d..26c3ee8c7a 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -166,7 +166,6 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
 	}
 
 	// scale screen size of borders down
-	//RN: for now, text on hud objects is never occluded
 
 	LLVector3 x_pixel_vec;
 	LLVector3 y_pixel_vec;
@@ -191,7 +190,6 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
 		+ (F32)mOffsetY * y_pixel_vec
 		- (width_vec / 2.f)
 		- (height_vec);
-	//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
 
 	LLVector3 v[] = 
 	{
@@ -201,18 +199,6 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
 		bg_pos + height_vec,
 	};
 
-	if (debug_render)
-	{
-		gGL.begin(LLRender::LINE_STRIP);
-		gGL.vertex3fv(v[0].mV);
-		gGL.vertex3fv(v[1].mV);
-		gGL.vertex3fv(v[2].mV);
-		gGL.vertex3fv(v[3].mV);
-		gGL.vertex3fv(v[0].mV);
-		gGL.vertex3fv(v[2].mV);
-		gGL.end();
-	}
-
 	LLVector3 dir = end-start;
 	F32 a, b, t;
 
@@ -334,46 +320,48 @@ void LLHUDNameTag::renderText(BOOL for_select)
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-	LLUI::pushMatrix();
-	{
-		LLVector3 bg_pos = render_position
-			+ (F32)mOffsetY * y_pixel_vec
-			- (width_vec / 2.f)
-			- (height_vec);
-		LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
-
-		if (for_select)
-		{
-			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-			S32 name = mSourceObject->mGLName;
-			LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
-			gGL.color4ubv(coloru.mV);
-			gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-			LLUI::popMatrix();
-			return;
-		}
-		else
-		{
-			gGL.getTexUnit(0)->bind(imagep->getImage());
-				
-			gGL.color4fv(bg_color.mV);
-			gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-		
-			if ( mLabelSegments.size())
-			{
-				LLUI::pushMatrix();
-				{
-					gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
-					LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
-					LLVector3 label_offset = height_vec - label_height;
-					LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
-					gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
-				}
-				LLUI::popMatrix();
-			}
-		}
-	}
-	LLUI::popMatrix();
+	LLRect screen_rect;
+	screen_rect.setCenterAndSize(0, -mHeight / 2 + mOffsetY, mWidth, mHeight);
+	imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
+	if (mLabelSegments.size())
+	{
+		LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");
+		LLRect label_top_rect = screen_rect;
+		const S32 label_height = llround((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
+		label_top_rect.mBottom = label_top_rect.mTop - label_height;
+		LLColor4 label_top_color = text_color;
+		label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
+
+		rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
+
+	}
+	//LLUI::pushMatrix();
+	//{
+	//	LLVector3 bg_pos = render_position
+	//		+ (F32)mOffsetY * y_pixel_vec
+	//		- (width_vec / 2.f)
+	//		- (height_vec);
+	//	LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+
+	//	gGL.getTexUnit(0)->bind(imagep->getImage());
+	//			
+	//	gGL.color4fv(bg_color.mV);
+	//	gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
+	//	
+	//	if ( mLabelSegments.size())
+	//	{
+	//		LLUI::pushMatrix();
+	//		{
+	//			gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
+	//			LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
+	//			LLVector3 label_offset = height_vec - label_height;
+	//			LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
+	//			gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
+	//		}
+	//		LLUI::popMatrix();
+	//	}
+	//}
+	//LLUI::popMatrix();
 
 	F32 y_offset = (F32)mOffsetY;
 		
-- 
cgit v1.2.3


From 234ce663fa52a588662153e6e465a53643c4e0f4 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 17 Apr 2012 15:14:36 -0700
Subject: fixed build

---
 indra/llui/llui.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index eafae10c49..1fbfbd7a07 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -127,7 +127,7 @@ typedef enum e_rounded_edge
 
 void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
 void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLVector3& width_vec, const LLVector3& height_vec);
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
 
 inline void gl_rect_2d( const LLRect& rect, BOOL filled )
 {
-- 
cgit v1.2.3


From 8c5819bdde26ad748060be53a2b6fefe809ad18b Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Tue, 17 Apr 2012 16:42:38 -0700
Subject: CHUI-86: Removing the LLHUDEffect parent class from the
 LLVoiceVisualizer.  #ifdef'ing the code out for now, to be removed later.

---
 indra/newview/llfollowcam.cpp       |    1 -
 indra/newview/llhudobject.cpp       |    8 +-
 indra/newview/llhudobject.h         |    4 +-
 indra/newview/llvoavatar.cpp        |   14 +
 indra/newview/llvoicevisualizer.cpp | 1267 ++++++++++++++++++-----------------
 indra/newview/llvoicevisualizer.h   |   37 +-
 6 files changed, 695 insertions(+), 636 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp
index b670af1782..47612fe25c 100644
--- a/indra/newview/llfollowcam.cpp
+++ b/indra/newview/llfollowcam.cpp
@@ -38,7 +38,6 @@ std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack;
 //-------------------------------------------------------
 // constants
 //-------------------------------------------------------
-const F32 ONE_HALF							= 0.5; 
 const F32 FOLLOW_CAM_ZOOM_FACTOR			= 0.1f;
 const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT		= 0.1f;
 const F32 DISTANCE_EPSILON					= 0.0001f;
diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 95d57d08d8..06b0c3c6c8 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -232,9 +232,11 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type)
 	case LL_HUD_EFFECT_LOOKAT:
 		hud_objectp = new LLHUDEffectLookAt(type);
 		break;
-	case LL_HUD_EFFECT_VOICE_VISUALIZER:
-		hud_objectp = new LLVoiceVisualizer(type);
-		break;
+#ifdef XXX_STINSON_CHUI_REWORK
+	case LL_HUD_EFFECT_VOICE_VISUALIZER:
+		hud_objectp = new LLVoiceVisualizer(type);
+		break;
+#endif // XXX_STINSON_CHUI_REWORK
 	case LL_HUD_EFFECT_POINTAT:
 		hud_objectp = new LLHUDEffectPointAt(type);
 		break;
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 2f7a98c86c..6f8be41177 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -94,7 +94,9 @@ public:
 		LL_HUD_EFFECT_EDIT,
 		LL_HUD_EFFECT_LOOKAT,
 		LL_HUD_EFFECT_POINTAT,
-		LL_HUD_EFFECT_VOICE_VISUALIZER,	// Ventrella
+#ifdef XXX_STINSON_CHUI_REWORK
+		LL_HUD_EFFECT_VOICE_VISUALIZER,	// Ventrella
+#endif // XXX_STINSON_CHUI_REWORK
 		LL_HUD_NAME_TAG,
 		LL_HUD_EFFECT_BLOB
 	};
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b420812a3c..e1d29da664 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -709,9 +709,13 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
 	//VTResume();  // VTune
 	
+#ifdef XXX_STINSON_CHUI_REWORK
 	// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
 	const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
 	mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
+#else // XXX_STINSON_CHUI_REWORK
+	mVoiceVisualizer = new LLVoiceVisualizer();
+#endif // XXX_STINSON_CHUI_REWORK
 
 	lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl;
 
@@ -870,7 +874,11 @@ void LLVOAvatar::markDead()
 		mNameText = NULL;
 		sNumVisibleChatBubbles--;
 	}
+#ifdef XXX_STINSON_CHUI_REWORK
 	mVoiceVisualizer->markDead();
+#else // XXX_STINSON_CHUI_REWORK
+	mVoiceVisualizer->setStopSpeaking();
+#endif // XXX_STINSON_CHUI_REWORK
 	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
 	LLViewerObject::markDead();
 }
@@ -1328,7 +1336,9 @@ void LLVOAvatar::initInstance(void)
 	
 	//VTPause();  // VTune
 	
+#ifdef XXX_STINSON_CHUI_REWORK
 	mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
+#endif // XXX_STINSON_CHUI_REWORK
 
 }
 
@@ -2424,6 +2434,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 
 void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 {
+#ifdef XXX_STINSON_CHUI_REWORK
 	bool render_visualizer = voice_enabled;
 	
 	// Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
@@ -2436,6 +2447,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 	}
 	
 	mVoiceVisualizer->setVoiceEnabled(render_visualizer);
+#endif // XXX_STINSON_CHUI_REWORK
 	
 	if ( voice_enabled )
 	{		
@@ -2511,6 +2523,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 			}
 		}
 		
+#ifdef XXX_STINSON_CHUI_REWORK
 		//--------------------------------------------------------------------------------------------
 		// here we get the approximate head position and set as sound source for the voice symbol
 		// (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
@@ -2528,6 +2541,7 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 			tagPos[VZ] += ( mBodySize[VZ] + 0.125f );
 			mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );
 		}
+#endif // XXX_STINSON_CHUI_REWORK
 	}//if ( voiceEnabled )
 }		
 
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 47060720e7..dcf33bce10 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -1,625 +1,642 @@
-/** 
- * @file llvoicevisualizer.cpp
- * @brief Draws in-world speaking indicators.
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-//----------------------------------------------------------------------
-// Voice Visualizer
-// author: JJ Ventrella
-// (information about this stuff can be found in "llvoicevisualizer.h")
-//----------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-#include "llviewercontrol.h"
-#include "llglheaders.h"
-#include "llsphere.h"
-#include "llvoicevisualizer.h"
-#include "llviewercamera.h"
-#include "llviewerobject.h"
-#include "llviewertexture.h"
-#include "llviewertexturelist.h"
-#include "llvoiceclient.h"
-#include "llrender.h"
-
-//brent's wave image
-//29de489d-0491-fb00-7dab-f9e686d31e83
-
-
-//--------------------------------------------------------------------------------------
-// sound symbol constants
-//--------------------------------------------------------------------------------------
-const F32	HEIGHT_ABOVE_HEAD	= 0.3f;		// how many meters vertically above the av's head the voice symbol will appear
-const F32	RED_THRESHOLD		= LLVoiceClient::OVERDRIVEN_POWER_LEVEL;		// value above which speaking amplitude causes the voice symbol to turn red
-const F32	GREEN_THRESHOLD		= 0.2f;		// value above which speaking amplitude causes the voice symbol to turn green
-const F32	FADE_OUT_DURATION	= 0.4f;		// how many seconds it takes for a pair of waves to fade away
-const F32	EXPANSION_RATE		= 1.0f;		// how many seconds it takes for the waves to expand to twice their original size
-const F32	EXPANSION_MAX		= 1.5f;		// maximum size scale to which the waves can expand before popping back to 1.0 
-const F32	WAVE_WIDTH_SCALE	= 0.03f;	// base width of the waves 
-const F32	WAVE_HEIGHT_SCALE	= 0.02f;	// base height of the waves 
-const F32	BASE_BRIGHTNESS		= 0.7f;		// gray level of the voice indicator when quiet (below green threshold)
-const F32	DOT_SIZE			= 0.05f;	// size of the dot billboard texture
-const F32	DOT_OPACITY			= 0.7f;		// how opaque the dot is
-const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a function of speaking amplitude
-
-//--------------------------------------------------------------------------------------
-// gesticulation constants
-//--------------------------------------------------------------------------------------
-const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE	= 0.2f; 
-const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f;
-
-//--------------------------------------------------------------------------------------
-// other constants
-//--------------------------------------------------------------------------------------
-const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. 
-const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
-
-
-//------------------------------------------------------------------
-// handles parameter updates
-//------------------------------------------------------------------
-static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
-{
-	// Note: Ignore the specific event value, we look up the ones we want
-	LLVoiceVisualizer::setPreferences();
-	return true;
-}
-
-//------------------------------------------------------------------
-// Initialize the statics
-//------------------------------------------------------------------
-bool LLVoiceVisualizer::sPrefsInitialized	= false;
-BOOL LLVoiceVisualizer::sLipSyncEnabled		= FALSE;
-F32* LLVoiceVisualizer::sOoh				= NULL;
-F32* LLVoiceVisualizer::sAah				= NULL;
-U32	 LLVoiceVisualizer::sOohs				= 0;
-U32	 LLVoiceVisualizer::sAahs				= 0;
-F32	 LLVoiceVisualizer::sOohAahRate			= 0.0f;
-F32* LLVoiceVisualizer::sOohPowerTransfer	= NULL;
-U32	 LLVoiceVisualizer::sOohPowerTransfers	= 0;
-F32	 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
-F32* LLVoiceVisualizer::sAahPowerTransfer	= NULL;
-U32	 LLVoiceVisualizer::sAahPowerTransfers	= 0;
-F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
-
-
-//-----------------------------------------------
-// constructor
-//-----------------------------------------------
-LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
-:LLHUDEffect( type )
-{
-	mCurrentTime					= mTimer.getTotalSeconds();
-	mPreviousTime					= mCurrentTime;
-	mStartTime						= mCurrentTime;
-	mVoiceSourceWorldPosition		= LLVector3( 0.0f, 0.0f, 0.0f );
-	mSpeakingAmplitude				= 0.0f;
-	mCurrentlySpeaking				= false;
-	mVoiceEnabled					= false;
-	mMinGesticulationAmplitude		= DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
-	mMaxGesticulationAmplitude		= DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
-	mSoundSymbol.mActive			= true;
-	mSoundSymbol.mPosition			= LLVector3( 0.0f, 0.0f, 0.0f );
-	
-	mTimer.reset();
-	
-	const char* sound_level_img[] = 
-	{
-		"voice_meter_dot.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c"
-	};
-
-	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
-	{
-		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
-		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
-		mSoundSymbol.mWaveActive			[i] = false;
-		mSoundSymbol.mWaveOpacity			[i] = 1.0f;
-		mSoundSymbol.mWaveExpansion			[i] = 1.0f;
-	}
-
-	mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-
-	// The first instance loads the initial state from prefs.
-	if (!sPrefsInitialized)
-	{
-		setPreferences();
-       
-		// Set up our listener to get updates on all prefs values we care about.
-		gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		
-		sPrefsInitialized = true;
-	}
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
-{
-	mMinGesticulationAmplitude = m;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
-{
-	mMaxGesticulationAmplitude = m;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setVoiceEnabled( bool v )
-{
-	mVoiceEnabled = v;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setStartSpeaking()
-{
-	mStartTime				= mTimer.getTotalSeconds();
-	mCurrentlySpeaking		= true;
-	mSoundSymbol.mActive	= true;
-		
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-bool LLVoiceVisualizer::getCurrentlySpeaking()
-{
-	return mCurrentlySpeaking;
-	
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setStopSpeaking()
-{
-	mCurrentlySpeaking = false;
-	mSpeakingAmplitude = 0.0f;
-	
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
-{
-	mSpeakingAmplitude = a;
-	
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setPreferences( )
-{
-	sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
-	sOohAahRate		= gSavedSettings.getF32("LipSyncOohAahRate");
-
-	std::string oohString = gSavedSettings.getString("LipSyncOoh");
-	lipStringToF32s (oohString, sOoh, sOohs);
-
-	std::string aahString = gSavedSettings.getString("LipSyncAah");
-	lipStringToF32s (aahString, sAah, sAahs);
-
-	std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
-	lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
-	sOohPowerTransfersf = (F32) sOohPowerTransfers;
-
-	std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
-	lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
-	sAahPowerTransfersf = (F32) sAahPowerTransfers;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-// convert a string of digits to an array of floats.
-// the result for each digit is the value of the
-// digit multiplied by 0.11
-//---------------------------------------------------
-void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
-{
-	delete[] out_F32s;	// get rid of the current array
-
-	count_F32s = in_string.length();
-	if (count_F32s == 0)
-	{
-		// we don't like zero length arrays
-
-		count_F32s  = 1;
-		out_F32s	   = new F32[1];
-		out_F32s[0] = 0.0f;
-	}
-	else
-	{
-		out_F32s = new F32[count_F32s];
-
-		for (U32 i=0; i<count_F32s; i++)
-		{
-			// we convert the characters 0 to 9 to their numeric value
-			// anything else we take the low order four bits with a ceiling of 9
-
-		    U8 digit = in_string[i];
-			U8 four_bits = digit % 16;
-			if (four_bits > 9)
-			{
-				four_bits = 9;
-			}
-			out_F32s[i] = 0.11f * (F32) four_bits;
-		} 
-	}
-
-}//---------------------------------------------------
-
-
-//--------------------------------------------------------------------------
-// find the amount to blend the ooh and aah mouth morphs
-//--------------------------------------------------------------------------
-void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
-{
-	if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
-	{
-		U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
-		if (transfer_index >= sOohPowerTransfers)
-		{
-		   transfer_index = sOohPowerTransfers - 1;
-		}
-		F32 transfer_ooh = sOohPowerTransfer[transfer_index];
-
-		transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
-		if (transfer_index >= sAahPowerTransfers)
-		{
-		   transfer_index = sAahPowerTransfers - 1;
-		}
-		F32 transfer_aah = sAahPowerTransfer[transfer_index];
-
-		F64 current_time   = mTimer.getTotalSeconds();
-		F64 elapsed_time   = current_time - mStartTime;
-		U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
-		U32 elapsed_oohs   = elapsed_frames % sOohs;
-		U32 elapsed_aahs   = elapsed_frames % sAahs;
-
-		ooh = transfer_ooh * sOoh[elapsed_oohs];
-		aah = transfer_aah * sAah[elapsed_aahs];
-
-		/*
-		llinfos << " elapsed frames " << elapsed_frames
-				<< " ooh "            << ooh
-				<< " aah "            << aah
-				<< " transfer ooh"    << transfer_ooh
-				<< " transfer aah"    << transfer_aah
-				<< " start time "     << mStartTime
-				<< " current time "   << current_time
-				<< " elapsed time "   << elapsed_time
-				<< " elapsed oohs "   << elapsed_oohs
-				<< " elapsed aahs "   << elapsed_aahs
-				<< llendl;
-		*/
-	}
-	else
-	{
-		ooh = 0.0f;
-		aah = 0.0f;
-	}
-	
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-// this method is inherited from HUD Effect
-//---------------------------------------------------
-void LLVoiceVisualizer::render()
-{
-	if ( ! mVoiceEnabled )
-	{
-		return;
-	}
-	
-	if ( mSoundSymbol.mActive ) 
-	{				
-		mPreviousTime = mCurrentTime;
-		mCurrentTime = mTimer.getTotalSeconds();
-	
-		//---------------------------------------------------------------
-		// set the sound symbol position over the source (avatar's head)
-		//---------------------------------------------------------------
-		mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
-	
-		//---------------------------------------------------------------
-		// some gl state
-		//---------------------------------------------------------------
-		LLGLSPipelineAlpha alpha_blend;
-		LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-		
-		//-------------------------------------------------------------
-		// create coordinates of the geometry for the dot
-		//-------------------------------------------------------------
-		LLViewerCamera* camera = LLViewerCamera::getInstance();
-		LLVector3 l	= camera->getLeftAxis() * DOT_SIZE;
-		LLVector3 u	= camera->getUpAxis()   * DOT_SIZE;
-
-		LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
-		LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
-		LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
-		LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
-		
-		//-----------------------------
-		// bind texture 0 (the dot)
-		//-----------------------------
-		gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
-		
-		//-------------------------------------------------------------
-		// now render the dot
-		//-------------------------------------------------------------
-		gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );	
-		
-		gGL.begin( LLRender::TRIANGLE_STRIP );
-			gGL.texCoord2i( 0,	0	); gGL.vertex3fv( bottomLeft.mV );
-			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
-			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
-		gGL.end();
-
-		gGL.begin( LLRender::TRIANGLE_STRIP );
-			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
-			gGL.texCoord2i( 1,	1	); gGL.vertex3fv( topRight.mV );
-			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
-		gGL.end();
-		
-		
-		
-		//--------------------------------------------------------------------------------------
-		// if currently speaking, trigger waves (1 through 6) based on speaking amplitude
-		//--------------------------------------------------------------------------------------
-		if ( mCurrentlySpeaking )
-		{
-			F32 min = 0.2f;
-			F32 max = 0.7f;
-			F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
-		
-			// in case mSpeakingAmplitude > max....
-			if ( fraction > 1.0f )
-			{
-				fraction = 1.0f;
-			}
-														
-			S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
-																										
-			for (int i=0; i<level+1; i++)
-			{
-				mSoundSymbol.mWaveActive			[i] = true;
-				mSoundSymbol.mWaveOpacity			[i] = 1.0f;
-				mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
-			}			
-			
-		} // if currently speaking
-								
-		//---------------------------------------------------
-		// determine color
-		//---------------------------------------------------
-		F32 red		= 0.0f;
-		F32 green	= 0.0f;
-		F32 blue	= 0.0f;
-        if ( mSpeakingAmplitude < RED_THRESHOLD )
-        {
-			if ( mSpeakingAmplitude < GREEN_THRESHOLD )
-			{
-				red		= BASE_BRIGHTNESS;
-				green	= BASE_BRIGHTNESS;
-				blue	= BASE_BRIGHTNESS;
-			}
-			else
-			{
-				//---------------------------------------------------
-				// fade from gray to bright green
-				//---------------------------------------------------
-				F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
-				red		= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
-				green	= BASE_BRIGHTNESS +   fraction * ( 1.0f - BASE_BRIGHTNESS );
-				blue	= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
-			}
-        }
-        else
-        {
-			//---------------------------------------------------
-			// redish
-			//---------------------------------------------------
-			red		= 1.0f;
-			green	= 0.2f;
-			blue	= 0.2f;
-        }
-														
-		for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
-		{
-			if ( mSoundSymbol.mWaveActive[i] ) 
-			{
-				F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
-
-				mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
-				
-				if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
-				{
-					mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
-					mSoundSymbol.mWaveOpacity			[i] = 0.0f;
-					mSoundSymbol.mWaveActive			[i] = false;
-				}
-				
-				//----------------------------------------------------------------------------------
-				// This is where we calculate the expansion of the waves - that is, the
-				// rate at which they are scaled greater than 1.0 so that they grow over time.
-				//----------------------------------------------------------------------------------
-				F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
-				F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
-				mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
-				
-				if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
-				{
-					mSoundSymbol.mWaveExpansion[i] = 1.0f;
-				}			
-								
-				//----------------------------------------------------------------------------------
-				// create geometry for the wave billboard textures
-				//----------------------------------------------------------------------------------
-				F32 width	= i * WAVE_WIDTH_SCALE  * mSoundSymbol.mWaveExpansion[i];
-				F32 height	= i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
-
-				LLVector3 l	= camera->getLeftAxis() * width;
-				LLVector3 u	= camera->getUpAxis()   * height;
-
-				LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
-				LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
-				LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
-				LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
-							
-				gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );		
-				gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
-
-				
-				//---------------------------------------------------
-				// now, render the mofo
-				//---------------------------------------------------
-				gGL.begin( LLRender::TRIANGLE_STRIP );
-					gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
-					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
-					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
-				gGL.end();
-
-				gGL.begin( LLRender::TRIANGLE_STRIP );
-					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
-					gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
-					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
-				gGL.end();
-				
-			} //if ( mSoundSymbol.mWaveActive[i] ) 
-			
-		}// for loop
-											
-	}//if ( mSoundSymbol.mActive ) 
-
-}//---------------------------------------------------
-
-
-
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
-{
-	mVoiceSourceWorldPosition	= p;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
-{
-	VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
-	
-	//-----------------------------------------------------------------------------------------
-	// Within the range of gesticulation amplitudes, the sound signal is split into
-	// three equal amplitude regimes, each specifying one of three gesticulation levels.
-	//-----------------------------------------------------------------------------------------
-	F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
-	
-			if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH;		}
-	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM;	}
-	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW;		}
-
-	return gesticulationLevel;
-
-}//---------------------------------------------------
-
-
-
-//------------------------------------
-// Destructor
-//------------------------------------
-LLVoiceVisualizer::~LLVoiceVisualizer()
-{
-}//----------------------------------------------
-
-
-//---------------------------------------------------
-// "packData" is inherited from HUDEffect
-//---------------------------------------------------
-void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
-{
-	// Pack the default data
-	LLHUDEffect::packData(mesgsys);
-
-	// TODO -- pack the relevant data for voice effects
-	// we'll come up with some cool configurations....TBD
-	//U8 packed_data[41];
-	//mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
-	U8 packed_data = 0;
-	mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
-}
-
-
-//---------------------------------------------------
-// "unpackData" is inherited from HUDEffect
-//---------------------------------------------------
-void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
-{
-	// TODO -- find the speaker, unpack binary data, set the properties of this effect
-	/*
-	LLHUDEffect::unpackData(mesgsys, blocknum);
-	LLUUID source_id;
-	LLUUID target_id;
-	S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
-	if (size != 1)
-	{
-		llwarns << "Voice effect with bad size " << size << llendl;
-		return;
-	}
-	mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
-	*/
-}
-
-
-//------------------------------------------------------------------
-// this method is inherited from HUD Effect
-//------------------------------------------------------------------
-void LLVoiceVisualizer::markDead()
-{
-	mCurrentlySpeaking		= false;
-	mVoiceEnabled			= false;
-	mSoundSymbol.mActive	= false;
-
-	LLHUDEffect::markDead();
-}//------------------------------------------------------------------
-
-
-
-
-
-
-
-
+/** 
+ * @file llvoicevisualizer.cpp
+ * @brief Draws in-world speaking indicators.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+//----------------------------------------------------------------------
+// Voice Visualizer
+// author: JJ Ventrella
+// (information about this stuff can be found in "llvoicevisualizer.h")
+//----------------------------------------------------------------------
+#include "llviewerprecompiledheaders.h"
+#include "llviewercontrol.h"
+#include "llglheaders.h"
+#include "llsphere.h"
+#include "llvoicevisualizer.h"
+#include "llviewercamera.h"
+#include "llviewerobject.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+#include "llvoiceclient.h"
+#include "llrender.h"
+
+//brent's wave image
+//29de489d-0491-fb00-7dab-f9e686d31e83
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//--------------------------------------------------------------------------------------
+// sound symbol constants
+//--------------------------------------------------------------------------------------
+const F32	HEIGHT_ABOVE_HEAD	= 0.3f;		// how many meters vertically above the av's head the voice symbol will appear
+const F32	RED_THRESHOLD		= LLVoiceClient::OVERDRIVEN_POWER_LEVEL;		// value above which speaking amplitude causes the voice symbol to turn red
+const F32	GREEN_THRESHOLD		= 0.2f;		// value above which speaking amplitude causes the voice symbol to turn green
+const F32	FADE_OUT_DURATION	= 0.4f;		// how many seconds it takes for a pair of waves to fade away
+const F32	EXPANSION_RATE		= 1.0f;		// how many seconds it takes for the waves to expand to twice their original size
+const F32	EXPANSION_MAX		= 1.5f;		// maximum size scale to which the waves can expand before popping back to 1.0 
+const F32	WAVE_WIDTH_SCALE	= 0.03f;	// base width of the waves 
+const F32	WAVE_HEIGHT_SCALE	= 0.02f;	// base height of the waves 
+const F32	BASE_BRIGHTNESS		= 0.7f;		// gray level of the voice indicator when quiet (below green threshold)
+const F32	DOT_SIZE			= 0.05f;	// size of the dot billboard texture
+const F32	DOT_OPACITY			= 0.7f;		// how opaque the dot is
+const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a function of speaking amplitude
+#endif // XXX_STINSON_CHUI_REWORK
+
+//--------------------------------------------------------------------------------------
+// gesticulation constants
+//--------------------------------------------------------------------------------------
+const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE	= 0.2f; 
+const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f;
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//--------------------------------------------------------------------------------------
+// other constants
+//--------------------------------------------------------------------------------------
+const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. 
+const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
+#endif // XXX_STINSON_CHUI_REWORK
+
+//------------------------------------------------------------------
+// Initialize the statics
+//------------------------------------------------------------------
+bool LLVoiceVisualizer::sPrefsInitialized	= false;
+BOOL LLVoiceVisualizer::sLipSyncEnabled		= FALSE;
+F32* LLVoiceVisualizer::sOoh				= NULL;
+F32* LLVoiceVisualizer::sAah				= NULL;
+U32	 LLVoiceVisualizer::sOohs				= 0;
+U32	 LLVoiceVisualizer::sAahs				= 0;
+F32	 LLVoiceVisualizer::sOohAahRate			= 0.0f;
+F32* LLVoiceVisualizer::sOohPowerTransfer	= NULL;
+U32	 LLVoiceVisualizer::sOohPowerTransfers	= 0;
+F32	 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
+F32* LLVoiceVisualizer::sAahPowerTransfer	= NULL;
+U32	 LLVoiceVisualizer::sAahPowerTransfers	= 0;
+F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
+
+
+//-----------------------------------------------
+// constructor
+//-----------------------------------------------
+#ifdef XXX_STINSON_CHUI_REWORK
+LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
+#else // XXX_STINSON_CHUI_REWORK
+LLVoiceVisualizer::LLVoiceVisualizer()
+	: LLRefCount(),
+	mTimer(),
+	mStartTime(0.0),
+	mCurrentlySpeaking(false),
+	mSpeakingAmplitude(0.0f),
+	mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE),
+	mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE)
+#endif // XXX_STINSON_CHUI_REWORK
+{
+#ifdef XXX_STINSON_CHUI_REWORK
+	mCurrentTime					= mTimer.getTotalSeconds();
+	mPreviousTime					= mCurrentTime;
+	mStartTime						= mCurrentTime;
+#else // XXX_STINSON_CHUI_REWORK
+	mStartTime						= mTimer.getTotalSeconds();
+#endif // XXX_STINSON_CHUI_REWORK
+#ifdef XXX_STINSON_CHUI_REWORK
+	mVoiceSourceWorldPosition		= LLVector3( 0.0f, 0.0f, 0.0f );
+	mSpeakingAmplitude				= 0.0f;
+	mCurrentlySpeaking				= false;
+	mVoiceEnabled					= false;
+	mMinGesticulationAmplitude		= DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
+	mMaxGesticulationAmplitude		= DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
+	mSoundSymbol.mActive			= true;
+	mSoundSymbol.mPosition			= LLVector3( 0.0f, 0.0f, 0.0f );
+#endif // XXX_STINSON_CHUI_REWORK
+	
+	mTimer.reset();
+	
+#ifdef XXX_STINSON_CHUI_REWORK
+	const char* sound_level_img[] = 
+	{
+		"voice_meter_dot.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c"
+	};
+
+	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
+	{
+		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
+		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
+		mSoundSymbol.mWaveActive			[i] = false;
+		mSoundSymbol.mWaveOpacity			[i] = 1.0f;
+		mSoundSymbol.mWaveExpansion			[i] = 1.0f;
+	}
+
+	mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+#endif // XXX_STINSON_CHUI_REWORK
+
+	// The first instance loads the initial state from prefs.
+	if (!sPrefsInitialized)
+	{
+		setPreferences();
+       
+		// Set up our listener to get updates on all prefs values we care about.
+		gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		
+		sPrefsInitialized = true;
+	}
+
+}//---------------------------------------------------
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
+{
+	mMinGesticulationAmplitude = m;
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
+{
+	mMaxGesticulationAmplitude = m;
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setVoiceEnabled( bool v )
+{
+	mVoiceEnabled = v;
+
+}//---------------------------------------------------
+#endif // XXX_STINSON_CHUI_REWORK
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setStartSpeaking()
+{
+	mStartTime				= mTimer.getTotalSeconds();
+	mCurrentlySpeaking		= true;
+#ifdef XXX_STINSON_CHUI_REWORK
+	mSoundSymbol.mActive	= true;
+#endif // XXX_STINSON_CHUI_REWORK
+		
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+bool LLVoiceVisualizer::getCurrentlySpeaking()
+{
+	return mCurrentlySpeaking;
+	
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setStopSpeaking()
+{
+	mCurrentlySpeaking = false;
+	mSpeakingAmplitude = 0.0f;
+	
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
+{
+	mSpeakingAmplitude = a;
+	
+}//---------------------------------------------------
+
+//------------------------------------------------------------------
+// handles parameter updates
+//------------------------------------------------------------------
+bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
+{
+	// Note: Ignore the specific event value, we look up the ones we want
+	LLVoiceVisualizer::setPreferences();
+	return true;
+}
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setPreferences( )
+{
+	sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
+	sOohAahRate		= gSavedSettings.getF32("LipSyncOohAahRate");
+
+	std::string oohString = gSavedSettings.getString("LipSyncOoh");
+	lipStringToF32s (oohString, sOoh, sOohs);
+
+	std::string aahString = gSavedSettings.getString("LipSyncAah");
+	lipStringToF32s (aahString, sAah, sAahs);
+
+	std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
+	lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
+	sOohPowerTransfersf = (F32) sOohPowerTransfers;
+
+	std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
+	lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
+	sAahPowerTransfersf = (F32) sAahPowerTransfers;
+
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+// convert a string of digits to an array of floats.
+// the result for each digit is the value of the
+// digit multiplied by 0.11
+//---------------------------------------------------
+void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
+{
+	delete[] out_F32s;	// get rid of the current array
+
+	count_F32s = in_string.length();
+	if (count_F32s == 0)
+	{
+		// we don't like zero length arrays
+
+		count_F32s  = 1;
+		out_F32s	   = new F32[1];
+		out_F32s[0] = 0.0f;
+	}
+	else
+	{
+		out_F32s = new F32[count_F32s];
+
+		for (U32 i=0; i<count_F32s; i++)
+		{
+			// we convert the characters 0 to 9 to their numeric value
+			// anything else we take the low order four bits with a ceiling of 9
+
+		    U8 digit = in_string[i];
+			U8 four_bits = digit % 16;
+			if (four_bits > 9)
+			{
+				four_bits = 9;
+			}
+			out_F32s[i] = 0.11f * (F32) four_bits;
+		} 
+	}
+
+}//---------------------------------------------------
+
+
+//--------------------------------------------------------------------------
+// find the amount to blend the ooh and aah mouth morphs
+//--------------------------------------------------------------------------
+void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
+{
+	if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
+	{
+		U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
+		if (transfer_index >= sOohPowerTransfers)
+		{
+		   transfer_index = sOohPowerTransfers - 1;
+		}
+		F32 transfer_ooh = sOohPowerTransfer[transfer_index];
+
+		transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
+		if (transfer_index >= sAahPowerTransfers)
+		{
+		   transfer_index = sAahPowerTransfers - 1;
+		}
+		F32 transfer_aah = sAahPowerTransfer[transfer_index];
+
+		F64 current_time   = mTimer.getTotalSeconds();
+		F64 elapsed_time   = current_time - mStartTime;
+		U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
+		U32 elapsed_oohs   = elapsed_frames % sOohs;
+		U32 elapsed_aahs   = elapsed_frames % sAahs;
+
+		ooh = transfer_ooh * sOoh[elapsed_oohs];
+		aah = transfer_aah * sAah[elapsed_aahs];
+
+		/*
+		llinfos << " elapsed frames " << elapsed_frames
+				<< " ooh "            << ooh
+				<< " aah "            << aah
+				<< " transfer ooh"    << transfer_ooh
+				<< " transfer aah"    << transfer_aah
+				<< " start time "     << mStartTime
+				<< " current time "   << current_time
+				<< " elapsed time "   << elapsed_time
+				<< " elapsed oohs "   << elapsed_oohs
+				<< " elapsed aahs "   << elapsed_aahs
+				<< llendl;
+		*/
+	}
+	else
+	{
+		ooh = 0.0f;
+		aah = 0.0f;
+	}
+	
+}//---------------------------------------------------
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+// this method is inherited from HUD Effect
+//---------------------------------------------------
+void LLVoiceVisualizer::render()
+{
+	if ( ! mVoiceEnabled )
+	{
+		return;
+	}
+	
+	if ( mSoundSymbol.mActive ) 
+	{				
+		mPreviousTime = mCurrentTime;
+		mCurrentTime = mTimer.getTotalSeconds();
+	
+		//---------------------------------------------------------------
+		// set the sound symbol position over the source (avatar's head)
+		//---------------------------------------------------------------
+		mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
+	
+		//---------------------------------------------------------------
+		// some gl state
+		//---------------------------------------------------------------
+		LLGLSPipelineAlpha alpha_blend;
+		LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+		
+		//-------------------------------------------------------------
+		// create coordinates of the geometry for the dot
+		//-------------------------------------------------------------
+		LLViewerCamera* camera = LLViewerCamera::getInstance();
+		LLVector3 l	= camera->getLeftAxis() * DOT_SIZE;
+		LLVector3 u	= camera->getUpAxis()   * DOT_SIZE;
+
+		LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
+		LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
+		LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
+		LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
+		
+		//-----------------------------
+		// bind texture 0 (the dot)
+		//-----------------------------
+		gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
+		
+		//-------------------------------------------------------------
+		// now render the dot
+		//-------------------------------------------------------------
+		gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );	
+		
+		gGL.begin( LLRender::TRIANGLE_STRIP );
+			gGL.texCoord2i( 0,	0	); gGL.vertex3fv( bottomLeft.mV );
+			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
+			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
+		gGL.end();
+
+		gGL.begin( LLRender::TRIANGLE_STRIP );
+			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
+			gGL.texCoord2i( 1,	1	); gGL.vertex3fv( topRight.mV );
+			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
+		gGL.end();
+		
+		
+		
+		//--------------------------------------------------------------------------------------
+		// if currently speaking, trigger waves (1 through 6) based on speaking amplitude
+		//--------------------------------------------------------------------------------------
+		if ( mCurrentlySpeaking )
+		{
+			F32 min = 0.2f;
+			F32 max = 0.7f;
+			F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
+		
+			// in case mSpeakingAmplitude > max....
+			if ( fraction > 1.0f )
+			{
+				fraction = 1.0f;
+			}
+														
+			S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
+																										
+			for (int i=0; i<level+1; i++)
+			{
+				mSoundSymbol.mWaveActive			[i] = true;
+				mSoundSymbol.mWaveOpacity			[i] = 1.0f;
+				mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
+			}			
+			
+		} // if currently speaking
+								
+		//---------------------------------------------------
+		// determine color
+		//---------------------------------------------------
+		F32 red		= 0.0f;
+		F32 green	= 0.0f;
+		F32 blue	= 0.0f;
+        if ( mSpeakingAmplitude < RED_THRESHOLD )
+        {
+			if ( mSpeakingAmplitude < GREEN_THRESHOLD )
+			{
+				red		= BASE_BRIGHTNESS;
+				green	= BASE_BRIGHTNESS;
+				blue	= BASE_BRIGHTNESS;
+			}
+			else
+			{
+				//---------------------------------------------------
+				// fade from gray to bright green
+				//---------------------------------------------------
+				F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
+				red		= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
+				green	= BASE_BRIGHTNESS +   fraction * ( 1.0f - BASE_BRIGHTNESS );
+				blue	= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
+			}
+        }
+        else
+        {
+			//---------------------------------------------------
+			// redish
+			//---------------------------------------------------
+			red		= 1.0f;
+			green	= 0.2f;
+			blue	= 0.2f;
+        }
+														
+		for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
+		{
+			if ( mSoundSymbol.mWaveActive[i] ) 
+			{
+				F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
+
+				mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
+				
+				if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
+				{
+					mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
+					mSoundSymbol.mWaveOpacity			[i] = 0.0f;
+					mSoundSymbol.mWaveActive			[i] = false;
+				}
+				
+				//----------------------------------------------------------------------------------
+				// This is where we calculate the expansion of the waves - that is, the
+				// rate at which they are scaled greater than 1.0 so that they grow over time.
+				//----------------------------------------------------------------------------------
+				F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
+				F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
+				mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
+				
+				if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
+				{
+					mSoundSymbol.mWaveExpansion[i] = 1.0f;
+				}			
+								
+				//----------------------------------------------------------------------------------
+				// create geometry for the wave billboard textures
+				//----------------------------------------------------------------------------------
+				F32 width	= i * WAVE_WIDTH_SCALE  * mSoundSymbol.mWaveExpansion[i];
+				F32 height	= i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
+
+				LLVector3 l	= camera->getLeftAxis() * width;
+				LLVector3 u	= camera->getUpAxis()   * height;
+
+				LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
+				LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
+				LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
+				LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
+							
+				gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );		
+				gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
+
+				
+				//---------------------------------------------------
+				// now, render the mofo
+				//---------------------------------------------------
+				gGL.begin( LLRender::TRIANGLE_STRIP );
+					gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
+					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
+					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
+				gGL.end();
+
+				gGL.begin( LLRender::TRIANGLE_STRIP );
+					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
+					gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
+					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
+				gGL.end();
+				
+			} //if ( mSoundSymbol.mWaveActive[i] ) 
+			
+		}// for loop
+											
+	}//if ( mSoundSymbol.mActive ) 
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
+{
+	mVoiceSourceWorldPosition	= p;
+
+}//---------------------------------------------------
+#endif // XXX_STINSON_CHUI_REWORK
+
+//---------------------------------------------------
+VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
+{
+	VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
+	
+	//-----------------------------------------------------------------------------------------
+	// Within the range of gesticulation amplitudes, the sound signal is split into
+	// three equal amplitude regimes, each specifying one of three gesticulation levels.
+	//-----------------------------------------------------------------------------------------
+	F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
+	
+			if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH;		}
+	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM;	}
+	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW;		}
+
+	return gesticulationLevel;
+
+}//---------------------------------------------------
+
+
+
+//------------------------------------
+// Destructor
+//------------------------------------
+LLVoiceVisualizer::~LLVoiceVisualizer()
+{
+}//----------------------------------------------
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+// "packData" is inherited from HUDEffect
+//---------------------------------------------------
+void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
+{
+	// Pack the default data
+	LLHUDEffect::packData(mesgsys);
+
+	// TODO -- pack the relevant data for voice effects
+	// we'll come up with some cool configurations....TBD
+	//U8 packed_data[41];
+	//mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
+	U8 packed_data = 0;
+	mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
+}
+
+
+//---------------------------------------------------
+// "unpackData" is inherited from HUDEffect
+//---------------------------------------------------
+void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
+{
+	// TODO -- find the speaker, unpack binary data, set the properties of this effect
+	/*
+	LLHUDEffect::unpackData(mesgsys, blocknum);
+	LLUUID source_id;
+	LLUUID target_id;
+	S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
+	if (size != 1)
+	{
+		llwarns << "Voice effect with bad size " << size << llendl;
+		return;
+	}
+	mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
+	*/
+}
+
+
+//------------------------------------------------------------------
+// this method is inherited from HUD Effect
+//------------------------------------------------------------------
+void LLVoiceVisualizer::markDead()
+{
+	mCurrentlySpeaking		= false;
+	mVoiceEnabled			= false;
+	mSoundSymbol.mActive	= false;
+
+	LLHUDEffect::markDead();
+}//------------------------------------------------------------------
+
+#endif // XXX_STINSON_CHUI_REWORK
diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h
index e434c7f3f1..6258de163d 100644
--- a/indra/newview/llvoicevisualizer.h
+++ b/indra/newview/llvoicevisualizer.h
@@ -42,7 +42,11 @@
 #ifndef LL_VOICE_VISUALIZER_H
 #define LL_VOICE_VISUALIZER_H
 
+#ifdef XXX_STINSON_CHUI_REWORK
 #include "llhudeffect.h"
+#else // XXX_STINSON_CHUI_REWORK
+#include "llpointer.h"
+#endif // XXX_STINSON_CHUI_REWORK
 
 //-----------------------------------------------------------------------------------------------
 // The values of voice gesticulation represent energy levels for avatar animation, based on 
@@ -60,34 +64,45 @@ enum VoiceGesticulationLevel
 	NUM_VOICE_GESTICULATION_LEVELS
 };
 
+#ifdef XXX_STINSON_CHUI_REWORK
 const static int NUM_VOICE_SYMBOL_WAVES = 7;
+#endif // XXX_STINSON_CHUI_REWORK
 
 //----------------------------------------------------
 // LLVoiceVisualizer class 
 //----------------------------------------------------
+#ifdef XXX_STINSON_CHUI_REWORK
 class LLVoiceVisualizer : public LLHUDEffect
+#else // XXX_STINSON_CHUI_REWORK
+class LLVoiceVisualizer : public LLRefCount
+#endif // XXX_STINSON_CHUI_REWORK
 {
 	//---------------------------------------------------
 	// public methods 
 	//---------------------------------------------------
 	public:
-		LLVoiceVisualizer ( const U8 type );	//constructor
+#ifdef XXX_STINSON_CHUI_REWORK
+		LLVoiceVisualizer( const U8 type );	//constructor
+#else // XXX_STINSON_CHUI_REWORK
+		LLVoiceVisualizer();	//constructor
+#endif // XXX_STINSON_CHUI_REWORK
 		~LLVoiceVisualizer();					//destructor
-		
-		friend class LLHUDObject;
 
+#ifdef XXX_STINSON_CHUI_REWORK
 		void					setVoiceSourceWorldPosition( const LLVector3 &p );		// this should be the position of the speaking avatar's head
 		void					setMinGesticulationAmplitude( F32 );					// the lower range of meaningful amplitude for setting gesticulation level 
 		void					setMaxGesticulationAmplitude( F32 );					// the upper range of meaningful amplitude for setting gesticulation level 
+#endif // XXX_STINSON_CHUI_REWORK
 		void					setStartSpeaking();										// tell me when the av starts speaking
+#ifdef XXX_STINSON_CHUI_REWORK
 		void					setVoiceEnabled( bool );								// tell me whether or not the user is voice enabled
+#endif // XXX_STINSON_CHUI_REWORK
 		void					setSpeakingAmplitude( F32 );							// tell me how loud the av is speaking (ranges from 0 to 1)
 		void					setStopSpeaking();										// tell me when the av stops speaking
 		bool					getCurrentlySpeaking();									// the get for the above set
 		VoiceGesticulationLevel	getCurrentGesticulationLevel();							// based on voice amplitude, I'll give you the current "energy level" of avatar speech
-		static void				setPreferences( );
-		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
 		void					lipSyncOohAah( F32& ooh, F32& aah );
+#ifdef XXX_STINSON_CHUI_REWORK
 		void					render();												// inherited from HUD Effect
 		void 					packData(LLMessageSystem *mesgsys);						// inherited from HUD Effect
 		void 					unpackData(LLMessageSystem *mesgsys, S32 blocknum);		// inherited from HUD Effect
@@ -103,12 +118,17 @@ class LLVoiceVisualizer : public LLHUDEffect
 		//----------------------------------------------------------------------------------------------
 		void setMaxGesticulationAmplitude(); 
 		void setMinGesticulationAmplitude(); 
+#endif // XXX_STINSON_CHUI_REWORK
 
 	//---------------------------------------------------
 	// private members 
 	//---------------------------------------------------
 	private:
-	
+		static bool				handleVoiceVisualizerPrefsChanged(const LLSD& newvalue);
+		static void				setPreferences( );
+		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
+
+#ifdef XXX_STINSON_CHUI_REWORK
 		struct SoundSymbol
 		{
 			F32						mWaveExpansion			[ NUM_VOICE_SYMBOL_WAVES ];
@@ -119,15 +139,20 @@ class LLVoiceVisualizer : public LLHUDEffect
 			bool					mActive;
 			LLVector3				mPosition;
 		};
+#endif // XXX_STINSON_CHUI_REWORK
 
 		LLFrameTimer			mTimer;							// so I can ask the current time in seconds
 		F64						mStartTime;						// time in seconds when speaking started
+#ifdef XXX_STINSON_CHUI_REWORK
 		F64						mCurrentTime;					// current time in seconds, captured every step
 		F64						mPreviousTime;					// copy of "current time" from last frame
 		SoundSymbol				mSoundSymbol;					// the sound symbol that appears over the avatar's head
 		bool					mVoiceEnabled;					// if off, no rendering should happen
+#endif // XXX_STINSON_CHUI_REWORK
 		bool					mCurrentlySpeaking;				// is the user currently speaking?
+#ifdef XXX_STINSON_CHUI_REWORK
 		LLVector3				mVoiceSourceWorldPosition;		// give this to me every step - I need it to update the sound symbol
+#endif // XXX_STINSON_CHUI_REWORK
 		F32						mSpeakingAmplitude;				// this should be set as often as possible when the user is speaking
 		F32						mMaxGesticulationAmplitude;		// this is the upper-limit of the envelope of detectable gesticulation leves
 		F32						mMinGesticulationAmplitude;		// this is the lower-limit of the envelope of detectable gesticulation leves
-- 
cgit v1.2.3


From 42b5dfda161a1e6b92990cd5206bca5ff5b95ab6 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 17 Apr 2012 17:13:48 -0700
Subject: CHUI-86 WIP Investigate voice-dot with name tag integration fixed bad
 parameters in draw3d...name tags should display properly now

---
 indra/llui/lluiimage.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp
index a4886dabb0..9ed98f941f 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llui/lluiimage.cpp
@@ -145,10 +145,10 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
 							mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
 		gl_segmented_rect_3d_tex(mClipRegion,
 								center_uv_rect,
-								LLRectf(border_width * border_scale * 0.5f,
-										1.f - (border_height * border_scale * 0.5f),
-										1.f - (border_width * border_scale * 0.5f),
-										border_height * border_scale * 0.5f),
+								LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
+										(rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
+										(rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
+										(border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
 								rect.getWidth() * x_axis, 
 								rect.getHeight() * y_axis);
 		
-- 
cgit v1.2.3


From 4be3ec7234c82f1e2b33d3eb30d5b6cc1eb890ba Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Tue, 17 Apr 2012 17:14:37 -0700
Subject: BUILDFIX: Attempting to correct a linux build problem.

---
 indra/newview/llhudnametag.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 26c3ee8c7a..423a6f8c07 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -321,7 +321,7 @@ void LLHUDNameTag::renderText(BOOL for_select)
 
 	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
 	LLRect screen_rect;
-	screen_rect.setCenterAndSize(0, -mHeight / 2 + mOffsetY, mWidth, mHeight);
+	screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight)));
 	imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
 	if (mLabelSegments.size())
 	{
-- 
cgit v1.2.3


From 448ae4ec9b2351d47253a5fc5c3df47694da8b4b Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 17 Apr 2012 17:18:48 -0700
Subject: CHUI-86 WIP Investigate voice-dot with name tag integration removed
 dead code

---
 indra/newview/llhudnametag.cpp | 49 ------------------------------------------
 1 file changed, 49 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 26c3ee8c7a..d5d31ba30e 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -276,24 +276,6 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");
 	bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
 
-	// maybe a no-op?
-	//const S32 border_height = 16;
-	//const S32 border_width = 16;
-	const S32 border_height = 8;
-	const S32 border_width = 8;
-
-	// *TODO move this into helper function
-	F32 border_scale = 1.f;
-
-	if (border_height * 2 > mHeight)
-	{
-		border_scale = (F32)mHeight / ((F32)border_height * 2.f);
-	}
-	if (border_width * 2 > mWidth)
-	{
-		border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f));
-	}
-
 	// scale screen size of borders down
 	//RN: for now, text on hud objects is never occluded
 
@@ -302,11 +284,8 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	
 	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
 
-	LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());
 	LLVector3 width_vec = mWidth * x_pixel_vec;
 	LLVector3 height_vec = mHeight * y_pixel_vec;
-	LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec;
-	LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;
 
 	mRadius = (width_vec + height_vec).magVec() * 0.5f;
 
@@ -333,35 +312,7 @@ void LLHUDNameTag::renderText(BOOL for_select)
 		label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
 
 		rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
-
 	}
-	//LLUI::pushMatrix();
-	//{
-	//	LLVector3 bg_pos = render_position
-	//		+ (F32)mOffsetY * y_pixel_vec
-	//		- (width_vec / 2.f)
-	//		- (height_vec);
-	//	LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
-
-	//	gGL.getTexUnit(0)->bind(imagep->getImage());
-	//			
-	//	gGL.color4fv(bg_color.mV);
-	//	gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-	//	
-	//	if ( mLabelSegments.size())
-	//	{
-	//		LLUI::pushMatrix();
-	//		{
-	//			gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
-	//			LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
-	//			LLVector3 label_offset = height_vec - label_height;
-	//			LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
-	//			gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
-	//		}
-	//		LLUI::popMatrix();
-	//	}
-	//}
-	//LLUI::popMatrix();
 
 	F32 y_offset = (F32)mOffsetY;
 		
-- 
cgit v1.2.3


From 05600db8968d05e816cd637e99d821961802cbc0 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 18 Apr 2012 17:27:28 -0700
Subject: converted to unix line endings

---
 indra/newview/llhudobject.cpp | 10 +++++-----
 indra/newview/llhudobject.h   |  6 +++---
 2 files changed, 8 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 06b0c3c6c8..0960846510 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -232,11 +232,11 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type)
 	case LL_HUD_EFFECT_LOOKAT:
 		hud_objectp = new LLHUDEffectLookAt(type);
 		break;
-#ifdef XXX_STINSON_CHUI_REWORK
-	case LL_HUD_EFFECT_VOICE_VISUALIZER:
-		hud_objectp = new LLVoiceVisualizer(type);
-		break;
-#endif // XXX_STINSON_CHUI_REWORK
+#ifdef XXX_STINSON_CHUI_REWORK
+	case LL_HUD_EFFECT_VOICE_VISUALIZER:
+		hud_objectp = new LLVoiceVisualizer(type);
+		break;
+#endif // XXX_STINSON_CHUI_REWORK
 	case LL_HUD_EFFECT_POINTAT:
 		hud_objectp = new LLHUDEffectPointAt(type);
 		break;
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 6f8be41177..21cf5fe17c 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -94,9 +94,9 @@ public:
 		LL_HUD_EFFECT_EDIT,
 		LL_HUD_EFFECT_LOOKAT,
 		LL_HUD_EFFECT_POINTAT,
-#ifdef XXX_STINSON_CHUI_REWORK
-		LL_HUD_EFFECT_VOICE_VISUALIZER,	// Ventrella
-#endif // XXX_STINSON_CHUI_REWORK
+#ifdef XXX_STINSON_CHUI_REWORK
+		LL_HUD_EFFECT_VOICE_VISUALIZER,	// Ventrella
+#endif // XXX_STINSON_CHUI_REWORK
 		LL_HUD_NAME_TAG,
 		LL_HUD_EFFECT_BLOB
 	};
-- 
cgit v1.2.3


From 23f7db3ceeadd9729f437ee12996e86d3a0bcff0 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 20 Apr 2012 13:52:49 -0700
Subject: allow nested modifier tags (e.g. Lazy, Atomic) in param block entries

---
 indra/llxuixml/llinitparam.h      | 273 ++++++++++++++++++++++++--------------
 indra/llxuixml/llxuiparser.cpp    |  33 ++---
 indra/newview/llpreviewscript.cpp |   6 +-
 3 files changed, 193 insertions(+), 119 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index afb6868c4b..5222d4c713 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -36,6 +36,71 @@
 
 #include "llerror.h"
 
+namespace LLTypeTags
+{
+	template <typename INNER_TYPE, int _SORT_ORDER>
+	struct TypeTagBase
+	{
+		typedef void		is_tag_t;
+		typedef INNER_TYPE	inner_t;
+		static const int	SORT_ORDER=_SORT_ORDER;
+	};
+
+	template <int VAL1, int VAL2>
+	struct GreaterThan
+	{
+		static const bool value = VAL1 > VAL2;
+	};
+
+	template<typename ITEM, typename REST, bool NEEDS_SWAP = GreaterThan<ITEM::SORT_ORDER, REST::SORT_ORDER>::value >
+	struct Swap
+	{
+		typedef typename ITEM::Cons<REST>::value_t value_t;
+	};
+
+	template<typename ITEM, typename REST>
+	struct Swap<ITEM, REST, true>
+	{
+		typedef typename REST::Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t;
+	};
+
+	template<typename T, typename SORTABLE = void>
+	struct IsSortable
+	{
+		static const bool value = false;
+	};
+
+	template<typename T>
+	struct IsSortable<T, typename T::is_tag_t>
+	{
+		static const bool value = true;
+	};
+
+	template<typename ITEM, typename REST, bool IS_REST_SORTABLE = IsSortable<REST>::value>
+	struct InsertInto
+	{
+		typedef typename ITEM::Cons<REST>::value_t value_t;
+	};
+
+	template<typename ITEM, typename REST>
+	struct InsertInto <ITEM, REST, true>
+	{
+		typedef typename Swap<ITEM, REST>::value_t value_t;
+	};
+
+	template<typename T, bool SORTABLE = IsSortable<T>::value>
+	struct Sorted
+	{
+		typedef T value_t;
+	};
+
+	template<typename T>
+	struct Sorted <T, true>
+	{
+		typedef typename InsertInto<T, typename Sorted<typename T::inner_t>::value_t>::value_t value_t;
+	};
+}
+
 namespace LLInitParam
 {
 	// used to indicate no matching value to a given name when parsing
@@ -100,7 +165,7 @@ namespace LLInitParam
 	// by holding on to a copy (scalar params)
 	// or deriving from it (blocks)
 	// has specializations for custom value behavior
-	// and "tagged" values like Lazy and Atomic
+	// and "tag" values like Lazy and Atomic
 	template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
 	class ParamValue
 	{
@@ -134,7 +199,7 @@ namespace LLInitParam
 
 	template<typename T>
 	class ParamValue<T, IS_A_BLOCK> 
-		:	public T
+	:	public T
 	{
 		typedef ParamValue<T, IS_A_BLOCK>	self_t;
 	public:
@@ -175,7 +240,7 @@ namespace LLInitParam
 	// leverages empty base class optimization
 	template <typename T>
 	class TypeValues
-	:	public ParamValue<T>
+	:	public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
 	{
 	private:
 		struct Inaccessable{};
@@ -183,10 +248,11 @@ namespace LLInitParam
 		typedef std::map<std::string, T> value_name_map_t;
 		typedef Inaccessable name_t;
 		typedef TypeValues<T> type_value_t;
-		typedef typename ParamValue<T>::value_t	value_t;
+		typedef typename ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t;
+		typedef typename param_value_t::value_t	value_t;
 
-		TypeValues(const value_t& val)
-		:	ParamValue<T>(val)
+		TypeValues(const typename param_value_t::value_t& val)
+		:	param_value_t(val)
 		{}
 
 		void setValueName(const std::string& key) {}
@@ -214,12 +280,12 @@ namespace LLInitParam
 
 		operator const value_t&() const
 		{
-			return ParamValue<T>::getValue();
+			return param_value_t::getValue();
 		}
 
 		const value_t& operator()() const
 		{
-			return ParamValue<T>::getValue();
+			return param_value_t::getValue();
 		}
 
 		static value_name_map_t* getValueNames() {return NULL;}
@@ -229,17 +295,18 @@ namespace LLInitParam
 	// and caching of last used name
 	template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >
 	class TypeValuesHelper
-	:	public ParamValue<T>
+	:	public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
 	{
 		typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;
 	public:
 		typedef typename std::map<std::string, T> value_name_map_t;
 		typedef std::string name_t;
 		typedef self_t type_value_t;
-		typedef typename ParamValue<T>::value_t	value_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+		typedef typename param_value_t::value_t	value_t;
 
-		TypeValuesHelper(const value_t& val)
-		:	ParamValue<T>(val)
+		TypeValuesHelper(const typename param_value_t::value_t& val)
+		:	param_value_t(val)
 		{}
 
 		//TODO: cache key by index to save on param block size
@@ -328,7 +395,7 @@ namespace LLInitParam
 
 		void assignNamedValue(const std::string& name)
 		{
-			if (getValueFromName(name, ParamValue<T>::getValue()))
+			if (getValueFromName(name, param_value_t::getValue()))
 			{
 				setValueName(name);
 			}
@@ -336,12 +403,12 @@ namespace LLInitParam
 
 		operator const value_t&() const
 		{
-			return ParamValue<T>::getValue();
+			return param_value_t::getValue();
 		}
 
 		const value_t& operator()() const
 		{
-			return ParamValue<T>::getValue();
+			return param_value_t::getValue();
 		}
 
 	protected:
@@ -571,7 +638,7 @@ namespace LLInitParam
 	{
 	public:
 		LazyValue()
-			:	mPtr(NULL)
+		:	mPtr(NULL)
 		{}
 
 		~LazyValue()
@@ -585,26 +652,28 @@ namespace LLInitParam
 		}
 
 		LazyValue(const LazyValue& other)
+		:	mPtr(NULL)
 		{
-			if (other.mPtr)
-			{
-				mPtr = new T(*other.mPtr);
-			}
-			else
-			{
-				mPtr = NULL;
-			}
+			*this = other;
 		}
 
 		LazyValue& operator = (const LazyValue& other)
 		{
-			if (other.mPtr)
+			if (!other.mPtr)
 			{
-				mPtr = new T(*other.mPtr);
+				delete mPtr;
+				mPtr = NULL;
 			}
 			else
 			{
-				mPtr = NULL;
+				if (!mPtr)
+				{
+					mPtr = new T(*other.mPtr);
+				}
+				else
+				{
+					*mPtr = *(other.mPtr);
+				}
 			}
 			return *this;
 		}
@@ -622,8 +691,14 @@ namespace LLInitParam
 
 		void set(const T& other)
 		{
-			delete mPtr;
-			mPtr = new T(other);
+			if (!mPtr)
+			{
+				mPtr = new T(other);
+			}
+			else
+			{
+				*mPtr = other;
+			}
 		}
 
 		const T& get() const
@@ -667,12 +742,28 @@ namespace LLInitParam
 		typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK;
 
 		template<typename T>
-		class Atomic
-		{};
+		struct Atomic : public LLTypeTags::TypeTagBase<T, 1>
+		{
+			template <typename S> struct Cons { typedef Atomic<ParamValue<S> > value_t; };
+			template <typename T> struct Cons<Atomic<T> > { typedef Atomic<T> value_t; };
+		};
 
 		template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
-		class Lazy
-		{};
+		struct Lazy : public LLTypeTags::TypeTagBase<T, 0>
+		{
+			template <typename S> struct Cons
+			{
+				typedef Lazy<ParamValue<S, BLOCK_T>, BLOCK_T> value_t;
+			};
+			template <typename T> struct Cons<Lazy<T, IS_A_BLOCK> >
+			{
+				typedef Lazy<T, IS_A_BLOCK> value_t;
+			};
+			template <typename T> struct Cons<Lazy<T, NOT_A_BLOCK> >
+			{
+				typedef Lazy<T, BLOCK_T> value_t;
+			};
+		};
 
 		// "Multiple" constraint types, put here in root class to avoid ambiguity during use
 		struct AnyAmount
@@ -837,14 +928,14 @@ namespace LLInitParam
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
-			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<T> >::value_t>
+			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<typename LLTypeTags::Sorted<T>::value_t> >::value_t>
 	class TypedParam 
 	:	public Param, 
 		public NAME_VALUE_LOOKUP::type_value_t
 	{
 	protected:
 		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t;
-		typedef ParamValue<T>															param_value_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>						param_value_t;
 		typedef typename param_value_t::default_value_t									default_value_t;
 		typedef typename NAME_VALUE_LOOKUP::type_value_t								named_value_t;
 	public:
@@ -1002,7 +1093,7 @@ namespace LLInitParam
 		public NAME_VALUE_LOOKUP::type_value_t
 	{
 	protected:
-		typedef ParamValue<T>										param_value_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t;
 		typedef typename param_value_t::default_value_t				default_value_t;
 		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>	self_t;
 		typedef typename NAME_VALUE_LOOKUP::type_value_t			named_value_t;
@@ -1185,11 +1276,11 @@ namespace LLInitParam
 	:	public Param
 	{
 	protected:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>	self_t;
-		typedef ParamValue<VALUE_TYPE>										param_value_t;
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t;
 		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;
-		typedef container_t													default_value_t;
-		typedef typename NAME_VALUE_LOOKUP::type_value_t					named_value_t;
+		typedef container_t														default_value_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t;
 		
 	public:
 		typedef typename param_value_t::value_t								value_t;
@@ -1385,7 +1476,7 @@ namespace LLInitParam
 	{
 	protected:
 		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>		self_t;
-		typedef ParamValue<VALUE_TYPE>											param_value_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t;
 		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;
 		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t;
 		typedef container_t														default_value_t;
@@ -1956,7 +2047,25 @@ namespace LLInitParam
 	template<typename T, typename BLOCK_IDENTIFIER>
 	struct IsBlock<ParamValue<BaseBlock::Atomic<T>, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER>
 	{
-		typedef typename IsBlock<ParamValue<T> >::value_t value_t;
+		typedef typename IsBlock<T>::value_t value_t;
+	};
+
+	template<typename T>
+	struct InnerMostType
+	{
+		typedef T value_t;
+	};
+
+	template<typename T>
+	struct InnerMostType<ParamValue<T, NOT_BLOCK> >
+	{
+		typedef typename InnerMostType<T>::value_t value_t;
+	};
+
+	template<typename T>
+	struct InnerMostType<ParamValue<T, IS_A_BLOCK> >
+	{
+		typedef typename InnerMostType<T>::value_t value_t;
 	};
 
 	template<typename T, typename BLOCK_T>
@@ -1965,8 +2074,8 @@ namespace LLInitParam
 		typedef ParamValue <BaseBlock::Atomic<T>, BLOCK_T> self_t;
 
 	public:
-		typedef T								value_t;
-		typedef T								default_value_t;
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef T									default_value_t;
 
 		ParamValue()
 		:	mValue(),
@@ -1980,27 +2089,17 @@ namespace LLInitParam
 
 		void setValue(const value_t& val)
 		{
-			mValue = val;
-		}
-
-		const T& getValue() const
-		{
-			return mValue;
-		}
-
-		T& getValue()
-		{
-			return mValue;
+			mValue.setValue(val);
 		}
 
-		operator const value_t&() const
+		const value_t& getValue() const
 		{
-			return mValue;
+			return mValue.getValue();
 		}
 
-		const value_t& operator()() const
+		value_t& getValue()
 		{
-			return mValue;
+			return mValue.getValue();
 		}
 
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
@@ -2030,7 +2129,7 @@ namespace LLInitParam
 			if (overwrite)
 			{
 				resetToDefault();
-				return mValue.mergeBlock(block_data, source, overwrite);
+				return mValue.mergeBlock(block_data, source.getValue(), overwrite);
 			}
 			return false;
 		}
@@ -2042,7 +2141,7 @@ namespace LLInitParam
 
 		static BlockDescriptor& getBlockDescriptor()
 		{
-			return T::getBlockDescriptor();
+			return value_t::getBlockDescriptor();
 		}
 
 
@@ -2064,9 +2163,9 @@ namespace LLInitParam
 		typedef ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> self_t;
 
 	public:
-		typedef T				value_t;
-		typedef LazyValue<T>	default_value_t;
-	
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef LazyValue<T>						default_value_t;
+
 		ParamValue()
 		:	mValue(),
 			mValidated(false)
@@ -2089,22 +2188,12 @@ namespace LLInitParam
 
 		const value_t& getValue() const
 		{
-			return mValue.get();
+			return mValue.get().getValue();
 		}
 
-		T& getValue()
+		value_t& getValue()
 		{
-			return mValue.get();
-		}
-
-		operator const value_t&() const
-		{
-			return mValue.get();
-		}
-
-		const value_t& operator()() const
-		{
-			return mValue.get();
+			return mValue.get().getValue();
 		}
 
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
@@ -2117,7 +2206,7 @@ namespace LLInitParam
 			if (mValue.empty()) return;
 			
 			const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())
-											? &(diff_block->mValue.get())
+											? &(diff_block->mValue.get().getValue())
 											: NULL;
 			mValue.get().serializeBlock(p, name_stack, base_block);
 		}
@@ -2129,7 +2218,7 @@ namespace LLInitParam
 
 		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
 		{
-			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source,  overwrite);
+			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite);
 		}
 
 		bool validateBlock(bool emit_errors = true) const
@@ -2139,10 +2228,9 @@ namespace LLInitParam
 
 		static BlockDescriptor& getBlockDescriptor()
 		{
-			return T::getBlockDescriptor();
+			return value_t::getBlockDescriptor();
 		}
 
-
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
@@ -2155,8 +2243,8 @@ namespace LLInitParam
 		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t;
 
 	public:
-		typedef T				value_t;
-		typedef LazyValue<T>	default_value_t;
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef LazyValue<T>						default_value_t;
 
 		ParamValue()
 		:	mValue(),
@@ -2180,22 +2268,12 @@ namespace LLInitParam
 
 		const value_t& getValue() const
 		{
-			return mValue.get();
+			return mValue.get().getValue();
 		}
 
-		T& getValue()
+		value_t& getValue()
 		{
-			return mValue.get();
-		}
-
-		operator const value_t&() const
-		{
-			return mValue.get();
-		}
-
-		const value_t& operator()() const
-		{
-			return mValue.get();
+			return mValue.get().getValue();
 		}
 
 		mutable bool 	mValidated; // lazy validation flag
@@ -2226,9 +2304,6 @@ namespace LLInitParam
 		const value_t& getValue() const { return mValue; }
 		LLSD& getValue() { return mValue; }
 
-		operator const value_t&() const { return mValue; }
-		const value_t& operator()() const { return mValue; }
-		
 		// block param interface
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 58ed24b08b..808e391575 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -43,7 +43,6 @@
 
 #include "lluicolor.h"
 #include "v3math.h"
-
 using namespace BOOST_SPIRIT_CLASSIC_NS;
 
 const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
@@ -80,7 +79,6 @@ struct Occurs : public LLInitParam::Block<Occurs>
 	{}
 };
 
-
 typedef enum
 {
 	USE_REQUIRED,
@@ -102,9 +100,18 @@ namespace LLInitParam
 
 struct Element;
 struct Group;
-struct Choice;
 struct Sequence;
-struct Any;
+
+struct All : public LLInitParam::Block<All, Occurs>
+{
+	Multiple< Lazy<Element, IS_A_BLOCK> > elements;
+
+	All()
+	:	elements("element")
+	{
+		maxOccurs = 1;
+	}
+};
 
 struct Attribute : public LLInitParam::Block<Attribute>
 {
@@ -128,24 +135,13 @@ struct Any : public LLInitParam::Block<Any, Occurs>
 	{}
 };
 
-struct All : public LLInitParam::Block<All, Occurs>
-{
-	Multiple< Lazy<Element, IS_A_BLOCK> > elements;
-
-	All()
-	:	elements("element")
-	{
-		maxOccurs = 1;
-	}
-};
-
 struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
 {
 	Alternative< Lazy<Element, IS_A_BLOCK> >	element;
 	Alternative< Lazy<Group, IS_A_BLOCK> >		group;
 	Alternative< Lazy<Choice, IS_A_BLOCK> >		choice;
 	Alternative< Lazy<Sequence, IS_A_BLOCK> >	sequence;
-	Alternative< Lazy<Any, IS_A_BLOCK> >		any;
+	Alternative< Lazy<Any> >					any;
 
 	Choice()
 	:	element("element"),
@@ -161,9 +157,9 @@ struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
 {
 	Alternative< Lazy<Element, IS_A_BLOCK> >	element;
 	Alternative< Lazy<Group, IS_A_BLOCK> >		group;
-	Alternative< Lazy<Choice, IS_A_BLOCK> >		choice;
+	Alternative< Lazy<Choice> >					choice;
 	Alternative< Lazy<Sequence, IS_A_BLOCK> >	sequence;
-	Alternative< Lazy<Any, IS_A_BLOCK> >		any;
+	Alternative< Lazy<Any> >					any;
 };
 
 struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
@@ -314,7 +310,6 @@ public:
 			setNameSpace(ns);
 		};
 	}
-
 };
 
 //
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 88727bf59b..29eb5ce69e 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -305,7 +305,11 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask)
 {
 	if (mEditorCore)
 	{
-		return mEditorCore->handleKeyHere(key, mask);
+		BOOL handled = mEditorCore->handleKeyHere(key, mask);
+		if (!handled)
+		{
+			LLFloater::handleKeyHere(key, mask);
+		}
 	}
 
 	return FALSE;
-- 
cgit v1.2.3


From c8bc9cca06ba33a81d4f7bb5d624519e09071d9c Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 20 Apr 2012 19:12:24 -0700
Subject: fix for gcc builds

---
 indra/llxuixml/llinitparam.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 5222d4c713..f7e5e41cae 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -55,13 +55,13 @@ namespace LLTypeTags
 	template<typename ITEM, typename REST, bool NEEDS_SWAP = GreaterThan<ITEM::SORT_ORDER, REST::SORT_ORDER>::value >
 	struct Swap
 	{
-		typedef typename ITEM::Cons<REST>::value_t value_t;
+		typedef typename ITEM::template Cons<REST>::value_t value_t;
 	};
 
 	template<typename ITEM, typename REST>
 	struct Swap<ITEM, REST, true>
 	{
-		typedef typename REST::Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t;
+		typedef typename REST::template Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t;
 	};
 
 	template<typename T, typename SORTABLE = void>
@@ -79,7 +79,7 @@ namespace LLTypeTags
 	template<typename ITEM, typename REST, bool IS_REST_SORTABLE = IsSortable<REST>::value>
 	struct InsertInto
 	{
-		typedef typename ITEM::Cons<REST>::value_t value_t;
+		typedef typename ITEM::template Cons<REST>::value_t value_t;
 	};
 
 	template<typename ITEM, typename REST>
@@ -248,7 +248,7 @@ namespace LLInitParam
 		typedef std::map<std::string, T> value_name_map_t;
 		typedef Inaccessable name_t;
 		typedef TypeValues<T> type_value_t;
-		typedef typename ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t;
 		typedef typename param_value_t::value_t	value_t;
 
 		TypeValues(const typename param_value_t::value_t& val)
@@ -745,7 +745,7 @@ namespace LLInitParam
 		struct Atomic : public LLTypeTags::TypeTagBase<T, 1>
 		{
 			template <typename S> struct Cons { typedef Atomic<ParamValue<S> > value_t; };
-			template <typename T> struct Cons<Atomic<T> > { typedef Atomic<T> value_t; };
+			template <typename S> struct Cons<Atomic<S> > { typedef Atomic<S> value_t; };
 		};
 
 		template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
-- 
cgit v1.2.3


From f11f7c78537f096a637f5f1790e4f2a089718a2e Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 20 Apr 2012 19:21:59 -0700
Subject: CHUI-92 FIX Notification count is not shown on notification chiclet

---
 indra/newview/llchiclet.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index dd0d47cccd..4236c3f359 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -926,9 +926,9 @@ protected:
 			mChiclet(chiclet)
 		{
 			// connect counter handlers to the signals
-			connectToChannel("IM Notifications");
 			connectToChannel("Group Notifications");
 			connectToChannel("Offer");
+			connectToChannel("Notifications");
 		}
 
 		static bool filterNotification(LLNotificationPtr notify);
-- 
cgit v1.2.3


From 20de8559e56df169ec7978e50061c3d587142ad5 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 20 Apr 2012 19:31:46 -0700
Subject: more gcc fixes

---
 indra/llxuixml/llinitparam.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index f7e5e41cae..a956719fa3 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -755,13 +755,13 @@ namespace LLInitParam
 			{
 				typedef Lazy<ParamValue<S, BLOCK_T>, BLOCK_T> value_t;
 			};
-			template <typename T> struct Cons<Lazy<T, IS_A_BLOCK> >
+			template <typename S> struct Cons<Lazy<S, IS_A_BLOCK> >
 			{
-				typedef Lazy<T, IS_A_BLOCK> value_t;
+				typedef Lazy<S, IS_A_BLOCK> value_t;
 			};
-			template <typename T> struct Cons<Lazy<T, NOT_A_BLOCK> >
+			template <typename S> struct Cons<Lazy<S, NOT_A_BLOCK> >
 			{
-				typedef Lazy<T, BLOCK_T> value_t;
+				typedef Lazy<S, BLOCK_T> value_t;
 			};
 		};
 
-- 
cgit v1.2.3


From dde1342fffcf0d90ef22e50405a0c4634ef22a74 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 23 Apr 2012 17:09:18 +0300
Subject: CHUI-93 FIXED Increased People floater minimum width to avoid
 scroller on the tab container.

---
 indra/newview/skins/default/xui/en/floater_people.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index 029e4464ea..45afe6b70b 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -7,7 +7,7 @@
   height="570"
   help_topic="sidebar_people"
   min_height="440"
-  min_width="333"
+  min_width="390"
   layout="topleft"
   name="floater_people"
   save_rect="true"
-- 
cgit v1.2.3


From 9b77ffb71ba112d27296b7ce8ab571285b9bba06 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 24 Apr 2012 16:51:59 -0700
Subject: CHUI-94 FIX Clicking OK on a notification does not remove the
 notification from the notifications listing

---
 indra/llxuixml/llinitparam.h    | 145 +++++++++++++++++++++++++++++++++++++++-
 indra/llxuixml/llxuiparser.cpp  |   4 +-
 indra/newview/llsyswellwindow.h |   2 +-
 3 files changed, 147 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index a956719fa3..be63e5cb39 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -207,7 +207,7 @@ namespace LLInitParam
 		typedef T	value_t;
 
 		ParamValue() 
-			:	T(),
+		:	T(),
 			mValidated(false)
 		{}
 
@@ -741,6 +741,13 @@ namespace LLInitParam
 		typedef LLInitParam::IS_A_BLOCK IS_A_BLOCK;
 		typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK;
 
+		template<typename T>
+		struct Sequential : public LLTypeTags::TypeTagBase<T, 2>
+		{
+			template <typename S> struct Cons { typedef Sequential<ParamValue<S> > value_t; };
+			template <typename S> struct Cons<Sequential<S> > { typedef Sequential<S> value_t; };
+		};
+
 		template<typename T>
 		struct Atomic : public LLTypeTags::TypeTagBase<T, 1>
 		{
@@ -2050,6 +2057,13 @@ namespace LLInitParam
 		typedef typename IsBlock<T>::value_t value_t;
 	};
 
+	template<typename T, typename BLOCK_IDENTIFIER>
+	struct IsBlock<ParamValue<BaseBlock::Sequential<T>, typename IsBlock<BaseBlock::Sequential<T> >::value_t >, BLOCK_IDENTIFIER>
+	{
+		typedef typename IsBlock<T>::value_t value_t;
+	};
+
+
 	template<typename T>
 	struct InnerMostType
 	{
@@ -2157,6 +2171,135 @@ namespace LLInitParam
 		T	mValue;
 	};
 
+	template<typename T>
+	class ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK>
+	{
+		typedef ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK> self_t;
+
+	public:
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef T									default_value_t;
+
+		ParamValue()
+		:	mValue(),
+			mValidated(false)
+		{
+			mCurParam = getBlockDescriptor().mAllParams.begin();
+		}
+
+		ParamValue(const default_value_t& value)
+		:	mValue(value),
+			mValidated(false)
+		{
+			mCurParam = getBlockDescriptor().mAllParams.begin();
+		}
+
+		void setValue(const value_t& val)
+		{
+			mValue.setValue(val);
+		}
+
+		const value_t& getValue() const
+		{
+			return mValue.getValue();
+		}
+
+		value_t& getValue()
+		{
+			return mValue.getValue();
+		}
+
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+		{
+			if (new_name)
+			{
+				mCurParam = getBlockDescriptor().mAllParams.begin();
+			}
+			if (name_stack_range.first == name_stack_range.second 
+				&& mCurParam != getBlockDescriptor().mAllParams.end())
+			{
+				// deserialize to mCurParam
+				LLParamDescriptor& pd = *(*mCurParam);
+				ParamDescriptor::deserialize_func_t deserialize_func = pd.mDeserializeFunc;
+				LLParam* paramp = mValue.getParamFromHandle(pd.mParamHandle);
+
+				if (deserialize_func 
+					&& paramp 
+					&& deserialize_func(paramp, p, name_stack_range, new_name))
+				{
+					++mCurParam;
+					return true;
+				}
+				else
+				{
+					return false;
+				}
+			}
+			else
+			{
+				return mValue.deserializeBlock(p, name_stack_range, new_name);
+			}
+		}
+
+		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+		{
+			const BaseBlock* base_block = diff_block
+				? &(diff_block->mValue)
+				: NULL;
+			mValue.serializeBlock(p, name_stack, base_block);
+		}
+
+		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+		{
+			return mValue.inspectBlock(p, name_stack, min_count, max_count);
+		}
+
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+		{
+			return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+		}
+
+		bool validateBlock(bool emit_errors = true) const
+		{
+			return mValue.validateBlock(emit_errors);
+		}
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			return value_t::getBlockDescriptor();
+		}
+
+		mutable bool 	mValidated; // lazy validation flag
+
+	private:
+
+		BlockDescriptor::all_params_list_t::iterator	mCurParam;
+		T												mValue;
+	};
+
+	template<typename T>
+	class ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK>
+	: public T
+	{
+		typedef ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> self_t;
+
+	public:
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef T									default_value_t;
+
+		ParamValue()
+		:	T(),
+			mValidated(false)
+		{}
+
+		ParamValue(const default_value_t& value)
+		:	T(value.getValue()),
+			mValidated(false)
+		{}
+
+		mutable bool 	mValidated; // lazy validation flag
+	};
+
 	template<typename T, typename BLOCK_T>
 	class ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> 
 	{
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 808e391575..9cd88a1620 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -115,8 +115,8 @@ struct All : public LLInitParam::Block<All, Occurs>
 
 struct Attribute : public LLInitParam::Block<Attribute>
 {
-	Mandatory<std::string>	name;
-	Mandatory<std::string>	type;
+	Mandatory<std::string>	name,
+							type;
 	Mandatory<EUse>			use;
 	
 	Attribute()
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index caf30cfd67..f497f546aa 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -123,7 +123,7 @@ protected:
 	struct WellNotificationChannel : public LLNotificationChannel
 	{
 		WellNotificationChannel(LLNotificationWellWindow*);
-		void onAdd(LLNotificationPtr notify)
+		void onDelete(LLNotificationPtr notify)
 		{
 			mWellWindow->removeItemByID(notify->getID());
 		} 
-- 
cgit v1.2.3


From 5955e6260e6e263fb089f7cc91c0be482cccdfb8 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 24 Apr 2012 17:10:43 -0700
Subject: CHUI-106 FIX Notifications like Friends online are shown in local
 chat history - no toast given if chat history is open

---
 indra/llui/llnotificationtemplate.h                  |  2 +-
 indra/newview/skins/default/xui/en/notifications.xml | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 8080acbf87..f7d08ae1f4 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -206,7 +206,7 @@ struct LLNotificationTemplate
 		:	name("name"),
 			persist("persist", false),
 			log_to_im("log_to_im", false),
-			log_to_chat("log_to_chat", false),
+			log_to_chat("log_to_chat", true),
 			functor("functor"),
 			icon("icon"),
 			label("label"),
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index da83ffbab4..73ec6ffdb3 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5164,7 +5164,7 @@ The string [STRING_NAME] is missing from strings.xml
    icon="notifytip.tga"
    name="IMSystemMessageTip"
    log_to_im="true"   
-   log_to_chat="true"   
+   log_to_chat="false"   
    type="notifytip">
 [MESSAGE]
   </notification>
@@ -5209,7 +5209,7 @@ Topic: [SUBJECT], Message: [MESSAGE]
   <notification
    icon="notifytip.tga"
    name="FriendOnline"
-   log_to_chat="true"
+   log_to_chat="false"
    type="notifytip">
     <tag>friendship</tag>
 &lt;nolink&gt;[NAME]&lt;/nolink&gt; is Online
@@ -5218,7 +5218,7 @@ Topic: [SUBJECT], Message: [MESSAGE]
   <notification
    icon="notifytip.tga"
    name="FriendOffline"
-   log_to_chat="true"
+   log_to_chat="false"
    type="notifytip">
     <tag>friendship</tag>
 &lt;nolink&gt;[NAME]&lt;/nolink&gt; is Offline
@@ -5466,7 +5466,7 @@ You don&apos;t have permission to copy this.
    icon="notifytip.tga"
    name="InventoryAccepted"
    log_to_im="true"   
-   log_to_chat="true"
+   log_to_chat="false"
    type="notifytip">
 [NAME] received your inventory offer.
   </notification>
@@ -5475,7 +5475,7 @@ You don&apos;t have permission to copy this.
    icon="notifytip.tga"
    name="InventoryDeclined"
    log_to_im="true"   
-   log_to_chat="true"
+   log_to_chat="false"
    type="notifytip">
 [NAME] declined your inventory offer.
   </notification>
-- 
cgit v1.2.3


From 734153b6399828cff9da44707a1720ad1b7a0c6f Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 24 Apr 2012 18:38:49 -0700
Subject: CHUI-96 FIX Cannot dismiss modal dialogs related to merchant outbox

---
 indra/newview/llfloateroutbox.cpp     | 8 ++++++++
 indra/newview/llnotificationhandler.h | 1 +
 2 files changed, 9 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 2a2b231b53..c55970ad69 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -58,6 +58,14 @@ bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotifi
 	return false;
 }
 
+void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p)
+{
+	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+	if (sys_handler)
+	{
+		sys_handler->onDelete(p);
+	}
+}
 
 ///----------------------------------------------------------------------------
 /// LLOutboxAddedObserver helper class
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 21f3961d18..1725d632e8 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -276,6 +276,7 @@ public:
 	{}
 	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
 	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ void onDelete(LLNotificationPtr p);
 	bool processNotification(const LLNotificationPtr& p);
 };
 	
-- 
cgit v1.2.3


From d5e4a69ffa8cb3cc8209f25bbfa1bc2ed49e3394 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 24 Apr 2012 18:57:13 -0700
Subject: fix for gcc builds

---
 indra/llxuixml/llinitparam.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index be63e5cb39..aa4bc73843 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -2219,9 +2219,9 @@ namespace LLInitParam
 				&& mCurParam != getBlockDescriptor().mAllParams.end())
 			{
 				// deserialize to mCurParam
-				LLParamDescriptor& pd = *(*mCurParam);
+				ParamDescriptor& pd = *(*mCurParam);
 				ParamDescriptor::deserialize_func_t deserialize_func = pd.mDeserializeFunc;
-				LLParam* paramp = mValue.getParamFromHandle(pd.mParamHandle);
+				Param* paramp = mValue.getParamFromHandle(pd.mParamHandle);
 
 				if (deserialize_func 
 					&& paramp 
-- 
cgit v1.2.3


From 6781eb101b135763a92153a3eab1245be95172bf Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 25 Apr 2012 10:28:20 -0700
Subject: more gcc build fixes

---
 indra/llxuixml/llinitparam.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index aa4bc73843..ce8a921cfe 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -2225,7 +2225,7 @@ namespace LLInitParam
 
 				if (deserialize_func 
 					&& paramp 
-					&& deserialize_func(paramp, p, name_stack_range, new_name))
+					&& deserialize_func(*paramp, p, name_stack_range, new_name))
 				{
 					++mCurParam;
 					return true;
-- 
cgit v1.2.3


From db316f830df45e1b0229ebcbdb5feedc5eb23913 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 26 Apr 2012 10:44:45 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose removed hacks for
 object inventory folderview

---
 indra/newview/llfolderview.cpp           | 23 ++++-------------
 indra/newview/llfolderview.h             |  8 ------
 indra/newview/llfolderviewitem.cpp       |  5 ++--
 indra/newview/llpanelobjectinventory.cpp | 43 +++++++++++++-------------------
 4 files changed, 25 insertions(+), 54 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index e0d7d67f7d..d54f04475f 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -176,6 +176,7 @@ LLFolderView::Params::Params()
 	show_load_status("show_load_status", true),
 	use_ellipses("use_ellipses", false)
 {
+	folder_indentation = -4;
 }
 
 
@@ -224,10 +225,7 @@ LLFolderView::LLFolderView(const Params& p)
 	mAutoOpenCandidate = NULL;
 	mAutoOpenTimer.stop();
 	mKeyboardSelection = FALSE;
-	const LLFolderViewItem::Params& item_params =
-		LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-	S32 indentation = item_params.folder_indentation();
-	mIndentation = -indentation; // children start at indentation 0
+	mIndentation = p.folder_indentation;
 	gIdleCallbacks.addFunction(idle, this);
 
 	//clear label
@@ -235,7 +233,6 @@ LLFolderView::LLFolderView(const Params& p)
 	// just make sure the label ("Inventory Folder") never shows up
 	mLabel = LLStringUtil::null;
 
-	//mRenamer->setWriteableBgColor(LLColor4::white);
 	// Escape is handled by reverting the rename, not commiting it (default behavior)
 	LLLineEditor::Params params;
 	params.name("ren");
@@ -1921,20 +1918,10 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 
 	// when drop is not handled by child, it should be handled
 	// by the folder which is the hierarchy root.
-	if (!handled)
+	if (!handled
+		&& getListener()->getUUID().notNull())
 	{
-		if (getListener()->getUUID().notNull())
-		{
-			handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-		}
-		else
-		{
-			if (!mFolders.empty())
-			{
-				// dispatch to last folder as a hack to support "Contents" folder in object inventory
-				handled = mFolders.back()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
-			}
-		}
+		handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 	}
 
 	if (handled)
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 1d018b5e6a..9a6bf05cd1 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -187,14 +187,6 @@ public:
 	// public rename functionality - can only start the process
 	void startRenamingSelectedItem( void );
 
-	// These functions were used when there was only one folderview,
-	// and relied on that concept. This functionality is now handled
-	// by the listeners and the lldraganddroptool.
-	//LLFolderViewItem*	getMovingItem() { return mMovingItem; }
-	//void setMovingItem( LLFolderViewItem* item ) { mMovingItem = item; }
-	//void				dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
-	//void				dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
-
 	// LLView functionality
 	///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
 	/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 8d6114c887..ab1794ff15 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -417,9 +417,8 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
 	const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	S32 indentation = p.folder_indentation();
 	// Only indent deeper items in hierarchy
-	mIndentation = (getParentFolder() 
-					&& getParentFolder()->getParentFolder() )
-		? mParentFolder->getIndentation() + indentation
+	mIndentation = (getParentFolder())
+		? getParentFolder()->getIndentation() + indentation
 		: 0;
 	if (mLabelWidthDirty)
 	{
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 98ea680504..1efd1c3d9c 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -738,15 +738,7 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
 
 	if (cat)
 	{
-		// Localize "Contents" folder.
-		if (cat->getParentUUID().isNull() && cat->getName() == "Contents")
-		{
-			mDisplayName.assign(LLTrans::getString("ViewerObjectContents"));
-		}
-		else
-		{
-			mDisplayName.assign(cat->getName());
-		}
+		mDisplayName.assign(cat->getName());
 	}
 
 	return mDisplayName;
@@ -1552,6 +1544,7 @@ void LLPanelObjectInventory::reset()
 	p.parent_panel = this;
 	p.tool_tip= LLTrans::getString("PanelContentsTooltip");
 	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
+	p.folder_indentation = -14; // subtract space normally reserved for folder expanders
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
 	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
@@ -1630,10 +1623,11 @@ void LLPanelObjectInventory::updateInventory()
 		LLInventoryObject* inventory_root = objectp->getInventoryRoot();
 		LLInventoryObject::object_list_t contents;
 		objectp->getInventoryContents(contents);
-		if (inventory_root)
+		mHaveInventory = TRUE;
+
+		if (inventory_root && !contents.empty())
 		{
 			createFolderViews(inventory_root, contents);
-			mHaveInventory = TRUE;
 			mIsInventoryEmpty = FALSE;
 			mFolders->setEnabled(TRUE);
 		}
@@ -1641,7 +1635,6 @@ void LLPanelObjectInventory::updateInventory()
 		{
 			// TODO: create an empty inventory
 			mIsInventoryEmpty = TRUE;
-			mHaveInventory = TRUE;
 		}
 	}
 	else
@@ -1693,19 +1686,19 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
 	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
 	if(bridge)
 	{
-		LLFolderViewFolder* new_folder = NULL;
-		LLFolderViewFolder::Params p;
-		p.name = inventory_root->getName();
-		p.icon = LLUI::getUIImage("Inv_FolderClosed");
-		p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
-		p.root = mFolders;
-		p.listener = bridge;
-		p.tool_tip = p.name;
-		new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
-		new_folder->addToFolder(mFolders, mFolders);
-		new_folder->toggleOpen();
-
-		createViewsForCategory(&contents, inventory_root, new_folder);
+		//LLFolderViewFolder* new_folder = NULL;
+		//LLFolderViewFolder::Params p;
+		//p.name = inventory_root->getName();
+		//p.icon = LLUI::getUIImage("Inv_FolderClosed");
+		//p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
+		//p.root = mFolders;
+		//p.listener = bridge;
+		//p.tool_tip = p.name;
+		//new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
+		//new_folder->addToFolder(mFolders, mFolders);
+		//new_folder->toggleOpen();
+
+		createViewsForCategory(&contents, inventory_root, mFolders);
 	}
 }
 
-- 
cgit v1.2.3


From 28d5727cecdad638202106fd1289bee25c0f97bd Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 26 Apr 2012 15:30:08 -0700
Subject: post-merge build fixes

---
 indra/llxuixml/llinitparam.h                 |  4 +-
 indra/newview/llfolderviewitem.cpp           |  2 +-
 indra/newview/llimhandler.cpp                | 56 +++++++++----------
 indra/newview/llnotificationgrouphandler.cpp |  1 +
 indra/newview/llnotificationhandler.h        |  2 +-
 indra/newview/llnotificationofferhandler.cpp |  2 +-
 indra/newview/llnotificationtiphandler.cpp   | 81 +++++++++++++---------------
 indra/newview/llviewerwindow.cpp             | 12 ++---
 indra/newview/llviewerwindow.h               |  3 ++
 9 files changed, 81 insertions(+), 82 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 2c854d8287..29f4a09cb7 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -1405,7 +1405,7 @@ namespace LLInitParam
 			return *this;
 		}
 
-		self_t& add(const typename named_value_lookup_t::name_t& name)
+		self_t& add(const typename named_value_t::name_t& name)
 		{
 			value_t value;
 
@@ -1612,7 +1612,7 @@ namespace LLInitParam
 			return *this;
 		}
 
-		self_t& add(const typename named_value_lookup_t::name_t& name)
+		self_t& add(const typename named_value_t::name_t& name)
 		{
 			value_t value;
 
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index c2dec4ab27..43d3675d17 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -357,7 +357,7 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
 	LLFolderView* root = getRoot();
 	if (getParentFolder())
 	{
-	getParentFolder()->requestArrange();
+		getParentFolder()->requestArrange();
 	}
 	if(set_selection)
 	{
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index c7034aea3a..047472a282 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -71,34 +71,34 @@ bool LLIMHandler::processNotification(const LLNotificationPtr& notification)
 		initChannel();
 	}
 
-		LLSD substitutions = notification->getSubstitutions();
-
-		// According to comments in LLIMMgr::addMessage(), if we get message
-		// from ourselves, the sender id is set to null. This fixes EXT-875.
-		LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
-		if (avatar_id.isNull())
-			avatar_id = gAgentID;
-
-		LLToastIMPanel::Params im_p;
-		im_p.notification = notification;
-		im_p.avatar_id = avatar_id;
-		im_p.from = substitutions["FROM"].asString();
-		im_p.time = substitutions["TIME"].asString();
-		im_p.message = substitutions["MESSAGE"].asString();
-		im_p.session_id = substitutions["SESSION_ID"].asUUID();
-
-		LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
-
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.session_id = im_p.session_id;
-		p.notification = notification;
-		p.panel = im_box;
-		p.can_be_stored = false;
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->addToast(p);
-	}
+	LLSD substitutions = notification->getSubstitutions();
+
+	// According to comments in LLIMMgr::addMessage(), if we get message
+	// from ourselves, the sender id is set to null. This fixes EXT-875.
+	LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
+	if (avatar_id.isNull())
+		avatar_id = gAgentID;
+
+	LLToastIMPanel::Params im_p;
+	im_p.notification = notification;
+	im_p.avatar_id = avatar_id;
+	im_p.from = substitutions["FROM"].asString();
+	im_p.time = substitutions["TIME"].asString();
+	im_p.message = substitutions["MESSAGE"].asString();
+	im_p.session_id = substitutions["SESSION_ID"].asUUID();
+
+	LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
+
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.session_id = im_p.session_id;
+	p.notification = notification;
+	p.panel = im_box;
+	p.can_be_stored = false;
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	if(channel)
+		channel->addToast(p);
+
 	return false;
 }
 
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 50db4737ce..6946b78cbf 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -43,6 +43,7 @@ LLGroupHandler::LLGroupHandler()
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
 	if(channel)
+	{
 		channel->addOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 805e29e2a4..83d228e799 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -95,7 +95,7 @@ public:
 	// base interface functions
 	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
 	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel) mChannel->killToastByNotificationID(p->getID());}
+	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->killToastByNotificationID(p->getID());}
 
 	virtual bool processNotification(const LLNotificationPtr& notify)=0;
 
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 52cc518968..2112b0d35e 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -48,7 +48,7 @@ LLOfferHandler::LLOfferHandler()
 	if(channel)
 	{
 		channel->setControlHovering(true);
-		channel->setOnRejectToastCallback(boost::bind(&LLOfferHandler::onRejectToast, this, _1));
+		channel->addOnRejectToastCallback(boost::bind(&LLOfferHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index f07109335d..3588721849 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -82,61 +82,56 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 
 		// archive message in nearby chat
 	if (notification->canLogToChat())
-		{
-			LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
-
-			// don't show toast if Nearby Chat is opened
-			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-			LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
-			if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible())
-			{
-				return false;
-			}
-		}
+	{
+		LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
 
-		std::string session_name = notification->getPayload()["SESSION_NAME"];
-		const std::string name = notification->getSubstitutions()["NAME"];
-		if (session_name.empty())
+		// don't show toast if Nearby Chat is opened
+		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
+		LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
+		if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible())
 		{
-			session_name = name;
+			return false;
 		}
-		LLUUID from_id = notification->getPayload()["from_id"];
+	}
+
+	std::string session_name = notification->getPayload()["SESSION_NAME"];
+	const std::string name = notification->getSubstitutions()["NAME"];
+	if (session_name.empty())
+	{
+		session_name = name;
+	}
+	LLUUID from_id = notification->getPayload()["from_id"];
 	if (notification->canLogToIM())
-		{
-			LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
-					notification->getMessage(), from_id, from_id);
-		}
+	{
+		LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
+				notification->getMessage(), from_id, from_id);
+	}
 
 	if (notification->canLogToIM() && notification->hasFormElements())
-		{
-			LLHandlerUtil::spawnIMSession(name, from_id);
-		}
+	{
+		LLHandlerUtil::spawnIMSession(name, from_id);
+	}
 
 	if (notification->canLogToIM() && LLHandlerUtil::isIMFloaterOpened(notification))
-		{
-			return false;
-		}
+	{
+		return false;
+	}
 
-		LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
+	LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
 
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.notification = notification;
-		p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
-		p.panel = notify_box;
-		p.is_tip = true;
-		p.can_be_stored = false;
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.notification = notification;
+	p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
+	p.panel = notify_box;
+	p.is_tip = true;
+	p.can_be_stored = false;
 		
-		removeExclusiveNotifications(notification);
+	removeExclusiveNotifications(notification);
 
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->addToast(p);
-	}
-	else if (notify["sigtype"].asString() == "delete")
-	{
-		mChannel->killToastByNotificationID(notification->getID());
-	}
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	if(channel)
+		channel->addToast(p);
 	return false;
 }
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 117078bcd1..32f693b009 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1542,14 +1542,14 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	// pass its value right now. Instead, pass it a nullary function that
 	// will, when we later need it, return the value of gKeyboard.
 	// boost::lambda::var() constructs such a functor on the fly.
-	mWindowListener(new LLWindowListener(this, boost::lambda::var(gKeyboard))),
-	mViewerWindowListener(new LLViewerWindowListener(this)),
+	mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
+	mViewerWindowListener.reset(new LLViewerWindowListener(this));
 
-	LLNotificationChannelPtr vw_alerts_channel(new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")));
-	LLNotificationChannelPtr vw_alerts_modal_channel(new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")));
+	mAlertsChannel.reset(new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")));
+	mModalAlertsChannel.reset(new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")));
 
-	vw_alerts_channel->connectChanged(&LLViewerWindow::onAlert);
-	vw_alerts_modal_channel->connectChanged(&LLViewerWindow::onAlert);
+	mAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
+	mModalAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
 	LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
 	llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
 
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 6efcaeaf18..ee6a7793f8 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -418,6 +418,9 @@ private:
 	bool			mActive;
 	bool			mUIVisible;
 
+	boost::shared_ptr<class LLNotificationChannel>	mAlertsChannel,
+													mModalAlertsChannel;
+
 	LLRect			mWindowRectRaw;				// whole window, including UI
 	LLRect			mWindowRectScaled;			// whole window, scaled by UI size
 	LLRect			mWorldViewRectRaw;			// area of screen for 3D world
-- 
cgit v1.2.3


From 2babcb4af56e6b7fb443f1b78002dc9e61e891c7 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 23 Feb 2012 21:02:46 +0200
Subject: Linux build fix. Moved type casts from protected base classes to
 derived LLCoord.

---
 indra/llmath/llcoord.h      | 19 +++++++++++++------
 indra/llui/llfloater.cpp    |  4 ++--
 indra/llwindow/llwindow.cpp |  8 ++++----
 3 files changed, 19 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/llmath/llcoord.h b/indra/llmath/llcoord.h
index 1f617e649e..a66f3c7424 100644
--- a/indra/llmath/llcoord.h
+++ b/indra/llmath/llcoord.h
@@ -26,6 +26,15 @@
 #ifndef LL_LLCOORD_H
 #define LL_LLCOORD_H
 
+template<typename> class LLCoord;
+struct LL_COORD_TYPE_GL;
+struct LL_COORD_TYPE_WINDOW;
+struct LL_COORD_TYPE_SCREEN;
+
+typedef LLCoord<LL_COORD_TYPE_GL> LLCoordGL;
+typedef LLCoord<LL_COORD_TYPE_WINDOW> LLCoordWindow;
+typedef LLCoord<LL_COORD_TYPE_SCREEN> LLCoordScreen;
+
 struct LLCoordCommon
 {
 	LLCoordCommon(S32 x, S32 y) : mX(x), mY(y) {}
@@ -62,6 +71,8 @@ public:
 	bool operator==(const self_t& other) const { return mX == other.mX && mY == other.mY; }
 	bool operator!=(const self_t& other) const { return !(*this == other); }
 
+	static const self_t& getTypedCoords(const COORD_FRAME& self) { return static_cast<const self_t&>(self); }
+	static self_t& getTypedCoords(COORD_FRAME& self) { return static_cast<self_t&>(self); }
 };
 
 struct LL_COORD_TYPE_GL 
@@ -70,13 +81,13 @@ struct LL_COORD_TYPE_GL
 
 	LLCoordCommon convertToCommon() const
 	{
-		const LLCoord<LL_COORD_TYPE_GL>& self = static_cast<const LLCoord<LL_COORD_TYPE_GL>&>(*this);
+		const LLCoordGL& self = LLCoordGL::getTypedCoords(*this);
 		return LLCoordCommon(self.mX, self.mY);
 	}
 
 	void convertFromCommon(const LLCoordCommon& from)
 	{
-		LLCoord<LL_COORD_TYPE_GL>& self = static_cast<LLCoord<LL_COORD_TYPE_GL>&>(*this);
+		LLCoordGL& self = LLCoordGL::getTypedCoords(*this);
 		self.mX = from.mX;
 		self.mY = from.mY;
 	}
@@ -98,8 +109,4 @@ struct LL_COORD_TYPE_SCREEN
 	void convertFromCommon(const LLCoordCommon& from);
 };
 
-typedef LLCoord<LL_COORD_TYPE_GL> LLCoordGL;
-typedef LLCoord<LL_COORD_TYPE_WINDOW> LLCoordWindow;
-typedef LLCoord<LL_COORD_TYPE_SCREEN> LLCoordScreen;
-
 #endif
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 22b20969fc..51611d547c 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -3306,7 +3306,7 @@ bool LLCoordFloater::operator==(const LLCoordFloater& other) const
 
 LLCoordCommon LL_COORD_FLOATER::convertToCommon() const
 {
-	const LLCoordFloater& self = static_cast<const LLCoordFloater&>(*this);
+	const LLCoordFloater& self = static_cast<const LLCoordFloater&>(LLCoordFloater::getTypedCoords(*this));
 
 	LLRect snap_rect = gFloaterView->getSnapRect();
 	LLFloater* floaterp = mFloater.get();
@@ -3348,7 +3348,7 @@ LLCoordCommon LL_COORD_FLOATER::convertToCommon() const
 
 void LL_COORD_FLOATER::convertFromCommon(const LLCoordCommon& from)
 {
-	LLCoordFloater& self = static_cast<LLCoordFloater&>(*this);
+	LLCoordFloater& self = static_cast<LLCoordFloater&>(LLCoordFloater::getTypedCoords(*this));
 	LLRect snap_rect = gFloaterView->getSnapRect();
 	LLFloater* floaterp = mFloater.get();
 	S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0;
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 6834b34387..4e91271d83 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -440,7 +440,7 @@ BOOL LLWindowManager::isWindowValid(LLWindow *window)
 //coordinate conversion utility funcs that forward to llwindow
 LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const
 {
-	const LLCoordWindow& self = static_cast<const LLCoordWindow&>(*this);
+	const LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this);
 
 	LLWindow* windowp = &(*LLWindow::beginInstances());
 	LLCoordGL out;
@@ -450,7 +450,7 @@ LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const
 
 void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from)
 {
-	LLCoordWindow& self = static_cast<LLCoordWindow&>(*this);
+	LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this);
 
 	LLWindow* windowp = &(*LLWindow::beginInstances());
 	LLCoordGL from_gl(from);
@@ -459,7 +459,7 @@ void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from)
 
 LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const
 {
-	const LLCoordScreen& self = static_cast<const LLCoordScreen&>(*this);
+	const LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this);
 
 	LLWindow* windowp = &(*LLWindow::beginInstances());
 	LLCoordGL out;
@@ -469,7 +469,7 @@ LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const
 
 void LL_COORD_TYPE_SCREEN::convertFromCommon(const LLCoordCommon& from)
 {
-	LLCoordScreen& self = static_cast<LLCoordScreen&>(*this);
+	LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this);
 
 	LLWindow* windowp = &(*LLWindow::beginInstances());
 	LLCoordGL from_gl(from);
-- 
cgit v1.2.3


From cf86247b8c5e199447b7cd3dc645a42a6a645265 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 26 Apr 2012 23:52:57 +0300
Subject: CHUI-78 WIP Reordered and added missing items for People floater gear
 menus.

---
 indra/newview/llpanelpeoplemenus.cpp               |  1 +
 .../skins/default/xui/en/menu_people_groups.xml    | 23 +++++----
 .../skins/default/xui/en/menu_people_nearby.xml    | 56 +++++++++++++---------
 3 files changed, 45 insertions(+), 35 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index f12c4de2f7..0d66b8f10b 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -67,6 +67,7 @@ LLContextMenu* NearbyMenu::createMenu()
 		registrar.add("Avatar.Share",			boost::bind(&LLAvatarActions::share,					id));
 		registrar.add("Avatar.Pay",				boost::bind(&LLAvatarActions::pay,						id));
 		registrar.add("Avatar.BlockUnblock",	boost::bind(&LLAvatarActions::toggleBlock,				id));
+		registrar.add("Avatar.InviteToGroup",	boost::bind(&LLAvatarActions::inviteToGroup,			id));
 
 		enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem,	this, _2));
 		enable_registrar.add("Avatar.CheckItem",  boost::bind(&NearbyMenu::checkContextMenuItem,	this, _2));
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups.xml b/indra/newview/skins/default/xui/en/menu_people_groups.xml
index 3a450258fa..1e0364b84e 100644
--- a/indra/newview/skins/default/xui/en/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_groups.xml
@@ -2,6 +2,16 @@
 <toggleable_menu name="menu_group_plus"
  left="0" bottom="0" visible="false"
  mouse_opaque="false" opaque="true" color="MenuDefaultBgColor">
+  <menu_item_call
+   label="Activate"
+   name="Activate">
+    <menu_item_call.on_click
+     function="People.Groups.Action"
+     parameter="activate" />
+    <menu_item_call.on_enable
+     function="People.Groups.Enable"
+     parameter="activate" />
+  </menu_item_call>
   <menu_item_call
    label="View Info"
    name="View Info">
@@ -23,7 +33,7 @@
      parameter="chat" />
   </menu_item_call>
   <menu_item_call
-   label="Call"
+   label="Voice call"
    name="Call">
     <menu_item_call.on_click
      function="People.Groups.Action"
@@ -33,17 +43,6 @@
      parameter="call" />
   </menu_item_call>
   <menu_item_separator />
-  <menu_item_call
-   label="Activate"
-   name="Activate">
-    <menu_item_call.on_click
-     function="People.Groups.Action"
-     parameter="activate" />
-    <menu_item_call.on_enable
-     function="People.Groups.Enable"
-     parameter="activate" />
-  </menu_item_call>
-  <menu_item_separator />
   <menu_item_call
    label="Leave"
    name="Leave">
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
index d2e35e4cc0..b7c9ab1fe3 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -9,13 +9,40 @@
         <menu_item_call.on_click
          function="Avatar.Profile" />
     </menu_item_call>
+    <menu_item_call
+     label="IM"
+     layout="topleft"
+     name="IM">
+        <menu_item_call.on_click
+         function="Avatar.IM" />
+    </menu_item_call>
+    <menu_item_call
+    label="Offer Teleport"
+    name="teleport">
+      <menu_item_call.on_click
+       function="Avatar.OfferTeleport"/>
+      <menu_item_call.on_enable
+      function="Avatar.EnableItem"
+      parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Voice call"
+     layout="topleft"
+     name="Call">
+        <menu_item_call.on_click
+         function="Avatar.Call" />
+        <menu_item_call.on_enable
+         function="Avatar.EnableItem"
+         parameter="can_call" />
+    </menu_item_call>
+    <menu_item_separator />
     <menu_item_call
      label="Add Friend"
      layout="topleft"
      name="Add Friend">
         <menu_item_call.on_click
          function="Avatar.AddFriend" />
-        <menu_item_call.on_enable
+        <menu_item_call.on_visible
          function="Avatar.EnableItem"
          parameter="can_add" />
     </menu_item_call>
@@ -30,22 +57,13 @@
          parameter="can_delete" />
     </menu_item_call>
     <menu_item_call
-     label="IM"
+     label="Invite to group..."
      layout="topleft"
-     name="IM">
+     name="Invite">
         <menu_item_call.on_click
-         function="Avatar.IM" />
-    </menu_item_call>
-    <menu_item_call
-     label="Call"
-     layout="topleft"
-     name="Call">
-        <menu_item_call.on_click
-         function="Avatar.Call" />
-        <menu_item_call.on_enable
-         function="Avatar.EnableItem"
-         parameter="can_call" />
+         function="Avatar.InviteToGroup" />
     </menu_item_call>
+    <menu_item_separator />
     <menu_item_call
      label="Map"
      layout="topleft"
@@ -83,13 +101,5 @@
          function="Avatar.EnableItem"
          parameter="can_block" />
     </menu_item_check>
-    <menu_item_call
-    label="Offer Teleport"
-    name="teleport">
-      <menu_item_call.on_click
-       function="Avatar.OfferTeleport"/>
-      <menu_item_call.on_enable
-      function="Avatar.EnableItem"
-      parameter="can_offer_teleport"/>
-    </menu_item_call>
+
 </context_menu>
-- 
cgit v1.2.3


From f948ba82a985c2fec5ed1e65a55bd68f6e811197 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 4 May 2012 22:08:13 +0300
Subject: CHUI-103 WIP Added support for showing/hiding timestamp and names,
 replacing own name with (You)

---
 indra/newview/llchathistory.cpp                | 30 ++++++++++++++++++--------
 indra/newview/skins/default/xui/en/strings.xml |  1 +
 2 files changed, 22 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 5bdfb5adbc..143d4ff4fe 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -778,15 +778,19 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	if (use_plain_text_chat_history)
 	{
 		LLStyle::Params timestamp_style(style_params);
-		if (!message_from_log)
+
+		if (args["show_time"].asBoolean())
 		{
-			LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
-			timestamp_style.color(timestamp_color);
-			timestamp_style.readonly_color(timestamp_color);
+			if (!message_from_log)
+			{
+				LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
+				timestamp_style.color(timestamp_color);
+				timestamp_style.readonly_color(timestamp_color);
+			}
+			mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style);
 		}
-		mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style);
 
-		if (utf8str_trim(chat.mFromName).size() != 0)
+		if (args["show_names_in_p2p_chat"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0)
 		{
 			// Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
 			if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())
@@ -806,13 +810,21 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				mEditor->appendText(chat.mFromName + delimiter,
 									false, link_params);
 			}
-			else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
+			else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
 			{
 				LLStyle::Params link_params(style_params);
 				link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));
 
-				// Add link to avatar's inspector and delimiter to message.
-				mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params);
+				if (gAgentID == chat.mFromID)
+				{	std::string localized_name;
+					bool is_localized = LLTrans::findString(localized_name, "AgentNameSubst");
+					mEditor->appendText((is_localized? localized_name:"(You)") + delimiter, false, link_params);
+				}
+				else
+				{
+					// Add link to avatar's inspector and delimiter to message.
+					mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params);
+				}
 			}
 			else
 			{
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 9752652679..0beb8ed0ab 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -405,6 +405,7 @@ Please try logging in again in a minute.</string>
 	<string name="TrackYourCamera">Track your camera</string>
 	<string name="ControlYourCamera">Control your camera</string>
 	<string name="NotConnected">Not Connected</string>
+	<string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name -->
 
 	<!-- Sim Access labels -->
 	<string name="SIM_ACCESS_PG">General</string>
-- 
cgit v1.2.3


From 79928c65329146920558d9bc286f643ccf8dca7f Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 7 May 2012 20:05:07 +0300
Subject: CHUI-103 Repair drawing messages with prepend new line

---
 indra/newview/llchathistory.cpp | 21 ++++++++++++++-------
 indra/newview/llchathistory.h   |  4 ++++
 2 files changed, 18 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 143d4ff4fe..30b2839547 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -775,10 +775,13 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		style_params.readonly_color(LLColor4::grey);
 	}
 
+	mPrependNewLineState = (mEditor->getText().size() != 0)? 1 : 0;
+
 	if (use_plain_text_chat_history)
 	{
 		LLStyle::Params timestamp_style(style_params);
 
+		// timestams showing
 		if (args["show_time"].asBoolean())
 		{
 			if (!message_from_log)
@@ -787,9 +790,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				timestamp_style.color(timestamp_color);
 				timestamp_style.readonly_color(timestamp_color);
 			}
-			mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style);
+			mEditor->appendText("[" + chat.mTimeStr + "] ", isNeedPrependNewline(), timestamp_style);
 		}
 
+		// names showing
 		if (args["show_names_in_p2p_chat"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0)
 		{
 			// Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
@@ -807,8 +811,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				link_params.is_link = true;
 				link_params.link_href = url;
 
-				mEditor->appendText(chat.mFromName + delimiter,
-									false, link_params);
+				mEditor->appendText(chat.mFromName + delimiter, isNeedPrependNewline(), link_params);
 			}
 			else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
 			{
@@ -818,22 +821,26 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				if (gAgentID == chat.mFromID)
 				{	std::string localized_name;
 					bool is_localized = LLTrans::findString(localized_name, "AgentNameSubst");
-					mEditor->appendText((is_localized? localized_name:"(You)") + delimiter, false, link_params);
+					mEditor->appendText((is_localized? localized_name:"(You)") + delimiter,
+							isNeedPrependNewline(), link_params);
 				}
 				else
 				{
 					// Add link to avatar's inspector and delimiter to message.
-					mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params);
+					mEditor->appendText(std::string(link_params.link_href) + delimiter,
+							isNeedPrependNewline(), link_params);
 				}
 			}
 			else
 			{
-				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, false, style_params);
+				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
+						isNeedPrependNewline(), style_params);
 			}
 		}
 	}
 	else
 	{
+		mPrependNewLineState = 0;
 		LLView* view = NULL;
 		LLInlineViewSegment::Params p;
 		p.force_newline = true;
@@ -956,7 +963,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			message = chat.mFromName + message;
 		}
 		
-		mEditor->appendText(message, FALSE, style_params);
+		mEditor->appendText(message, isNeedPrependNewline(), style_params);
 	}
 
 	mEditor->blockUndo();
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index 28344e6a10..4cd9c75e1c 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -138,6 +138,10 @@ class LLChatHistory : public LLUICtrl
 		S32 mTopHeaderPad;
 		S32 mBottomHeaderPad;
 
+		S32 mPrependNewLineState;
+
+		bool isNeedPrependNewline() {return (mPrependNewLineState-- > 0);}
+
 		class LLLayoutPanel*	mMoreChatPanel;
 		LLTextBox*		mMoreChatText;
 		LLTextEditor*	mEditor;
-- 
cgit v1.2.3


From 7b8251fd2f169136fc45e4c17104da676f75727b Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 7 May 2012 21:54:09 +0300
Subject: CHUI-103 WIP Added settings for switching text view mode

---
 indra/newview/app_settings/settings.xml | 23 +++++++++++++++++++++++
 indra/newview/llchathistory.cpp         | 24 +++++++++++++++---------
 indra/newview/llchathistory.h           |  4 ----
 indra/newview/llimfloater.cpp           |  3 +++
 4 files changed, 41 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ee8c15752b..e6d0ed7dfa 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2,6 +2,29 @@
 <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="llsd.xsd">
 <map>
+    <key>IMShowTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable(disable) timestamp showing in the chat.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>IMShowNamesForP2PConv</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable(disable) showing of a names in the chat.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+
 	<key>CrashHostUrl</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 30b2839547..b70e98f22b 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -775,7 +775,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		style_params.readonly_color(LLColor4::grey);
 	}
 
-	mPrependNewLineState = (mEditor->getText().size() != 0)? 1 : 0;
+	bool prependNewLineState = mEditor->getText().size() != 0;
 
 	if (use_plain_text_chat_history)
 	{
@@ -790,11 +790,12 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				timestamp_style.color(timestamp_color);
 				timestamp_style.readonly_color(timestamp_color);
 			}
-			mEditor->appendText("[" + chat.mTimeStr + "] ", isNeedPrependNewline(), timestamp_style);
+			mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style);
+			prependNewLineState = false;
 		}
 
 		// names showing
-		if (args["show_names_in_p2p_chat"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0)
+		if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0)
 		{
 			// Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
 			if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())
@@ -811,7 +812,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				link_params.is_link = true;
 				link_params.link_href = url;
 
-				mEditor->appendText(chat.mFromName + delimiter, isNeedPrependNewline(), link_params);
+				mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params);
+				prependNewLineState = false;
 			}
 			else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
 			{
@@ -822,25 +824,28 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				{	std::string localized_name;
 					bool is_localized = LLTrans::findString(localized_name, "AgentNameSubst");
 					mEditor->appendText((is_localized? localized_name:"(You)") + delimiter,
-							isNeedPrependNewline(), link_params);
+							prependNewLineState, link_params);
+					prependNewLineState = false;
 				}
 				else
 				{
 					// Add link to avatar's inspector and delimiter to message.
 					mEditor->appendText(std::string(link_params.link_href) + delimiter,
-							isNeedPrependNewline(), link_params);
+							prependNewLineState, link_params);
+					prependNewLineState = false;
 				}
 			}
 			else
 			{
 				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
-						isNeedPrependNewline(), style_params);
+						prependNewLineState, style_params);
+				prependNewLineState = false;
 			}
 		}
 	}
 	else
 	{
-		mPrependNewLineState = 0;
+		prependNewLineState = 0;
 		LLView* view = NULL;
 		LLInlineViewSegment::Params p;
 		p.force_newline = true;
@@ -963,7 +968,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			message = chat.mFromName + message;
 		}
 		
-		mEditor->appendText(message, isNeedPrependNewline(), style_params);
+		mEditor->appendText(message, prependNewLineState, style_params);
+		prependNewLineState = false;
 	}
 
 	mEditor->blockUndo();
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index 4cd9c75e1c..28344e6a10 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -138,10 +138,6 @@ class LLChatHistory : public LLUICtrl
 		S32 mTopHeaderPad;
 		S32 mBottomHeaderPad;
 
-		S32 mPrependNewLineState;
-
-		bool isNeedPrependNewline() {return (mPrependNewLineState-- > 0);}
-
 		class LLLayoutPanel*	mMoreChatPanel;
 		LLTextBox*		mMoreChatText;
 		LLTextEditor*	mEditor;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index f67464078b..f743b5e2bf 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -630,6 +630,9 @@ void LLIMFloater::updateMessages()
 	{
 		LLSD chat_args;
 		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] =
+				gSavedSettings.getBOOL("IMShowNamesForP2PConv");
 
 		std::ostringstream message;
 		std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
-- 
cgit v1.2.3


From fac210075f4c68db372ae0535e332ffe9765a5d1 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Mon, 7 May 2012 22:40:56 +0300
Subject: CHUI-105 WIP Added tear-off and return behavior for IM floater. XUI
 changed for Converstions multifloater and IM floater.

---
 indra/llui/llfloater.cpp                           |   4 +-
 indra/newview/llimfloater.cpp                      |  46 ++++++
 indra/newview/llimfloater.h                        |   2 +
 indra/newview/llimfloatercontainer.cpp             |  24 ++++
 indra/newview/llimfloatercontainer.h               |   1 +
 .../skins/default/xui/en/floater_im_container.xml  | 111 ++++++++++-----
 .../skins/default/xui/en/floater_im_session.xml    | 158 +++++++++++++++++----
 7 files changed, 281 insertions(+), 65 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 51611d547c..b087205a5c 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1371,7 +1371,7 @@ void LLFloater::setHost(LLMultiFloater* host)
 		mButtonScale = 1.f;
 		//mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE;
 	}
-	updateTitleButtons();
+
 	if (host)
 	{
 		mHostHandle = host->getHandle();
@@ -1381,6 +1381,8 @@ void LLFloater::setHost(LLMultiFloater* host)
 	{
 		mHostHandle.markDead();
 	}
+
+	updateTitleButtons();
 }
 
 void LLFloater::moveResizeHandlesToFront()
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index f743b5e2bf..df3521ecb0 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -28,6 +28,7 @@
 
 #include "llimfloater.h"
 
+#include "lldraghandle.h"
 #include "llnotificationsutil.h"
 
 #include "llagent.h"
@@ -251,6 +252,12 @@ BOOL LLIMFloater::postBuild()
 	slide_right->setVisible(!mControlPanel->getParent()->getVisible());
 	slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
 
+	LLButton* return_btn = getChild<LLButton>("return_btn");
+	return_btn->setCommitCallback(boost::bind(&LLFloater::onClickTearOff, this));
+
+	LLButton* tear_off_btn = getChild<LLButton>("tear_off_btn");
+	tear_off_btn->setCommitCallback(boost::bind(&LLFloater::onClickTearOff, this));
+
 	mInputEditor = getChild<LLLineEditor>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
 	// enable line history support for instant message bar
@@ -1194,3 +1201,42 @@ void	LLIMFloater::onClickCloseBtn()
 
 	LLFloater::onClickCloseBtn();
 }
+
+// virtual
+void LLIMFloater::updateTitleButtons()
+{
+	if (!mDragHandle)
+	{
+		return;
+	}
+
+	LLMultiFloater* host_floater = getHost();
+
+	bool is_hosted = host_floater != NULL;
+	if (is_hosted) ///< floater is hosted
+	{
+		for (S32 i = 0; i < BUTTON_COUNT; i++)
+		{
+			if (!mButtons[i])
+			{
+				continue;
+			}
+
+			// Hide the standard header buttons in a docked IM floater.
+			mButtons[i]->setVisible(false);
+		}
+	}
+	else ///< floater is torn off
+	{
+		LLFloater::updateTitleButtons();
+	}
+
+	// toggle floater's drag handle and title visibility
+	mDragHandle->setVisible(!is_hosted);
+	
+	LLButton* return_btn = getChild<LLButton>("return_btn");
+	return_btn->setVisible(!is_hosted);
+
+	LLButton* tear_off_btn = getChild<LLButton>("tear_off_btn");
+	tear_off_btn->setVisible(is_hosted);
+}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index f7cd35b5eb..95aa214ff6 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -120,6 +120,8 @@ protected:
 	/* virtual */
 	void	onClickCloseBtn();
 
+	/*virtual*/ void	updateTitleButtons();
+
 private:
 	// process focus events to set a currently active session
 	/* virtual */ void onFocusLost();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c8e48b0d42..9b5055fb98 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -56,6 +56,9 @@ BOOL LLIMFloaterContainer::postBuild()
 	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));
 	// Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
 	// mTabContainer will be initialized in LLMultiFloater::addChild()
+	
+	setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
+
 	return TRUE;
 }
 
@@ -74,6 +77,7 @@ void LLIMFloaterContainer::onOpen(const LLSD& key)
 */
 }
 
+// virtual
 void LLIMFloaterContainer::addFloater(LLFloater* floaterp, 
 									BOOL select_added_floater, 
 									LLTabContainer::eInsertionPoint insertion_point)
@@ -89,6 +93,12 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
+	LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
+
+	// we don't show the header when the floater is hosted,
+	// so reshape floater contents to occupy the header space
+	floater_contents->setShape(floaterp->getRect());
+
 	LLUUID session_id = floaterp->getKey();
 
 	LLIconCtrl* icon = 0;
@@ -116,6 +126,20 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 	mTabContainer->setTabImage(floaterp, icon);
 }
 
+// virtual
+void LLIMFloaterContainer::removeFloater(LLFloater* floaterp)
+{
+	LLMultiFloater::removeFloater(floaterp);
+
+	LLRect contents_rect = floaterp->getRect();
+
+	// reduce the floater contents height by header height
+	contents_rect.mTop -= floaterp->getHeaderHeight();
+
+	LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
+	floater_contents->setShape(contents_rect);
+}
+
 void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
 {
 	mSessions.erase(id);
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 892ecef48d..93b91fe3cf 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -50,6 +50,7 @@ public:
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+	/*virtual*/ void removeFloater(LLFloater* floaterp);
 
 	static LLFloater* getCurrentVoiceFloater();
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index e123de46c2..d19b36971f 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -3,47 +3,86 @@
  can_close="false"  
  can_minimize="true"
  can_resize="true"
- height="390"
+ height="430"
  layout="topleft"
+ min_width="510"
  name="floater_im_box"
  help_topic="floater_im_box"
  save_rect="true"
  save_visibility="true"
  single_instance="true"
  title="CONVERSATIONS"
- width="396">
-    <tab_container
-     follows="left|right|top|bottom"
-     height="390"
-     layout="topleft"
-     left="1"
-     name="im_box_tab_container"
-     tab_position="bottom"
-     tab_width="64"
-     tab_max_width = "134"
-     tab_height="16"
-     use_custom_icon_ctrl="true"
-     tab_icon_ctrl_pad="2"
-     halign="left"
-     use_ellipses="true"
-     top="0"
-     width="394">
-      <first_tab
-       tab_bottom_image_flash="Toolbar_Left_Flash"/>
-      <middle_tab
-       tab_bottom_image_flash="Toolbar_Middle_Flash"/>
-      <last_tab
-       tab_bottom_image_flash="Toolbar_Right_Flash"/>
-    </tab_container>
-    <icon
-     color="DefaultShadowLight"
-     enabled="false"
-     follows="left|right|bottom"
-     height="17"
-     image_name="tabarea.tga"
-     layout="bottomleft"
-     left="1"
-     name="im_box_tab_container_icon"
-     bottom="10"
-     width="394" />
+ width="680">
+    <panel
+         border="true"
+         follows="top|bottom|left"
+         layout="topleft"
+         name="conversations_list"
+         opaque="true"
+         top="0"
+         left="5"
+         height="425"
+         width="263">
+             <menu_button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left="5"
+                 name="sort_btn"
+                 top="5"
+                 width="31" />
+             <button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+             	 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="4"
+                 name="add_btn"
+                 tool_tip="Add button on the left panel"
+                 width="31">
+             </button>
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TabIcon_Open_Off"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left="228"
+                 name="slide_left_btn"
+                 width="31" />
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TabIcon_Close_Off"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_delta="0"
+                 name="slide_right_btn"
+                 width="31" />            
+     </panel>
+    <panel_container
+         follows="all"
+         layout="topleft"
+         name="im_box_tab_container"
+         opaque="true"
+         top="0"
+         left_pad="15"
+         height="430"
+         width="389"
+         min_width="290">         
+     </panel_container>
 </multi_floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index ca73883e53..3c3f4ad0e2 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- legacy_header_height="18"
  background_visible="true"
  default_tab_group="1"
  height="355"
@@ -15,28 +14,147 @@
  can_resize="true"
  min_width="250"
  min_height="190">
+    <view
+        follows="all"
+        layout="topleft"
+        name="contents_view"
+        top="0"
+        left="0"
+        height="355"
+        width="394"> 
+     <panel
+         follows="all"
+         layout="topleft"
+         name="toolbar_panel"
+         top="0"
+         left="0"
+         height="35"
+         width="394">         
+             <menu_button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left="5"
+                 name="view_options_btn"
+                 top="5"
+                 width="31" />
+             <button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="4"
+                 name="add_btn"
+                 width="31">
+                 <commit_callback
+                    function="Chats.add" />
+             </button>   
+             <button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="VoicePTT_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="4"
+                 name="call"
+                 width="31">
+                 <commit_callback
+                    function="Chats.add" />
+             </button>
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Icon_Close_Foreground"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left="283"
+                 name="close_btn"
+                 width="31" />
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TabIcon_Open_Off"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="5"
+                 name="slide_left_btn"
+                 width="31" />
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TabIcon_Close_Off"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_delta="0"
+                 name="slide_right_btn"
+                 width="31" />
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="tearoffbox.tga"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="5"
+                 name="tear_off_btn"
+                 width="31" />
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Icon_Dock_Foreground"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_delta="0"
+                 name="return_btn"
+                 width="31" />
+     </panel>
   <layout_stack
    animate="true" 
    default_tab_group="2"
   follows="all"
-  height="320"
+  height="310"
   width="394"
   layout="topleft"
   orientation="horizontal"
   name="im_panels"
   tab_group="1"
-  top="20"
+  top_pad="0"
   left="0">
     <layout_panel
       name="im_control_panel_holder"
       min_width="115"
       width="150" 
-      height="320" 
+      height="310" 
       auto_resize="false">
       <panel
         name="panel_im_control_panel"
         layout="topleft"
-        height="320"
+        height="310"
         width="150" 
         follows="all"/>
       </layout_panel>
@@ -46,39 +164,22 @@
        tab_group="2"
        top="0"
        height="200"
-	     width="254"
+	    width="254"
        user_resize="true">
-        <button
-          height="20"
-          follows="left|top"
-          top="0"
-          left="2"
-          image_overlay="TabIcon_Open_Off"
-          layout="topleft"
-          width="25"
-          name="slide_left_btn" />
-         <button
-          height="20"
-          follows="left|top"
-          top="0"
-          left="2"
-          image_overlay="TabIcon_Close_Off"
-          width="25"
-          name="slide_right_btn" />
         <chat_history
-	 font="SansSerifSmall"
-         follows="left|right|top|bottom"
-         height="150"
+	     font="SansSerifSmall"
+         follows="all"
+         height="170"
          name="chat_history"
          parse_highlights="true"
          parse_urls="true"
-        left="1"
+         left="1"
          width="249">
         </chat_history>
         <line_editor
          bottom="0"
          follows="left|right|bottom"
-	 font="SansSerifSmall"
+	     font="SansSerifSmall"
          height="20"
          label="To"
          layout="bottomleft"
@@ -88,4 +189,5 @@
         </line_editor>
     </layout_panel>
   </layout_stack>
+    </view>
 </floater>
-- 
cgit v1.2.3


From 905e56f8823e7513b35b9de4e5c6f8b0b6cca539 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 8 May 2012 23:30:34 +0300
Subject: CHUI-103 FIXED Implemented switching text view modes from pop-up menu

---
 indra/newview/app_settings/settings.xml            |  1 -
 indra/newview/llimfloater.cpp                      | 54 ++++++++++++++++++++--
 indra/newview/llimfloater.h                        |  6 ++-
 indra/newview/llnearbychat.cpp                     |  3 ++
 .../skins/default/xui/en/floater_im_session.xml    |  1 +
 .../default/xui/en/menu_im_session_showmodes.xml   | 50 ++++++++++++++++++++
 6 files changed, 110 insertions(+), 5 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index e6d0ed7dfa..d1fc8bdb7e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -24,7 +24,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-
 	<key>CrashHostUrl</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index df3521ecb0..d02db458b4 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -94,7 +94,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 		case IM_SESSION_GROUP_START:
 			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
 			break;
-		case IM_SESSION_INVITE:		
+		case IM_SESSION_INVITE:
 			if (gAgent.isInGroup(mSessionID))
 			{
 				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
@@ -104,7 +104,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
 			}
 			break;
-		default: break;
+		default:
+			break;
 		}
 	}
 	setOverlapsScreenChannel(true);
@@ -112,6 +113,52 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
 
 	setDocked(true);
+	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
+			boost::bind(&LLIMFloater::onIMSessionMenuItemClicked,  this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
+			boost::bind(&LLIMFloater::onIMCompactExpandedMenuItemCheck,	this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
+			boost::bind(&LLIMFloater::onIMShowModesMenuItemCheck,	this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
+			boost::bind(&LLIMFloater::onIMShowModesMenuItemEnable,	this, _2));
+}
+
+bool LLIMFloater::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
+
+	return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
+}
+
+bool LLIMFloater::onIMShowModesMenuItemCheck(const LLSD& userdata)
+{
+	return gSavedSettings.getBOOL(userdata.asString());
+}
+
+bool LLIMFloater::onIMShowModesMenuItemEnable(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
+	bool is_not_names = (item != "IMShowNamesForP2PConv");
+	bool is_p2p_chat = (mDialog == IM_SESSION_P2P_INVITE || mDialog == IM_NOTHING_SPECIAL);
+	return (plain_text && (is_not_names || is_p2p_chat));
+}
+
+void LLIMFloater::onIMSessionMenuItemClicked(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+
+	if (item == "compact_view" || item == "expanded_view")
+	{
+		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
+	}
+	else
+	{   bool prev_value = gSavedSettings.getBOOL(item);
+		gSavedSettings.setBOOL(item, !prev_value);
+	}
+
+	reloadMessages();
 }
 
 void LLIMFloater::onFocusLost()
@@ -635,11 +682,12 @@ void LLIMFloater::updateMessages()
 
 	if (messages.size())
 	{
+		bool is_p2p_chat = (mDialog == IM_SESSION_P2P_INVITE || mDialog == IM_NOTHING_SPECIAL);
 		LLSD chat_args;
 		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
 		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
 		chat_args["show_names_for_p2p_conv"] =
-				gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+				(!is_p2p_chat) || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
 
 		std::ostringstream message;
 		std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 95aa214ff6..ff4eaed0b9 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -87,7 +87,6 @@ public:
 
 	// called when docked floater's position has been set by chiclet
 	void setPositioned(bool b) { mPositioned = b; };
-
 	void onVisibilityChange(const LLSD& new_visibility);
 	void processIMTyping(const LLIMInfo* im_info, BOOL typing);
 	void processAgentListUpdates(const LLSD& body);
@@ -148,6 +147,11 @@ private:
 	static void*	createPanelGroupControl(void* userdata);
 	static void* 	createPanelAdHocControl(void* userdata);
 
+	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
+	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
+	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
+	void onIMSessionMenuItemClicked(const LLSD& userdata);
+
 	// Add the "User is typing..." indicator.
 	void addTypingIndicator(const LLIMInfo* im_info);
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a7303ad035..3a43750408 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -120,6 +120,9 @@ void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
 		tmp_chat.mFromName = chat.mFromName;
 		LLSD chat_args = args;
 		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
+		chat_args["show_time"] = true;
+		chat_args["show_names_for_p2p_conv"] = true;
+
 		mChatHistory->appendMessage(chat, chat_args);
 	}
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 3c3f4ad0e2..d90947a80a 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -31,6 +31,7 @@
          height="35"
          width="394">         
              <menu_button
+                 menu_filename="menu_im_session_showmodes.xml"
                  follows="top|left"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
diff --git a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000..483f24afd0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_modes"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+    <menu_item_check
+       label="Compact view"
+       name="compact_view">
+      <menu_item_check.on_click
+         function="IMSession.Menu.Action"
+         parameter="compact_view"/>
+      <menu_item_check.on_check
+         function="IMSession.Menu.CompactExpandedModes.CheckItem"
+         parameter="compact_view"/>
+    </menu_item_check>
+    <menu_item_check
+       label="Expanded view"
+       name="expanded_view">
+      <menu_item_check.on_click
+         function="IMSession.Menu.Action"
+         parameter="expanded_view"/>
+      <menu_item_check.on_check
+         function="IMSession.Menu.CompactExpandedModes.CheckItem"
+         parameter="expanded_view"/>
+    </menu_item_check>
+    <menu_item_separator layout="topleft" />
+    <menu_item_check name="IMShowTime" label="Show time">
+        <menu_item_check.on_click
+         function="IMSession.Menu.Action"
+         parameter="IMShowTime" />
+        <menu_item_check.on_check
+         function="IMSession.Menu.ShowModes.CheckItem"
+         parameter="IMShowTime" />
+        <menu_item_check.on_enable
+         function="IMSession.Menu.ShowModes.Enable"
+         parameter="IMShowTime" />
+    </menu_item_check>
+    <menu_item_check name="IMShowNamesForP2PConv" label="Show names in one-to-one conversations">
+        <menu_item_check.on_click
+         function="IMSession.Menu.Action"
+         parameter="IMShowNamesForP2PConv" />
+        <menu_item_check.on_check
+         function="IMSession.Menu.ShowModes.CheckItem"
+         parameter="IMShowNamesForP2PConv" />
+        <menu_item_check.on_enable
+         function="IMSession.Menu.ShowModes.Enable"
+         parameter="IMShowNamesForP2PConv" />
+         
+    </menu_item_check>
+</toggleable_menu>
-- 
cgit v1.2.3


From dfe6ce4be9b2b61a689e6cce41a9da91bd9a8b73 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 9 May 2012 21:41:46 +0300
Subject: Removed a recursive include declaration

---
 indra/newview/llspeakers.h | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index b9358cf37c..1c6f51e131 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -29,7 +29,6 @@
 
 #include "llevent.h"
 #include "lleventtimer.h"
-#include "llspeakers.h"
 #include "llvoicechannel.h"
 
 class LLSpeakerMgr;
-- 
cgit v1.2.3


From 7eaeb88bc37a747ff82fd37df84592f54c88cdbf Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 10 May 2012 20:40:15 +0300
Subject: CHUI-105 WIP Added expand/collapse behavior for Conversations floater
 messages pane.

---
 indra/newview/llimfloater.cpp                      | 70 ++++++++++++++--------
 indra/newview/llimfloater.h                        |  5 ++
 indra/newview/llimfloatercontainer.cpp             | 26 ++++++++
 indra/newview/llimfloatercontainer.h               |  4 ++
 .../skins/default/xui/en/floater_im_container.xml  | 44 +++++---------
 .../skins/default/xui/en/floater_im_session.xml    | 41 +++++--------
 6 files changed, 111 insertions(+), 79 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index d02db458b4..b2a5c4a64d 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -67,6 +67,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mDialog(IM_NOTHING_SPECIAL),
 	mChatHistory(NULL),
 	mInputEditor(NULL),
+	mExpandCollapseBtn(NULL),
+	mTearOffBtn(NULL),
 	mSavedTitle(),
 	mTypingStart(),
 	mShouldSendTypingState(false),
@@ -180,6 +182,17 @@ void LLIMFloater::onFocusReceived()
 	}
 }
 
+/*virtual*/
+void LLIMFloater::onOpen(const LLSD& key)
+{
+	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
+	if (host_floater)
+	{
+		// Show the messages pane when opening a floater hosted in the Conversations
+		host_floater->toggleMessagesPane(true);
+	}
+}
+
 // virtual
 void LLIMFloater::onClose(bool app_quitting)
 {
@@ -291,19 +304,14 @@ BOOL LLIMFloater::postBuild()
 	mControlPanel->setSessionId(mSessionID);
 	mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
 
-	LLButton* slide_left = getChild<LLButton>("slide_left_btn");
-	slide_left->setVisible(mControlPanel->getParent()->getVisible());
-	slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
-	LLButton* slide_right = getChild<LLButton>("slide_right_btn");
-	slide_right->setVisible(!mControlPanel->getParent()->getVisible());
-	slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
+	getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
 
-	LLButton* return_btn = getChild<LLButton>("return_btn");
-	return_btn->setCommitCallback(boost::bind(&LLFloater::onClickTearOff, this));
+	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+	mExpandCollapseBtn->setImageOverlay(getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon"));
+	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
 
-	LLButton* tear_off_btn = getChild<LLButton>("tear_off_btn");
-	tear_off_btn->setCommitCallback(boost::bind(&LLFloater::onClickTearOff, this));
+	mTearOffBtn = getChild<LLButton>("tear_off_btn");
+	mTearOffBtn->setCommitCallback(boost::bind(&LLFloater::onClickTearOff, this));
 
 	mInputEditor = getChild<LLLineEditor>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
@@ -427,12 +435,23 @@ void* LLIMFloater::createPanelAdHocControl(void* userdata)
 
 void LLIMFloater::onSlide()
 {
-	mControlPanel->getParent()->setVisible(!mControlPanel->getParent()->getVisible());
+	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
+	if (host_floater)
+	{
+		// Hide the messages pane if a floater is hosted in the Conversations
+		host_floater->toggleMessagesPane(false);
+	}
+	else ///< floater is torn off
+	{
+		bool expand = !mControlPanel->getParent()->getVisible();
 
-	gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getParent()->getVisible());
+		// Expand/collapse the IM control panel
+		mControlPanel->getParent()->setVisible(expand);
 
-	getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getParent()->getVisible());
-	getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getParent()->getVisible());
+		gSavedSettings.setBOOL("IMShowControlPanel", expand);
+
+		mExpandCollapseBtn->setImageOverlay(getString(expand ? "collapse_icon" : "expand_icon"));
+	}
 }
 
 //static
@@ -1253,14 +1272,16 @@ void	LLIMFloater::onClickCloseBtn()
 // virtual
 void LLIMFloater::updateTitleButtons()
 {
-	if (!mDragHandle)
+	// This gets called before LLIMFloater::postBuild() while some LLIMFloater members are NULL
+	if (   !mDragHandle
+		|| !mControlPanel
+		|| !mExpandCollapseBtn
+		|| !mTearOffBtn)
 	{
 		return;
 	}
 
-	LLMultiFloater* host_floater = getHost();
-
-	bool is_hosted = host_floater != NULL;
+	bool is_hosted = getHost() != NULL;
 	if (is_hosted) ///< floater is hosted
 	{
 		for (S32 i = 0; i < BUTTON_COUNT; i++)
@@ -1273,18 +1294,19 @@ void LLIMFloater::updateTitleButtons()
 			// Hide the standard header buttons in a docked IM floater.
 			mButtons[i]->setVisible(false);
 		}
+
+		mExpandCollapseBtn->setImageOverlay(getString("collapse_icon"));
 	}
 	else ///< floater is torn off
 	{
 		LLFloater::updateTitleButtons();
+
+		bool is_expanded = mControlPanel->getParent()->getVisible();
+		mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
 	}
 
 	// toggle floater's drag handle and title visibility
 	mDragHandle->setVisible(!is_hosted);
-	
-	LLButton* return_btn = getChild<LLButton>("return_btn");
-	return_btn->setVisible(!is_hosted);
 
-	LLButton* tear_off_btn = getChild<LLButton>("tear_off_btn");
-	tear_off_btn->setVisible(is_hosted);
+	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
 }
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index ff4eaed0b9..4f161449f7 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -33,6 +33,7 @@
 #include "lltransientdockablefloater.h"
 
 class LLAvatarName;
+class LLButton;
 class LLLineEditor;
 class LLPanelChatControlPanel;
 class LLChatHistory;
@@ -59,6 +60,7 @@ public:
 	/*virtual*/ void draw();
 
 	// LLFloater overrides
+	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
 
@@ -182,6 +184,9 @@ private:
 
 	bool mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
+
+	LLButton* mExpandCollapseBtn;
+	LLButton* mTearOffBtn;
 };
 
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 9b5055fb98..c8b8cb208d 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -40,6 +40,7 @@
 //
 LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 :	LLMultiFloater(seed)
+    ,mMessagesPaneWidth(0)
 {
 	mAutoResize = FALSE;
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
@@ -185,4 +186,29 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 	}
 }
 
+void LLIMFloaterContainer::toggleMessagesPane(bool expand)
+{
+	LLView* messages_pane = getChild<LLView>("im_box_tab_container");
+	bool is_expanded = messages_pane->getVisible();
+	if (is_expanded == expand)
+	{
+		return;
+	}
+
+	// Store the messages pane width before collapsing it.
+	if (!expand)
+	{
+		LLView* conversations_pane = getChild<LLView>("conversations_pane");
+		S32 horizontal_pad = messages_pane->getRect().mLeft - conversations_pane->getRect().mRight;
+		mMessagesPaneWidth = messages_pane->getRect().getWidth() + horizontal_pad;
+	}
+
+	// Show/hide the messages pane.
+	messages_pane->setVisible(expand);
+
+	S32 floater_width = getRect().getWidth();
+	floater_width += (expand ? mMessagesPaneWidth : -mMessagesPaneWidth);
+	reshape(floater_width, getRect().getHeight());
+}
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 93b91fe3cf..045f053b1c 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -60,12 +60,16 @@ public:
 
 	virtual void setMinimized(BOOL b);
 
+	void toggleMessagesPane(bool expand);
+
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
 	avatarID_panel_map_t mSessions;
 	boost::signals2::connection mNewMessageConnection;
 
 	void onNewMessageReceived(const LLSD& data);
+
+	S32	mMessagesPaneWidth;
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index d19b36971f..8a0181bae4 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <multi_floater
- can_close="false"  
+ can_close="true"  
  can_minimize="true"
  can_resize="true"
  height="430"
@@ -17,7 +17,7 @@
          border="true"
          follows="top|bottom|left"
          layout="topleft"
-         name="conversations_list"
+         name="conversations_pane"
          opaque="true"
          top="0"
          left="5"
@@ -29,7 +29,7 @@
                  image_hover_unselected="Toolbar_Middle_Over"
                  image_overlay="OptionsMenu_Off"
                  image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
+                 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left="5"
                  name="sort_btn"
@@ -39,7 +39,7 @@
                  follows="top|left"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-             	 image_overlay="AddItem_Off"
+                 image_overlay="AddItem_Off"
                  image_selected="Toolbar_Middle_Selected"
              	 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
@@ -55,34 +55,20 @@
                  image_hover_unselected="Toolbar_Middle_Over"
                  image_overlay="TabIcon_Open_Off"
                  image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
+                 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  top="5"
                  left="228"
-                 name="slide_left_btn"
+                 name="expand_collapse_btn"
                  width="31" />
-             <button
-                 follows="right|top"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="TabIcon_Close_Off"
-                 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left_delta="0"
-                 name="slide_right_btn"
-                 width="31" />            
-     </panel>
+    </panel>
     <panel_container
-         follows="all"
-         layout="topleft"
-         name="im_box_tab_container"
-         opaque="true"
-         top="0"
-         left_pad="15"
-         height="430"
-         width="389"
-         min_width="290">         
-     </panel_container>
+     follows="all"
+     height="430"
+     layout="topleft"
+     left_pad="15"
+     min_width="290"
+     name="im_box_tab_container"
+     top="0"
+     width="389"/>
 </multi_floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index d90947a80a..954f646bae 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -12,8 +12,21 @@
  visible="false"
  width="394"
  can_resize="true"
+ can_tear_off="false"
  min_width="250"
  min_height="190">
+    <floater.string
+     name="collapse_icon"
+     value="TabIcon_Open_Off"/>
+    <floater.string
+     name="expand_icon"
+     value="TabIcon_Close_Off"/>
+    <floater.string
+     name="tear_off_icon"
+     value="tearoffbox.tga"/>
+    <floater.string
+     name="return_icon"
+     value="Icon_Dock_Foreground"/>
     <view
         follows="all"
         layout="topleft"
@@ -23,7 +36,7 @@
         height="355"
         width="394"> 
      <panel
-         follows="all"
+         follows="left|top|right"
          layout="topleft"
          name="toolbar_panel"
          top="0"
@@ -95,19 +108,7 @@
                  layout="topleft"
                  top="5"
                  left_pad="5"
-                 name="slide_left_btn"
-                 width="31" />
-             <button
-                 follows="right|top"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="TabIcon_Close_Off"
-                 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left_delta="0"
-                 name="slide_right_btn"
+                 name="expand_collapse_btn"
                  width="31" />
              <button
                  follows="right|top"
@@ -121,18 +122,6 @@
                  left_pad="5"
                  name="tear_off_btn"
                  width="31" />
-             <button
-                 follows="right|top"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Icon_Dock_Foreground"
-                 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left_delta="0"
-                 name="return_btn"
-                 width="31" />
      </panel>
   <layout_stack
    animate="true" 
-- 
cgit v1.2.3


From df58153514f6b361c65efc5dd6d31d39f68603c0 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 14 May 2012 15:44:57 +0300
Subject: CHUI-113 WIP all voice controls is moved from a IM-control panel to
 the IM floater; IMControlPanel is removed; simplified voice button's listener
 behavior

---
 indra/newview/llchathistory.cpp                    |  14 +-
 indra/newview/llimfloater.cpp                      | 192 +++++++++++++-----
 indra/newview/llimfloater.h                        |  30 ++-
 indra/newview/llpanelimcontrolpanel.cpp            | 221 +--------------------
 indra/newview/llpanelimcontrolpanel.h              |  31 +--
 .../skins/default/xui/en/floater_im_session.xml    |  16 +-
 6 files changed, 202 insertions(+), 302 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index b70e98f22b..3214c95600 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -700,9 +700,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		return;
 	}
 
+	bool from_me = chat.mFromID == gAgent.getID();
 	mEditor->setPlainText(use_plain_text_chat_history);
 
-	if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty())
+	if (!mEditor->scrolledToEnd() && !from_me && !chat.mFromName.empty())
 	{
 		mUnreadChatSources.insert(chat.mFromName);
 		mMoreChatPanel->setVisible(TRUE);
@@ -777,6 +778,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 
 	bool prependNewLineState = mEditor->getText().size() != 0;
 
+	// show timestamps and names in the compact mode
 	if (use_plain_text_chat_history)
 	{
 		LLStyle::Params timestamp_style(style_params);
@@ -820,7 +822,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				LLStyle::Params link_params(style_params);
 				link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));
 
-				if (gAgentID == chat.mFromID)
+				if (from_me)
 				{	std::string localized_name;
 					bool is_localized = LLTrans::findString(localized_name, "AgentNameSubst");
 					mEditor->appendText((is_localized? localized_name:"(You)") + delimiter,
@@ -843,9 +845,9 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			}
 		}
 	}
-	else
+	else // showing timestamp and name in the expanded mode
 	{
-		prependNewLineState = 0;
+		prependNewLineState = false;
 		LLView* view = NULL;
 		LLInlineViewSegment::Params p;
 		p.force_newline = true;
@@ -953,7 +955,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 
 		//MESSAGE TEXT PROCESSING
 		//*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010)
-		if (use_plain_text_chat_history && gAgentID != chat.mFromID && chat.mFromID.notNull())
+		if (use_plain_text_chat_history && !from_me && chat.mFromID.notNull())
 		{
 			std::string slurl_about = SLURL_APP_AGENT + chat.mFromID.asString() + SLURL_ABOUT;
 			if (message.length() > slurl_about.length() && 
@@ -975,7 +977,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	mEditor->blockUndo();
 
 	// automatically scroll to end when receiving chat from myself
-	if (chat.mFromID == gAgentID)
+	if (from_me)
 	{
 		mEditor->setCursorAndScrollToEnd();
 	}
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index b2a5c4a64d..248e50eefa 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -51,14 +51,12 @@
 #include "llchathistory.h"
 #include "llnotifications.h"
 #include "llviewerwindow.h"
-#include "llvoicechannel.h"
 #include "lltransientfloatermgr.h"
 #include "llinventorymodel.h"
 #include "llrootview.h"
 #include "llspeakers.h"
 #include "llviewerchat.h"
 
-
 LLIMFloater::LLIMFloater(const LLUUID& session_id)
   : LLTransientDockableFloater(NULL, true, session_id),
 	mControlPanel(NULL),
@@ -85,11 +83,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 		mSessionInitialized = im_session->mSessionInitialized;
 		
 		mDialog = im_session->mType;
-		switch(mDialog){
-		case IM_NOTHING_SPECIAL:
-		case IM_SESSION_P2P_INVITE:
-			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
-			break;
+		switch (mDialog)
+		{
 		case IM_SESSION_CONFERENCE_START:
 			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
 			break;
@@ -106,6 +101,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
 			}
 			break;
+		case IM_NOTHING_SPECIAL:
+		case IM_SESSION_P2P_INVITE:
 		default:
 			break;
 		}
@@ -143,7 +140,8 @@ bool LLIMFloater::onIMShowModesMenuItemEnable(const LLSD& userdata)
 	std::string item = userdata.asString();
 	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
 	bool is_not_names = (item != "IMShowNamesForP2PConv");
-	bool is_p2p_chat = (mDialog == IM_SESSION_P2P_INVITE || mDialog == IM_NOTHING_SPECIAL);
+	LLIMModel::LLIMSession* im_session = LLIMModel::instance().findIMSession(mSessionID);
+	bool is_p2p_chat = im_session && im_session->isP2PSessionType();
 	return (plain_text && (is_not_names || is_p2p_chat));
 }
 
@@ -289,6 +287,12 @@ void LLIMFloater::sendMsg()
 
 LLIMFloater::~LLIMFloater()
 {
+	mVoiceChannelStateChangeConnection.disconnect();
+	if(LLVoiceClient::instanceExists())
+	{
+		LLVoiceClient::getInstance()->removeObserver(this);
+	}
+
 	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
 }
 
@@ -301,15 +305,27 @@ BOOL LLIMFloater::postBuild()
 		mOtherParticipantUUID = other_party_id;
 	}
 
-	mControlPanel->setSessionId(mSessionID);
-	mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
+	boundVoiceChannel();
 
 	getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
 
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
-	mExpandCollapseBtn->setImageOverlay(getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon"));
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
 
+	if (mControlPanel)
+	{
+		mControlPanel->setSessionId(mSessionID);
+		mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
+
+		mExpandCollapseBtn->setImageOverlay(
+				getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon"));
+	}
+	else
+	{
+		mExpandCollapseBtn->setEnabled(false);
+		getChild<LLLayoutPanel>("im_control_panel_holder")->setVisible(false);
+	}
+
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLFloater::onClickTearOff, this));
 
@@ -358,6 +374,10 @@ BOOL LLIMFloater::postBuild()
 		std::string session_name(LLIMModel::instance().getName(mSessionID));
 		updateSessionName(session_name, session_name);
 	}
+
+	childSetAction("voice_call_btn", boost::bind(&LLIMFloater::onCallButtonClicked, this));
+
+	LLVoiceClient::getInstance()->addObserver(this);
 	
 	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
 	//see LLFloaterIMPanel for how it is done (IB)
@@ -372,6 +392,89 @@ BOOL LLIMFloater::postBuild()
 	}
 }
 
+void LLIMFloater::boundVoiceChannel()
+{
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+	if(voice_channel)
+	{
+		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(
+				boost::bind(&LLIMFloater::onVoiceChannelStateChanged, this, _1, _2));
+
+		//call (either p2p, group or ad-hoc) can be already in started state
+		updateCallState(voice_channel->getState());
+	}
+}
+
+void LLIMFloater::updateCallState(LLVoiceChannel::EState state)
+{
+	bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
+	getChild<LLButton>("voice_call_btn")->setImageOverlay(
+			is_call_started? getString("call_btn_stop") : getString("call_btn_start"));
+    enableDisableCallBtn();
+
+}
+
+void LLIMFloater::enableDisableCallBtn()
+{
+	bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled()
+			&& LLVoiceClient::getInstance()->isVoiceWorking();
+
+	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+	if (!session)
+	{
+		getChildView("voice_call_btn")->setEnabled(false);
+		return;
+	}
+
+	bool session_initialized = session->mSessionInitialized;
+	bool callback_enabled = session->mCallBackEnabled;
+
+	BOOL enable_connect = session_initialized
+		&& voice_enabled
+		&& callback_enabled;
+	getChildView("voice_call_btn")->setEnabled(enable_connect);
+}
+
+
+void LLIMFloater::onCallButtonClicked()
+{
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+	if (voice_channel)
+	{
+		bool is_call_active = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+	    if (is_call_active)
+	    {
+		    gIMMgr->endCall(mSessionID);
+	    }
+	    else
+	    {
+		    gIMMgr->startCall(mSessionID);
+	    }
+	}
+}
+
+/*void LLIMFloater::onOpenVoiceControlsClicked()
+{
+	LLFloaterReg::showInstance("voice_controls");
+}*/
+
+void LLIMFloater::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+	{
+		return;
+	}
+
+	enableDisableCallBtn();
+}
+
+void LLIMFloater::onVoiceChannelStateChanged(
+		const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
+{
+	updateCallState(new_state);
+}
+
 void LLIMFloater::updateSessionName(const std::string& ui_title,
 									const std::string& ui_label)
 {
@@ -404,17 +507,6 @@ void LLIMFloater::draw()
 	LLTransientDockableFloater::draw();
 }
 
-
-// static
-void* LLIMFloater::createPanelIMControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*)userdata;
-	self->mControlPanel = new LLPanelIMControlPanel();
-	self->mControlPanel->setXMLFilename("panel_im_control_panel.xml");
-	return self->mControlPanel;
-}
-
-
 // static
 void* LLIMFloater::createPanelGroupControl(void* userdata)
 {
@@ -443,14 +535,17 @@ void LLIMFloater::onSlide()
 	}
 	else ///< floater is torn off
 	{
-		bool expand = !mControlPanel->getParent()->getVisible();
+		if (mControlPanel)
+		{
+			bool expand = !mControlPanel->getParent()->getVisible();
 
-		// Expand/collapse the IM control panel
-		mControlPanel->getParent()->setVisible(expand);
+			// Expand/collapse the IM control panel
+			mControlPanel->getParent()->setVisible(expand);
 
-		gSavedSettings.setBOOL("IMShowControlPanel", expand);
+			gSavedSettings.setBOOL("IMShowControlPanel", expand);
 
-		mExpandCollapseBtn->setImageOverlay(getString(expand ? "collapse_icon" : "expand_icon"));
+			mExpandCollapseBtn->setImageOverlay(getString(expand ? "collapse_icon" : "expand_icon"));
+		}
 	}
 }
 
@@ -659,15 +754,13 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	{
 		mSessionID = im_session_id;
 		setKey(im_session_id);
-		mControlPanel->setSessionId(im_session_id);
+		if (mControlPanel)
+		{
+			mControlPanel->setSessionId(im_session_id);
+		}
+		boundVoiceChannel();
 	}
 
-	// updating "Call" button from group control panel here to enable it without placing into draw() (EXT-4796)
-	if(gAgent.isInGroup(im_session_id))
-	{
-		mControlPanel->updateCallButton();
-	}
-	
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
 
 
@@ -910,13 +1003,6 @@ void LLIMFloater::processAgentListUpdates(const LLSD& body)
 	}
 }
 
-void LLIMFloater::updateChatHistoryStyle()
-{
-	mChatHistory->clear();
-	mLastMessageIndex = -1;
-	updateMessages();
-}
-
 void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue)
 {
 	LLFontGL* font = LLViewerChat::getChatFont();
@@ -927,11 +1013,10 @@ void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue)
 		LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
 		if (floater)
 		{
-			floater->updateChatHistoryStyle();
+			floater->reloadMessages();
 			floater->mInputEditor->setFont(font);
 		}
 	}
-
 }
 
 void LLIMFloater::processSessionUpdate(const LLSD& session_update)
@@ -1152,7 +1237,6 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
 			}
 		}
-
 	}
 }
 
@@ -1274,7 +1358,7 @@ void LLIMFloater::updateTitleButtons()
 {
 	// This gets called before LLIMFloater::postBuild() while some LLIMFloater members are NULL
 	if (   !mDragHandle
-		|| !mControlPanel
+		//|| !mControlPanel
 		|| !mExpandCollapseBtn
 		|| !mTearOffBtn)
 	{
@@ -1301,8 +1385,22 @@ void LLIMFloater::updateTitleButtons()
 	{
 		LLFloater::updateTitleButtons();
 
-		bool is_expanded = mControlPanel->getParent()->getVisible();
-		mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+		if (mControlPanel)
+		{
+			bool is_expanded = mControlPanel->getParent()->getVisible();
+			mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+		}
+	}
+
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
+	if (session)
+	{
+		mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType());
+	}
+	else
+	{
+		llwarns << "Empty session." << llendl;
+		return;
 	}
 
 	// toggle floater's drag handle and title visibility
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 4f161449f7..40b3fff8f4 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -31,6 +31,8 @@
 #include "lllogchat.h"
 #include "lltooldraganddrop.h"
 #include "lltransientdockablefloater.h"
+#include "llvoicechannel.h"
+#include "llvoiceclient.h"
 
 class LLAvatarName;
 class LLButton;
@@ -44,14 +46,16 @@ class LLInventoryCategory;
  * Individual IM window that appears at the bottom of the screen,
  * optionally "docked" to the bottom tray.
  */
-class LLIMFloater : public LLTransientDockableFloater
+class LLIMFloater
+	: public LLTransientDockableFloater
+	, public LLVoiceClientStatusObserver
 {
 	LOG_CLASS(LLIMFloater);
 public:
 	LLIMFloater(const LLUUID& session_id);
 
 	virtual ~LLIMFloater();
-	
+
 	// LLView overrides
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void setVisible(BOOL visible);
@@ -90,11 +94,20 @@ public:
 	// called when docked floater's position has been set by chiclet
 	void setPositioned(bool b) { mPositioned = b; };
 	void onVisibilityChange(const LLSD& new_visibility);
+
+	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
+	// button when voice is available
+	void onChange(EStatusType status, const std::string &channelURI,
+			bool proximal);
+
+	virtual void onVoiceChannelStateChanged(
+			const LLVoiceChannel::EState& old_state,
+			const LLVoiceChannel::EState& new_state);
+
 	void processIMTyping(const LLIMInfo* im_info, BOOL typing);
 	void processAgentListUpdates(const LLSD& body);
 	void processSessionUpdate(const LLSD& session_update);
 
-	void updateChatHistoryStyle();
 	static void processChatHistoryStyleUpdate(const LLSD& newvalue);
 
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
@@ -153,6 +166,13 @@ private:
 	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
 	void onIMSessionMenuItemClicked(const LLSD& userdata);
+	void onCallButtonClicked();
+
+	void boundVoiceChannel();
+	void enableDisableCallBtn();
+
+	// refresh a visual state of the Call button
+	void updateCallState(LLVoiceChannel::EState state);
 
 	// Add the "User is typing..." indicator.
 	void addTypingIndicator(const LLIMInfo* im_info);
@@ -185,9 +205,11 @@ private:
 	bool mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
 
+	// connection to voice channel state change signal
+	boost::signals2::connection mVoiceChannelStateChangeConnection;
+
 	LLButton* mExpandCollapseBtn;
 	LLButton* mTearOffBtn;
 };
 
-
 #endif  // LL_IMFLOATER_H
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index eda0749cdb..f0fc15b4d8 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -1,31 +1,30 @@
-/** 
+/**
  * @file llpanelavatar.cpp
  * @brief LLPanelAvatar and related class implementations
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
 
 #include "llviewerprecompiledheaders.h"
-
 #include "llfloaterreg.h"
 
 #include "llpanelimcontrolpanel.h"
@@ -39,92 +38,15 @@
 #include "llavatarlist.h"
 #include "llparticipantlist.h"
 #include "llimview.h"
-#include "llvoicechannel.h"
 #include "llspeakers.h"
 #include "lltrans.h"
 
-void LLPanelChatControlPanel::onCallButtonClicked()
-{
-	gIMMgr->startCall(mSessionId);
-}
-
-void LLPanelChatControlPanel::onEndCallButtonClicked()
-{
-	gIMMgr->endCall(mSessionId);
-}
-
-void LLPanelChatControlPanel::onOpenVoiceControlsClicked()
-{
-	LLFloaterReg::showInstance("voice_controls");
-}
-
-void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal)
-{
-	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
-	{
-		return;
-	}
-
-	updateCallButton();
-}
-
-void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
-	updateButtons(new_state);
-}
-
-void LLPanelChatControlPanel::updateCallButton()
-{
-	// hide/show call button
-	bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
-
-	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
-	
-	if (!session) 
-	{
-		getChildView("call_btn")->setEnabled(false);
-		return;
-	}
-
-	bool session_initialized = session->mSessionInitialized;
-	bool callback_enabled = session->mCallBackEnabled;
-
-	BOOL enable_connect = session_initialized
-		&& voice_enabled
-		&& callback_enabled;
-	getChildView("call_btn")->setEnabled(enable_connect);
-}
-
-void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state)
-{
-	bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
-	getChildView("end_call_btn_panel")->setVisible( is_call_started);
-	getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel"));
-	getChildView("call_btn_panel")->setVisible( ! is_call_started);
-	
-	getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED);
-	
-	updateCallButton();
-	
-}
-
 LLPanelChatControlPanel::~LLPanelChatControlPanel()
 {
-	mVoiceChannelStateChangeConnection.disconnect();
-	if(LLVoiceClient::instanceExists())
-	{
-		LLVoiceClient::getInstance()->removeObserver(this);
-	}
 }
 
 BOOL LLPanelChatControlPanel::postBuild()
 {
-	childSetAction("call_btn", boost::bind(&LLPanelChatControlPanel::onCallButtonClicked, this));
-	childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));
-	childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this));
-
-	LLVoiceClient::getInstance()->addObserver(this);
-
 	return TRUE;
 }
 
@@ -132,14 +54,6 @@ void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
 {
 	//Method is called twice for AdHoc and Group chat. Second time when server init reply received
 	mSessionId = session_id;
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionId);
-	if(voice_channel)
-	{
-		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2));
-		
-		//call (either p2p, group or ad-hoc) can be already in started state
-		updateButtons(voice_channel->getState());
-	}
 }
 
 LLPanelIMControlPanel::LLPanelIMControlPanel()
@@ -148,29 +62,27 @@ LLPanelIMControlPanel::LLPanelIMControlPanel()
 
 LLPanelIMControlPanel::~LLPanelIMControlPanel()
 {
-	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
+//	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
 }
 
 BOOL LLPanelIMControlPanel::postBuild()
 {
-	childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this));
+/*	childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this));
 	childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this));
 
 	childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));
 	childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this));
 	childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this));
 
-	childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this));
 	childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this));
 	childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this));
-	
-	getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2));
 
 	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));
 
 	setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this));
-	
+*/
 	return LLPanelChatControlPanel::postBuild();
+
 }
 
 void LLPanelIMControlPanel::draw()
@@ -180,56 +92,14 @@ void LLPanelIMControlPanel::draw()
 	getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted);
 	getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted);
 
-	if (getChildView("volume_ctrl_panel")->getVisible())
-	{
-
-		bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat);
-
-		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
-		mute_btn->setValue( is_muted_voice );
-
-		LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
-		volume_slider->setEnabled( !is_muted_voice );
-
-		F32 volume;
-
-		if (is_muted_voice)
-		{
-			// it's clearer to display their volume as zero
-			volume = 0.f;
-		}
-		else
-		{
-			// actual volume
-			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
-		}
-		volume_slider->setValue( (F64)volume );
-	}
 
 	LLPanelChatControlPanel::draw();
 }
 
-void LLPanelIMControlPanel::onClickMuteVolume()
-{
-	// By convention, we only display and toggle voice mutes, not all mutes
-	LLMuteList* mute_list = LLMuteList::getInstance();
-	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
-
-	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-	if (!is_muted)
-	{
-		mute_list->add(mute, LLMute::flagVoiceChat);
-	}
-	else
-	{
-		mute_list->remove(mute, LLMute::flagVoiceChat);
-	}
-}
-
 void LLPanelIMControlPanel::onClickBlock()
 {
 	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-	
+
 	LLMuteList::getInstance()->add(mute);
 }
 
@@ -240,12 +110,6 @@ void LLPanelIMControlPanel::onClickUnblock()
 	LLMuteList::getInstance()->remove(mute);
 }
 
-void LLPanelIMControlPanel::onVolumeChange(const LLSD& data)
-{
-	F32 volume = (F32)data.asReal();
-	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
-}
-
 void LLPanelIMControlPanel::onTeleportButtonClicked()
 {
 	LLAvatarActions::offerTeleport(mAvatarID);
@@ -281,62 +145,6 @@ void LLPanelIMControlPanel::onFocusReceived()
 	}
 }
 
-void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)
-{
-	LLPanelChatControlPanel::setSessionId(session_id);
-
-	LLIMModel& im_model = LLIMModel::instance();
-
-	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
-	mAvatarID = im_model.getOtherParticipantID(session_id);
-	LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);
-
-	// Disable "Add friend" button for friends.
-	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID));
-	
-	// Disable "Teleport" button if friend is offline
-	if(LLAvatarActions::isFriend(mAvatarID))
-	{
-		getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID));
-	}
-
-	getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(mAvatarID);
-
-	// Disable most profile buttons if the participant is
-	// not really an SL avatar (e.g., an Avaline caller).
-	LLIMModel::LLIMSession* im_session =
-		im_model.findIMSession(session_id);
-	if( im_session && !im_session->mOtherParticipantIsAvatar )
-	{
-		getChildView("view_profile_btn")->setEnabled(FALSE);
-		getChildView("add_friend_btn")->setEnabled(FALSE);
-
-		getChildView("share_btn")->setEnabled(FALSE);
-		getChildView("teleport_btn")->setEnabled(FALSE);
-		getChildView("pay_btn")->setEnabled(FALSE);
-
-        getChild<LLTextBox>("avatar_name")->setValue(im_session->mName);
-        getChild<LLTextBox>("avatar_name")->setToolTip(im_session->mName);
-	}
-	else
-	{
-		// If the participant is an avatar, fetch the currect name
-		gCacheName->get(mAvatarID, false,
-			boost::bind(&LLPanelIMControlPanel::onNameCache, this, _1, _2, _3));
-	}
-}
-
-//virtual
-void LLPanelIMControlPanel::changed(U32 mask)
-{
-	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID));
-	
-	// Disable "Teleport" button if friend is offline
-	if(LLAvatarActions::isFriend(mAvatarID))
-	{
-		getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID));
-	}
-}
 
 void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group)
 {
@@ -398,19 +206,13 @@ void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata)
 
 }
 
-void LLPanelGroupControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
-	LLPanelChatControlPanel::onVoiceChannelStateChanged(old_state, new_state);
-	mParticipantList->setSpeakingIndicatorsVisible(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
-}
-
 void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
 {
 	LLPanelChatControlPanel::setSessionId(session_id);
 
 	mGroupID = session_id;
 
-	// for group and Ad-hoc chat we need to include agent into list 
+	// for group and Ad-hoc chat we need to include agent into list
 	if(!mParticipantList)
 	{
 		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
@@ -428,4 +230,3 @@ BOOL LLPanelAdHocControlPanel::postBuild()
 	//We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat
 	return LLPanelChatControlPanel::postBuild();
 }
-
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index bba847b5d4..3466da33a1 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -28,14 +28,12 @@
 #define LL_LLPANELIMCONTROLPANEL_H
 
 #include "llpanel.h"
-#include "llvoicechannel.h"
 #include "llcallingcard.h"
 
 class LLParticipantList;
 
-class LLPanelChatControlPanel 
+class LLPanelChatControlPanel
 	: public LLPanel
-	, public LLVoiceClientStatusObserver
 {
 public:
 	LLPanelChatControlPanel() :
@@ -44,21 +42,6 @@ public:
 
 	virtual BOOL postBuild();
 
-	void onCallButtonClicked();
-	void onEndCallButtonClicked();
-	void onOpenVoiceControlsClicked();
-
-	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
-	// button when voice is available
-	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
-
-	virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
-
-	void updateButtons(LLVoiceChannel::EState state);
-	
-	// Enables/disables call button depending on voice availability
-	void updateCallButton();
-
 	virtual void setSessionId(const LLUUID& session_id);
 	const LLUUID& getSessionId() { return mSessionId; }
 
@@ -70,7 +53,7 @@ private:
 };
 
 
-class LLPanelIMControlPanel : public LLPanelChatControlPanel, LLFriendObserver
+class LLPanelIMControlPanel : public LLPanelChatControlPanel
 {
 public:
 	LLPanelIMControlPanel();
@@ -78,10 +61,7 @@ public:
 
 	BOOL postBuild();
 
-	void setSessionId(const LLUUID& session_id);
-
-	// LLFriendObserver trigger
-	virtual void changed(U32 mask);
+	//void setSessionId(const LLUUID& session_id);
 
 protected:
 	void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
@@ -93,13 +73,9 @@ private:
 	void onTeleportButtonClicked();
 	void onPayButtonClicked();
 	void onFocusReceived();
-
-	void onClickMuteVolume();
 	void onClickBlock();
 	void onClickUnblock();
 	/*virtual*/ void draw();
-	void onVolumeChange(const LLSD& data);
-
 	LLUUID mAvatarID;
 };
 
@@ -123,7 +99,6 @@ protected:
 private:
 	void onGroupInfoButtonClicked();
 	void onSortMenuItemClicked(const LLSD& userdata);
-	/*virtual*/ void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
 };
 
 class LLPanelAdHocControlPanel : public LLPanelGroupControlPanel
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 954f646bae..a332bb5b12 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -15,6 +15,8 @@
  can_tear_off="false"
  min_width="250"
  min_height="190">
+    <floater.string name="call_btn_start">VoicePTT_Off</floater.string>
+    <floater.string name="call_btn_stop">VoicePTT_On</floater.string>
     <floater.string
      name="collapse_icon"
      value="TabIcon_Open_Off"/>
@@ -47,10 +49,10 @@
                  menu_filename="menu_im_session_showmodes.xml"
                  follows="top|left"
                  height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_hover_unselected="Toolbar_Left_Over"
                  image_overlay="OptionsMenu_Off"
-                 image_selected="Toolbar_Middle_Selected"
-                 image_unselected="Toolbar_Middle_Off"
+                 image_selected="Toolbar_Left_Selected"
+                 image_unselected="Toolbar_Left_Off"
                  layout="topleft"
                  left="5"
                  name="view_options_btn"
@@ -74,14 +76,14 @@
              <button
                  follows="top|left"
                  height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_hover_unselected="Toolbar_Right_Over"
                  image_overlay="VoicePTT_Off"
-                 image_selected="Toolbar_Middle_Selected"
-                 image_unselected="Toolbar_Middle_Off"
+                 image_selected="Toolbar_Right_Selected"
+                 image_unselected="Toolbar_Right_Off"
                  layout="topleft"
                  top="5"
                  left_pad="4"
-                 name="call"
+                 name="voice_call_btn"
                  width="31">
                  <commit_callback
                     function="Chats.add" />
-- 
cgit v1.2.3


From 6cd68b321147136b2ad79fdbfeafdd2ffc39f1a3 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 14 May 2012 16:03:39 +0300
Subject: Formatting fixes

---
 indra/newview/llimfloater.cpp | 299 ++++++++++++++++++++++--------------------
 indra/newview/llimfloater.h   |  35 +++--
 2 files changed, 171 insertions(+), 163 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 248e50eefa..cb489627fb 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -115,11 +115,11 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
 			boost::bind(&LLIMFloater::onIMSessionMenuItemClicked,  this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
-			boost::bind(&LLIMFloater::onIMCompactExpandedMenuItemCheck,	this, _2));
+			boost::bind(&LLIMFloater::onIMCompactExpandedMenuItemCheck, this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
-			boost::bind(&LLIMFloater::onIMShowModesMenuItemCheck,	this, _2));
+			boost::bind(&LLIMFloater::onIMShowModesMenuItemCheck,   this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
-			boost::bind(&LLIMFloater::onIMShowModesMenuItemEnable,	this, _2));
+			boost::bind(&LLIMFloater::onIMShowModesMenuItemEnable,  this, _2));
 }
 
 bool LLIMFloater::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
@@ -154,7 +154,8 @@ void LLIMFloater::onIMSessionMenuItemClicked(const LLSD& userdata)
 		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
 	}
 	else
-	{   bool prev_value = gSavedSettings.getBOOL(item);
+	{
+		bool prev_value = gSavedSettings.getBOOL(item);
 		gSavedSettings.setBOOL(item, !prev_value);
 	}
 
@@ -164,7 +165,7 @@ void LLIMFloater::onIMSessionMenuItemClicked(const LLSD& userdata)
 void LLIMFloater::onFocusLost()
 {
 	LLIMModel::getInstance()->resetActiveSessionID();
-	
+
 	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, false);
 }
 
@@ -205,8 +206,8 @@ void LLIMFloater::onClose(bool app_quitting)
 }
 
 /* static */
-void LLIMFloater::newIMCallback(const LLSD& data){
-	
+void LLIMFloater::newIMCallback(const LLSD& data)
+{
 	if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull())
 	{
 		LLUUID session_id = data["session_id"].asUUID();
@@ -214,7 +215,7 @@ void LLIMFloater::newIMCallback(const LLSD& data){
 		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
 		if (floater == NULL) return;
 
-        // update if visible, otherwise will be updated when opened
+		// update if visible, otherwise will be updated when opened
 		if (floater->getVisible())
 		{
 			floater->updateMessages();
@@ -229,7 +230,7 @@ void LLIMFloater::onVisibilityChange(const LLSD& new_visibility)
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
 
 	if (visible && voice_channel &&
-		voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
+			voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
 	{
 		LLFloaterReg::showInstance("voice_call", mSessionID);
 	}
@@ -248,9 +249,9 @@ void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
 
 void LLIMFloater::sendMsg()
 {
-	if (!gAgent.isGodlike() 
-		&& (mDialog == IM_NOTHING_SPECIAL)
-		&& mOtherParticipantUUID.isNull())
+	if (!gAgent.isGodlike()
+			&& (mDialog == IM_NOTHING_SPECIAL)
+			&& mOtherParticipantUUID.isNull())
 	{
 		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
 		return;
@@ -259,16 +260,15 @@ void LLIMFloater::sendMsg()
 	if (mInputEditor)
 	{
 		LLWString text = mInputEditor->getConvertedText();
-		if(!text.empty())
+		if (!text.empty())
 		{
 			// Truncate and convert to UTF8 for transport
 			std::string utf8_text = wstring_to_utf8str(text);
 			utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
-			
+
 			if (mSessionInitialized)
 			{
-				LLIMModel::sendMessage(utf8_text, mSessionID,
-					mOtherParticipantUUID,mDialog);
+				LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
 			}
 			else
 			{
@@ -283,8 +283,6 @@ void LLIMFloater::sendMsg()
 	}
 }
 
-
-
 LLIMFloater::~LLIMFloater()
 {
 	mVoiceChannelStateChangeConnection.disconnect();
@@ -299,7 +297,8 @@ LLIMFloater::~LLIMFloater()
 //virtual
 BOOL LLIMFloater::postBuild()
 {
-	const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+	const LLUUID& other_party_id =
+			LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
 	if (other_party_id.notNull())
 	{
 		mOtherParticipantUUID = other_party_id;
@@ -335,8 +334,8 @@ BOOL LLIMFloater::postBuild()
 	mInputEditor->setEnableLineHistory(TRUE);
 
 	LLFontGL* font = LLViewerChat::getChatFont();
-	mInputEditor->setFont(font);	
-	
+	mInputEditor->setFont(font);
+
 	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
 	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
 	mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
@@ -346,7 +345,7 @@ BOOL LLIMFloater::postBuild()
 	mInputEditor->setPassDelete( TRUE );
 
 	childSetCommitCallback("chat_editor", onSendMsg, this);
-	
+
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
 	setDocked(true);
@@ -355,19 +354,19 @@ BOOL LLIMFloater::postBuild()
 
 	// Disable input editor if session cannot accept text
 	LLIMModel::LLIMSession* im_session =
-		LLIMModel::instance().findIMSession(mSessionID);
-	if( im_session && !im_session->mTextIMPossible )
+			LLIMModel::instance().findIMSession(mSessionID);
+	if ( im_session && !im_session->mTextIMPossible )
 	{
 		mInputEditor->setEnabled(FALSE);
 		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
 	}
 
-	if ( im_session && im_session->isP2PSessionType())
+	if (im_session && im_session->isP2PSessionType())
 	{
 		// look up display name for window title
 		LLAvatarNameCache::get(im_session->mOtherParticipantID,
-							   boost::bind(&LLIMFloater::onAvatarNameCache,
-										   this, _1, _2));
+				boost::bind(&LLIMFloater::onAvatarNameCache,
+						this, _1, _2));
 	}
 	else
 	{
@@ -382,7 +381,7 @@ BOOL LLIMFloater::postBuild()
 	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
 	//see LLFloaterIMPanel for how it is done (IB)
 
-	if(isChatMultiTab())
+	if (isChatMultiTab())
 	{
 		return LLFloater::postBuild();
 	}
@@ -476,14 +475,14 @@ void LLIMFloater::onVoiceChannelStateChanged(
 }
 
 void LLIMFloater::updateSessionName(const std::string& ui_title,
-									const std::string& ui_label)
+		const std::string& ui_label)
 {
 	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + ui_label);
-	setTitle(ui_title);	
+	setTitle(ui_title);
 }
 
 void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
-									const LLAvatarName& av_name)
+		const LLAvatarName& av_name)
 {
 	// Use display name only for labels, as the extended name will be in the
 	// floater title
@@ -498,7 +497,7 @@ void LLIMFloater::draw()
 	if ( mMeTyping )
 	{
 		// Time out if user hasn't typed for a while.
-		if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS )
+		if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS)
 		{
 			setTyping(false);
 		}
@@ -510,7 +509,7 @@ void LLIMFloater::draw()
 // static
 void* LLIMFloater::createPanelGroupControl(void* userdata)
 {
-	LLIMFloater *self = (LLIMFloater*)userdata;
+	LLIMFloater *self = (LLIMFloater*) userdata;
 	self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID);
 	self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
 	return self->mControlPanel;
@@ -519,7 +518,7 @@ void* LLIMFloater::createPanelGroupControl(void* userdata)
 // static
 void* LLIMFloater::createPanelAdHocControl(void* userdata)
 {
-	LLIMFloater *self = (LLIMFloater*)userdata;
+	LLIMFloater *self = (LLIMFloater*) userdata;
 	self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID);
 	self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml");
 	return self->mControlPanel;
@@ -554,14 +553,15 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 {
 	closeHiddenIMToasts();
 
-	if (!gIMMgr->hasSession(session_id)) return NULL;
+	if (!gIMMgr->hasSession(session_id))
+		return NULL;
 
-	if(!isChatMultiTab())
+	if (!isChatMultiTab())
 	{
 		//hide all
 		LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
 		for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
-			 iter != inst_list.end(); ++iter)
+				iter != inst_list.end(); ++iter)
 		{
 			LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
 			if (floater && floater->isDocked())
@@ -574,9 +574,10 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 	bool exist = findInstance(session_id);
 
 	LLIMFloater* floater = getInstance(session_id);
-	if (!floater) return NULL;
+	if (!floater)
+		return NULL;
 
-	if(isChatMultiTab())
+	if (isChatMultiTab())
 	{
 		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
 
@@ -586,7 +587,7 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 			//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
 			// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
 			LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
-			
+
 			if (floater_container)
 			{
 				floater_container->addFloater(floater, TRUE, i_pt);
@@ -629,16 +630,16 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 {
 	// update notification channel state
 	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-		(LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-	
-	if(!isChatMultiTab())
+	    (LLNotificationsUI::LLChannelManager::getInstance()->
+	    		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+	if (!isChatMultiTab())
 	{
 		LLTransientDockableFloater::setDocked(docked, pop_on_undock);
 	}
 
 	// update notification channel state
-	if(channel)
+	if (channel)
 	{
 		channel->updateShowToastsState();
 		channel->redrawToasts();
@@ -648,12 +649,12 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 void LLIMFloater::setVisible(BOOL visible)
 {
 	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-		(LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+	    (LLNotificationsUI::LLChannelManager::getInstance()->
+	    		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
 	LLTransientDockableFloater::setVisible(visible);
 
 	// update notification channel state
-	if(channel)
+	if (channel)
 	{
 		channel->updateShowToastsState();
 		channel->redrawToasts();
@@ -674,10 +675,10 @@ void LLIMFloater::setVisible(BOOL visible)
 		}
 	}
 
-	if(!visible)
+	if (!visible)
 	{
 		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
-		if(chiclet)
+		if (chiclet)
 		{
 			chiclet->setToggleState(false);
 		}
@@ -686,13 +687,14 @@ void LLIMFloater::setVisible(BOOL visible)
 
 BOOL LLIMFloater::getVisible()
 {
-	if(isChatMultiTab())
+	if (isChatMultiTab())
 	{
-		LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance();
-		
+		LLIMFloaterContainer* im_container =
+				LLIMFloaterContainer::getInstance();
+
 		// Treat inactive floater as invisible.
 		bool is_active = im_container->getActiveFloater() == this;
-	
+
 		//torn off floater is always inactive
 		if (!is_active && getHost() != im_container)
 		{
@@ -700,7 +702,8 @@ BOOL LLIMFloater::getVisible()
 		}
 
 		// getVisible() returns TRUE when Tabbed IM window is minimized.
-		return is_active && !im_container->isMinimized() && im_container->getVisible();
+		return is_active && !im_container->isMinimized()
+				&& im_container->getVisible();
 	}
 	else
 	{
@@ -711,9 +714,10 @@ BOOL LLIMFloater::getVisible()
 //static
 bool LLIMFloater::toggle(const LLUUID& session_id)
 {
-	if(!isChatMultiTab())
+	if (!isChatMultiTab())
 	{
-		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>(
+				"impanel", session_id);
 		if (floater && floater->getVisible() && floater->hasFocus())
 		{
 			// clicking on chiclet to close floater just hides it to maintain existing
@@ -721,7 +725,7 @@ bool LLIMFloater::toggle(const LLUUID& session_id)
 			floater->setVisible(false);
 			return false;
 		}
-		else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
+		else if (floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
 		{
 			floater->setVisible(TRUE);
 			floater->setFocus(TRUE);
@@ -763,16 +767,15 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
 
-
 	//need to send delayed messaged collected while waiting for session initialization
-	if (!mQueuedMsgsForInit.size()) return;
+	if (!mQueuedMsgsForInit.size())
+		return;
 	LLSD::array_iterator iter;
-	for ( iter = mQueuedMsgsForInit.beginArray();
-		iter != mQueuedMsgsForInit.endArray();
-		++iter)
+	for (iter = mQueuedMsgsForInit.beginArray();
+			iter != mQueuedMsgsForInit.endArray(); ++iter)
 	{
 		LLIMModel::sendMessage(iter->asString(), mSessionID,
-			mOtherParticipantUUID, mDialog);
+				mOtherParticipantUUID, mDialog);
 	}
 }
 
@@ -785,11 +788,11 @@ void LLIMFloater::updateMessages()
 	// we shouldn't reset unread message counters if IM floater doesn't have focus
 	if (hasFocus())
 	{
-		LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex+1);
+		LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex + 1);
 	}
 	else
 	{
-		LLIMModel::instance().getMessagesSilently(mSessionID, messages, mLastMessageIndex+1);
+		LLIMModel::instance().getMessagesSilently(mSessionID, messages, mLastMessageIndex + 1);
 	}
 
 	if (messages.size())
@@ -798,8 +801,7 @@ void LLIMFloater::updateMessages()
 		LLSD chat_args;
 		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
 		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
-		chat_args["show_names_for_p2p_conv"] =
-				(!is_p2p_chat) || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+		chat_args["show_names_for_p2p_conv"] = (!is_p2p_chat) || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
 
 		std::ostringstream message;
 		std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
@@ -830,8 +832,8 @@ void LLIMFloater::updateMessages()
 				{
 					// remove embedded notification from channel
 					LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-							(LLNotificationsUI::LLChannelManager::getInstance()->
-																findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+					    (LLNotificationsUI::LLChannelManager::getInstance()->
+					    		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
 					if (getVisible())
 					{
 						// toast will be automatically closed since it is not storable toast
@@ -849,7 +851,7 @@ void LLIMFloater::updateMessages()
 			{
 				chat.mText = message;
 			}
-			
+
 			mChatHistory->appendMessage(chat, chat_args);
 			mLastMessageIndex = msg["index"].asInteger();
 
@@ -857,16 +859,16 @@ void LLIMFloater::updateMessages()
 			if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
 			{
 				if (++iter == iter_end)
-				{
-					break;
-				}
-				else
-				{
-					mLastMessageIndex++;
-				}
-			}
-		}
-	}
+			    {
+				    break;
+			    }
+			    else
+			    {
+				    mLastMessageIndex++;
+			    }
+		    }
+	    }
+    }
 }
 
 void LLIMFloater::reloadMessages()
@@ -877,15 +879,15 @@ void LLIMFloater::reloadMessages()
 }
 
 // static
-void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
+void LLIMFloater::onInputEditorFocusReceived(LLFocusableElement* caller, void* userdata)
 {
-	LLIMFloater* self= (LLIMFloater*) userdata;
+	LLIMFloater* self = (LLIMFloater*) userdata;
 
 	// Allow enabling the LLIMFloater input editor only if session can accept text
 	LLIMModel::LLIMSession* im_session =
-		LLIMModel::instance().findIMSession(self->mSessionID);
+			LLIMModel::instance().findIMSession(self->mSessionID);
 	//TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
-	if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
+	if (im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
 	{
 		//in disconnected state IM input editor should be disabled
 		self->mInputEditor->setEnabled(!gDisconnected);
@@ -902,7 +904,7 @@ void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userd
 // static
 void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
 {
-	LLIMFloater* self = (LLIMFloater*)userdata;
+	LLIMFloater* self = (LLIMFloater*) userdata;
 	std::string text = self->mInputEditor->getText();
 	if (!text.empty())
 	{
@@ -917,13 +919,13 @@ void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
 
 void LLIMFloater::setTyping(bool typing)
 {
-	if ( typing )
+	if (typing)
 	{
 		// Started or proceeded typing, reset the typing timeout timer
 		mTypingTimeoutTimer.reset();
 	}
 
-	if ( mMeTyping != typing )
+	if (mMeTyping != typing)
 	{
 		// Typing state is changed
 		mMeTyping = typing;
@@ -935,21 +937,23 @@ void LLIMFloater::setTyping(bool typing)
 
 	// Don't want to send typing indicators to multiple people, potentially too
 	// much network traffic. Only send in person-to-person IMs.
-	if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
+	if (mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL)
 	{
-		if ( mMeTyping )
+		if (mMeTyping)
 		{
-			if ( mTypingTimer.getElapsedTimeF32() > 1.f )
+			if (mTypingTimer.getElapsedTimeF32() > 1.f)
 			{
 				// Still typing, send 'start typing' notification
-				LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE);
+				LLIMModel::instance().sendTypingState(mSessionID,
+						mOtherParticipantUUID, TRUE);
 				mShouldSendTypingState = false;
 			}
 		}
 		else
 		{
 			// Send 'stop typing' notification immediately
-			LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE);
+			LLIMModel::instance().sendTypingState(mSessionID,
+					mOtherParticipantUUID, FALSE);
 			mShouldSendTypingState = false;
 		}
 	}
@@ -962,7 +966,7 @@ void LLIMFloater::setTyping(bool typing)
 
 void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
 {
-	if ( typing )
+	if (typing)
 	{
 		// other user started typing
 		addTypingIndicator(im_info);
@@ -976,9 +980,10 @@ void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
 
 void LLIMFloater::processAgentListUpdates(const LLSD& body)
 {
-	if ( !body.isMap() ) return;
+	if (!body.isMap())
+		return;
 
-	if ( body.has("agent_updates") && body["agent_updates"].isMap() )
+	if (body.has("agent_updates") && body["agent_updates"].isMap())
 	{
 		LLSD agent_data = body["agent_updates"].get(gAgentID.asString());
 		if (agent_data.isMap() && agent_data.has("info"))
@@ -987,7 +992,7 @@ void LLIMFloater::processAgentListUpdates(const LLSD& body)
 
 			if (agent_info.has("mutes"))
 			{
-				BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean(); 
+				BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean();
 				mInputEditor->setEnabled(!moderator_muted_text);
 				std::string label;
 				if (moderator_muted_text)
@@ -1008,7 +1013,7 @@ void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue)
 	LLFontGL* font = LLViewerChat::getChatFont();
 	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
 	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
-		 iter != inst_list.end(); ++iter)
+			iter != inst_list.end(); ++iter)
 	{
 		LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
 		if (floater)
@@ -1022,15 +1027,16 @@ void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue)
 void LLIMFloater::processSessionUpdate(const LLSD& session_update)
 {
 	// *TODO : verify following code when moderated mode will be implemented
-	if ( false && session_update.has("moderated_mode") &&
-		 session_update["moderated_mode"].has("voice") )
+	if (false && session_update.has("moderated_mode") &&
+			session_update["moderated_mode"].has("voice"))
 	{
 		BOOL voice_moderated = session_update["moderated_mode"]["voice"];
 		const std::string session_label = LLIMModel::instance().getName(mSessionID);
 
 		if (voice_moderated)
 		{
-			setTitle(session_label + std::string(" ") + LLTrans::getString("IM_moderated_chat_label"));
+			setTitle(session_label + std::string(" ")
+							+ LLTrans::getString("IM_moderated_chat_label"));
 		}
 		else
 		{
@@ -1044,15 +1050,14 @@ void LLIMFloater::processSessionUpdate(const LLSD& session_update)
 }
 
 BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
-						   BOOL drop, EDragAndDropType cargo_type,
-						   void *cargo_data, EAcceptance *accept,
-						   std::string& tooltip_msg)
+		BOOL drop, EDragAndDropType cargo_type,
+		void *cargo_data, EAcceptance *accept,
+		std::string& tooltip_msg)
 {
-
 	if (mDialog == IM_NOTHING_SPECIAL)
 	{
 		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
-												 cargo_type, cargo_data, accept);
+				cargo_type, cargo_data, accept);
 	}
 
 	// handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites
@@ -1062,14 +1067,14 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
 
 		if (cargo_type == DAD_CALLINGCARD)
 		{
-			if (dropCallingCard((LLInventoryItem*)cargo_data, drop))
+			if (dropCallingCard((LLInventoryItem*) cargo_data, drop))
 			{
 				*accept = ACCEPT_YES_MULTI;
 			}
 		}
 		else if (cargo_type == DAD_CATEGORY)
 		{
-			if (dropCategory((LLInventoryCategory*)cargo_data, drop))
+			if (dropCategory((LLInventoryCategory*) cargo_data, drop))
 			{
 				*accept = ACCEPT_YES_MULTI;
 			}
@@ -1081,9 +1086,9 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
 BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
 {
 	BOOL rv = isInviteAllowed();
-	if(rv && item && item->getCreatorUUID().notNull())
+	if (rv && item && item->getCreatorUUID().notNull())
 	{
-		if(drop)
+		if (drop)
 		{
 			uuid_vec_t ids;
 			ids.push_back(item->getCreatorUUID());
@@ -1101,26 +1106,26 @@ BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
 BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
 {
 	BOOL rv = isInviteAllowed();
-	if(rv && category)
+	if (rv && category)
 	{
 		LLInventoryModel::cat_array_t cats;
 		LLInventoryModel::item_array_t items;
 		LLUniqueBuddyCollector buddies;
 		gInventory.collectDescendentsIf(category->getUUID(),
-										cats,
-										items,
-										LLInventoryModel::EXCLUDE_TRASH,
-										buddies);
+				cats,
+				items,
+				LLInventoryModel::EXCLUDE_TRASH,
+				buddies);
 		S32 count = items.count();
-		if(count == 0)
+		if (count == 0)
 		{
 			rv = FALSE;
 		}
-		else if(drop)
+		else if (drop)
 		{
 			uuid_vec_t ids;
 			ids.reserve(count);
-			for(S32 i = 0; i < count; ++i)
+			for (S32 i = 0; i < count; ++i)
 			{
 				ids.push_back(items.get(i)->getCreatorUUID());
 			}
@@ -1132,12 +1137,11 @@ BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
 
 BOOL LLIMFloater::isInviteAllowed() const
 {
-
-	return ( (IM_SESSION_CONFERENCE_START == mDialog)
-			 || (IM_SESSION_INVITE == mDialog) );
+	return ((IM_SESSION_CONFERENCE_START == mDialog)
+			|| (IM_SESSION_INVITE == mDialog));
 }
 
-class LLSessionInviteResponder : public LLHTTPClient::Responder
+class LLSessionInviteResponder: public LLHTTPClient::Responder
 {
 public:
 	LLSessionInviteResponder(const LLUUID& session_id)
@@ -1165,7 +1169,7 @@ BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 
 	S32 count = ids.size();
 
-	if( isInviteAllowed() && (count > 0) )
+	if (isInviteAllowed() && (count > 0))
 	{
 		llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
 
@@ -1182,10 +1186,9 @@ BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 		data["method"] = "invite";
 		data["session-id"] = mSessionID;
 		LLHTTPClient::post(
-			url,
-			data,
-			new LLSessionInviteResponder(
-					mSessionID));
+				url,
+				data,
+				new LLSessionInviteResponder(mSessionID));
 	}
 	else
 	{
@@ -1202,17 +1205,17 @@ BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
 {
 	// We may have lost a "stop-typing" packet, don't add it twice
-	if ( im_info && !mOtherTyping )
+	if (im_info && !mOtherTyping)
 	{
 		mOtherTyping = true;
 
 		// Save and set new title
 		mSavedTitle = getTitle();
-		setTitle (mTypingStart);
+		setTitle(mTypingStart);
 
 		// Update speaker
 		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		if ( speaker_mgr )
+		if (speaker_mgr)
 		{
 			speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
 		}
@@ -1221,18 +1224,18 @@ void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
 
 void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 {
-	if ( mOtherTyping )
+	if (mOtherTyping)
 	{
 		mOtherTyping = false;
 
 		// Revert the title to saved one
 		setTitle(mSavedTitle);
 
-		if ( im_info )
+		if (im_info)
 		{
 			// Update speaker
 			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-			if ( speaker_mgr )
+			if (speaker_mgr)
 			{
 				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
 			}
@@ -1253,7 +1256,8 @@ void LLIMFloater::closeHiddenIMToasts()
 		}
 	};
 
-	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
+	LLNotificationsUI::LLScreenChannel* channel =
+			LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
 	if (channel != NULL)
 	{
 		channel->closeHiddenToasts(IMToastMatcher());
@@ -1295,28 +1299,34 @@ void LLIMFloater::initIMFloater()
 void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
 {
 	LLUUID session_id = data["session_id"];
-	if (session_id.isNull()) return;
+	if (session_id.isNull())
+		return;
 
 	LLUUID from_id = data["from_id"];
-	if (gAgentID == from_id || LLUUID::null == from_id) return;
+	if (gAgentID == from_id || LLUUID::null == from_id)
+		return;
 
 	LLIMFloater* floater = LLIMFloater::findInstance(session_id);
-	if (!floater) return;
+	if (!floater)
+		return;
 
-	if (IM_NOTHING_SPECIAL != floater->mDialog) return;
+	if (IM_NOTHING_SPECIAL != floater->mDialog)
+		return;
 
 	floater->removeTypingIndicator();
 }
 
-void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
+void LLIMFloater::onIMChicletCreated(const LLUUID& session_id)
 {
 
 	if (isChatMultiTab())
 	{
 		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-		if (!im_box) return;
+		if (!im_box)
+			return;
 
-		if (LLIMFloater::findInstance(session_id)) return;
+		if (LLIMFloater::findInstance(session_id))
+			return;
 
 		LLIMFloater* new_tab = LLIMFloater::getInstance(session_id);
 
@@ -1325,11 +1335,11 @@ void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
 
 }
 
-void	LLIMFloater::onClickCloseBtn()
+void LLIMFloater::onClickCloseBtn()
 {
 
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				mSessionID);
+			mSessionID);
 
 	if (session == NULL)
 	{
@@ -1342,7 +1352,8 @@ void	LLIMFloater::onClickCloseBtn()
 
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
 
-	if (is_call_with_chat && voice_channel != NULL && voice_channel->isActive())
+	if (is_call_with_chat && voice_channel != NULL
+			&& voice_channel->isActive())
 	{
 		LLSD payload;
 		payload["session_id"] = mSessionID;
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 40b3fff8f4..60b392952f 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -84,7 +84,7 @@ public:
 	// get new messages from LLIMModel
 	void updateMessages();
 	void reloadMessages();
-	static void onSendMsg( LLUICtrl*, void*);
+	static void onSendMsg(LLUICtrl*, void*);
 	void sendMsg();
 
 	// callback for LLIMModel on new messages
@@ -111,9 +111,9 @@ public:
 	static void processChatHistoryStyleUpdate(const LLSD& newvalue);
 
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
-							   BOOL drop, EDragAndDropType cargo_type,
-							   void *cargo_data, EAcceptance *accept,
-							   std::string& tooltip_msg);
+			BOOL drop, EDragAndDropType cargo_type,
+			void *cargo_data, EAcceptance *accept,
+			std::string& tooltip_msg);
 
 	/**
 	 * Returns true if chat is displayed in multi tabbed floater
@@ -131,10 +131,8 @@ public:
 	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
 
 protected:
-	/* virtual */
-	void	onClickCloseBtn();
-
-	/*virtual*/ void	updateTitleButtons();
+	/* virtual */ void onClickCloseBtn();
+	/* virtual */ void updateTitleButtons();
 
 private:
 	// process focus events to set a currently active session
@@ -143,24 +141,23 @@ private:
 
 	// Update the window title, input field help text, etc.
 	void updateSessionName(const std::string& ui_title, const std::string& ui_label);
-	
+
 	// For display name lookups for IM window titles
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-	
+
 	BOOL dropCallingCard(LLInventoryItem* item, BOOL drop);
 	BOOL dropCategory(LLInventoryCategory* category, BOOL drop);
 
 	BOOL isInviteAllowed() const;
 	BOOL inviteToSession(const uuid_vec_t& agent_ids);
-	
-	static void		onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
-	static void		onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
-	static void		onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
-	void			setTyping(bool typing);
-	void			onSlide();
-	static void*	createPanelIMControl(void* userdata);
-	static void*	createPanelGroupControl(void* userdata);
-	static void* 	createPanelAdHocControl(void* userdata);
+
+	static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
+	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
+	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
+	void setTyping(bool typing);
+	void onSlide();
+	static void* createPanelGroupControl(void* userdata);
+	static void* createPanelAdHocControl(void* userdata);
 
 	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
-- 
cgit v1.2.3


From c866b094ee000172f7cd820692f228f3f0afddc8 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 14 May 2012 21:19:18 +0300
Subject: CHUI-113 WIP  clean-up (obsolete code was removed)

---
 indra/newview/llpanelimcontrolpanel.cpp            | 102 -------------
 indra/newview/llpanelimcontrolpanel.h              |  28 ----
 .../default/xui/en/panel_im_control_panel.xml      | 166 ---------------------
 3 files changed, 296 deletions(-)
 delete mode 100644 indra/newview/skins/default/xui/en/panel_im_control_panel.xml

(limited to 'indra')

diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index f0fc15b4d8..cba0d6c064 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -56,108 +56,6 @@ void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
 	mSessionId = session_id;
 }
 
-LLPanelIMControlPanel::LLPanelIMControlPanel()
-{
-}
-
-LLPanelIMControlPanel::~LLPanelIMControlPanel()
-{
-//	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
-}
-
-BOOL LLPanelIMControlPanel::postBuild()
-{
-/*	childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this));
-	childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this));
-
-	childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));
-	childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this));
-	childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this));
-
-	childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this));
-	childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this));
-
-	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));
-
-	setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this));
-*/
-	return LLPanelChatControlPanel::postBuild();
-
-}
-
-void LLPanelIMControlPanel::draw()
-{
-	bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID);
-
-	getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted);
-	getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted);
-
-
-	LLPanelChatControlPanel::draw();
-}
-
-void LLPanelIMControlPanel::onClickBlock()
-{
-	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-
-	LLMuteList::getInstance()->add(mute);
-}
-
-void LLPanelIMControlPanel::onClickUnblock()
-{
-	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-
-	LLMuteList::getInstance()->remove(mute);
-}
-
-void LLPanelIMControlPanel::onTeleportButtonClicked()
-{
-	LLAvatarActions::offerTeleport(mAvatarID);
-}
-void LLPanelIMControlPanel::onPayButtonClicked()
-{
-	LLAvatarActions::pay(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onViewProfileButtonClicked()
-{
-	LLAvatarActions::showProfile(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onAddFriendButtonClicked()
-{
-	LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
-	std::string full_name = avatar_icon->getFullName();
-	LLAvatarActions::requestFriendshipDialog(mAvatarID, full_name);
-}
-
-void LLPanelIMControlPanel::onShareButtonClicked()
-{
-	LLAvatarActions::share(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onFocusReceived()
-{
-	// Disable all the buttons (Call, Teleport, etc) if disconnected.
-	if (gDisconnected)
-	{
-		setAllChildrenEnabled(FALSE);
-	}
-}
-
-
-void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group)
-{
-	if ( id == mAvatarID )
-	{
-		std::string avatar_name = full_name;
-		getChild<LLTextBox>("avatar_name")->setValue(avatar_name);
-		getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name);
-
-		bool is_linden = LLStringUtil::endsWith(full_name, " Linden");
-		getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden);
-	}
-}
 
 LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):
 mParticipantList(NULL)
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index 3466da33a1..0ec992bb1e 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -52,34 +52,6 @@ private:
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
 };
 
-
-class LLPanelIMControlPanel : public LLPanelChatControlPanel
-{
-public:
-	LLPanelIMControlPanel();
-	~LLPanelIMControlPanel();
-
-	BOOL postBuild();
-
-	//void setSessionId(const LLUUID& session_id);
-
-protected:
-	void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
-
-private:
-	void onViewProfileButtonClicked();
-	void onAddFriendButtonClicked();
-	void onShareButtonClicked();
-	void onTeleportButtonClicked();
-	void onPayButtonClicked();
-	void onFocusReceived();
-	void onClickBlock();
-	void onClickUnblock();
-	/*virtual*/ void draw();
-	LLUUID mAvatarID;
-};
-
-
 class LLPanelGroupControlPanel : public LLPanelChatControlPanel
 {
 public:
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
deleted file mode 100644
index 8fcd6ccbaf..0000000000
--- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- height="300"
- name="panel_im_control_panel"
- width="150">
-    <avatar_icon
-     follows="left|top"
-     height="105"
-     left_delta="20"
-     name="avatar_icon"
-     top="-5"
-     width="114"/>
-    <layout_stack
-     mouse_opaque="false"
-     border_size="0"
-     clip="false"
-     follows="all"
-     height="183"
-     layout="topleft"
-     left="5"
-     name="button_stack"
-     orientation="vertical"
-     top_pad="5"
-     width="145">
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="20"
-         layout="topleft"
-         left="2" 
-         min_height="20"
-         width="140"
-         name="view_profile_btn_panel"
-         top="0" >
-            <button
-             follows="left|top|right"
-             height="23"
-             label="Profile"
-             name="view_profile_btn"
-             top="0"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="add_friend_btn_panel">
-            <button
-             follows="left|top|right"
-             height="23"
-             label="Add Friend"
-             name="add_friend_btn"
-             top="5"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="teleport_btn_panel">
-        <button
-             auto_resize="false"
-             follows="left|top|right"
-             height="23"
-             label="Teleport"
-             name="teleport_btn"
-             tool_tip = "Offer to teleport this person"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="share_btn_panel">
-           <button
-             auto_resize="true"
-             follows="left|top|right"
-             height="23"
-             label="Share"
-             name="share_btn"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="pay_btn_panel">
-           <button
-             auto_resize="true"
-             follows="left|top|right"
-             height="23"
-             label="Pay"
-             name="pay_btn"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="call_btn_panel">
-            <button
-             follows="left|top|right"
-             height="23"
-             label="Call"
-             name="call_btn"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="end_call_btn_panel"
-         visible="false">
-            <button
-             follows="left|top|right"
-             height="23"
-             label="End Call"
-             name="end_call_btn"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="voice_ctrls_btn_panel"
-         visible="false">
-            <button
-             follows="left|top|right"
-             height="23"
-             label="Voice Controls"
-             name="voice_ctrls_btn"
-             width="140" />
-        </layout_panel>
-      <layout_panel
-       mouse_opaque="false"
-       auto_resize="true"
-       follows="top|left"
-       height="0"
-       layout="topleft"
-       min_height="0"
-       width="140"
-       name="spacer"/>
-    </layout_stack>
-</panel>
-- 
cgit v1.2.3


From 0568fb00ab1bc6ddaed5fdd7cac88e81aa8c26e2 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 15 May 2012 19:31:55 +0300
Subject: CHUI-102 WIP Implemented new context menu for ad-hoc and group
 conferences

---
 indra/newview/llpanelpeoplemenus.cpp |  7 +++++--
 indra/newview/llparticipantlist.cpp  | 14 ++++++++------
 2 files changed, 13 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 0d66b8f10b..c84790d839 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -51,6 +51,7 @@ LLContextMenu* NearbyMenu::createMenu()
 	// set up the callbacks for all of the avatar menu items
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+	LLContextMenu* menu;
 
 	if ( mUUIDs.size() == 1 )
 	{
@@ -73,7 +74,7 @@ LLContextMenu* NearbyMenu::createMenu()
 		enable_registrar.add("Avatar.CheckItem",  boost::bind(&NearbyMenu::checkContextMenuItem,	this, _2));
 
 		// create the context menu from the XUI
-		return createFromFile("menu_people_nearby.xml");
+		menu = createFromFile("menu_people_nearby.xml");
 	}
 	else
 	{
@@ -89,8 +90,10 @@ LLContextMenu* NearbyMenu::createMenu()
 		enable_registrar.add("Avatar.EnableItem",	boost::bind(&NearbyMenu::enableContextMenuItem,	this, _2));
 
 		// create the context menu from the XUI
-		return createFromFile("menu_people_nearby_multiselect.xml");
+		menu = createFromFile("menu_people_nearby_multiselect.xml");
 	}
+
+    return menu;
 }
 
 bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 975a6c67d8..59d26edff2 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -32,6 +32,7 @@
 #include "llagent.h"
 
 #include "llimview.h"
+#include "llpanelpeoplemenus.h"
 #include "llnotificationsutil.h"
 #include "llparticipantlist.h"
 #include "llspeakers.h"
@@ -197,10 +198,10 @@ private:
 	uuid_set_t mAvalineCallers;
 };
 
-LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, 
+LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 									 LLAvatarList* avatar_list,
 									 bool use_context_menu/* = true*/,
-									 bool exclude_agent /*= true*/, 
+									 bool exclude_agent /*= true*/,
 									 bool can_toggle_icons /*= true*/) :
 	mSpeakerMgr(data_source),
 	mAvatarList(avatar_list),
@@ -233,8 +234,9 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 
 	if (use_context_menu)
 	{
-		mParticipantListMenu = new LLParticipantListMenu(*this);
-		mAvatarList->setContextMenu(mParticipantListMenu);
+		//mParticipantListMenu = new LLParticipantListMenu(*this);
+		//mAvatarList->setContextMenu(mParticipantListMenu);
+		mAvatarList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
 	}
 	else
 	{
@@ -670,7 +672,7 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::
 	return mParent.onSpeakerMuteEvent(event, userdata);
 }
 
-LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
+/*LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
 {
 	// set up the callbacks for all of the avatar menu items
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -708,7 +710,7 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
 	main_menu->arrangeAndClear();
 
 	return main_menu;
-}
+}*/
 
 void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y)
 {
-- 
cgit v1.2.3


From 0ed7966bd5471e4152ade9ac63e81406b4d0a679 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 15 May 2012 20:42:14 +0300
Subject: CHUI-105 WIP Remove obsolete controls from the group's control pane

---
 indra/newview/llpanelimcontrolpanel.cpp            |  7 +---
 indra/newview/llpanelimcontrolpanel.h              |  1 -
 .../default/xui/en/panel_group_control_panel.xml   | 49 ----------------------
 3 files changed, 1 insertion(+), 56 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index cba0d6c064..bc4097cd93 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -64,7 +64,6 @@ mParticipantList(NULL)
 
 BOOL LLPanelGroupControlPanel::postBuild()
 {
-	childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this));
 
 	return LLPanelChatControlPanel::postBuild();
 }
@@ -84,10 +83,6 @@ void LLPanelGroupControlPanel::draw()
 	LLPanelChatControlPanel::draw();
 }
 
-void LLPanelGroupControlPanel::onGroupInfoButtonClicked()
-{
-	LLGroupActions::show(mGroupID);
-}
 
 void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata)
 {
@@ -114,7 +109,7 @@ void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
 	if(!mParticipantList)
 	{
 		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
-		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false);
+		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);
 	}
 }
 
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index 0ec992bb1e..02915ec4bb 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -69,7 +69,6 @@ protected:
 	LLParticipantList* mParticipantList;
 
 private:
-	void onGroupInfoButtonClicked();
 	void onSortMenuItemClicked(const LLSD& userdata);
 };
 
diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
index ad10e53a4e..a5295ebe01 100644
--- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
@@ -40,55 +40,6 @@
              show_speaking_indicator="false"
              width="145" />
         </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         width="130"
-         name="group_info_btn_panel">
-            <button
-             follows="left|right|bottom"
-             height="23"
-             label="Group Profile"
-             name="group_info_btn"
-             use_ellipses="true"
-             top="5"
-             width="130" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         width="130"
-         name="call_btn_panel">
-            <button
-             follows="all"
-             height="23"
-             label="Call Group"
-             name="call_btn"
-             use_ellipses="true" 
-             width="130" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         width="130"
-         name="end_call_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="23"
-             label="Leave Call"
-             name="end_call_btn"
-             use_ellipses="true" />
-        </layout_panel>
         <layout_panel
          auto_resize="false"
          follows="top|left|right"
-- 
cgit v1.2.3


From e2824864590ded669eac3c53efbfc60d04107ee4 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 15 May 2012 22:19:20 +0300
Subject: CHUI-105 WIP Hide an additional close button for undocked state of an
 IM floater

---
 indra/newview/llimfloater.cpp | 10 ++++++++++
 indra/newview/llimfloater.h   |  3 +++
 2 files changed, 13 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index cb489627fb..1ca3545aae 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -391,6 +391,12 @@ BOOL LLIMFloater::postBuild()
 	}
 }
 
+void LLIMFloater::onTearOffClicked(LLIMFloater* self)
+{
+	onClickTearOff(self);
+	updateTitleButtons();
+}
+
 void LLIMFloater::boundVoiceChannel()
 {
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
@@ -1377,6 +1383,7 @@ void LLIMFloater::updateTitleButtons()
 	}
 
 	bool is_hosted = getHost() != NULL;
+
 	if (is_hosted) ///< floater is hosted
 	{
 		for (S32 i = 0; i < BUTTON_COUNT; i++)
@@ -1391,6 +1398,7 @@ void LLIMFloater::updateTitleButtons()
 		}
 
 		mExpandCollapseBtn->setImageOverlay(getString("collapse_icon"));
+
 	}
 	else ///< floater is torn off
 	{
@@ -1403,6 +1411,8 @@ void LLIMFloater::updateTitleButtons()
 		}
 	}
 
+	getChild<LLButton>("close_btn")->setVisible(is_hosted);
+
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
 	if (session)
 	{
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 60b392952f..03f52fb316 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -93,6 +93,7 @@ public:
 
 	// called when docked floater's position has been set by chiclet
 	void setPositioned(bool b) { mPositioned = b; };
+
 	void onVisibilityChange(const LLSD& new_visibility);
 
 	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
@@ -139,6 +140,8 @@ private:
 	/* virtual */ void onFocusLost();
 	/* virtual */ void onFocusReceived();
 
+	void onTearOffClicked(LLIMFloater *self);
+
 	// Update the window title, input field help text, etc.
 	void updateSessionName(const std::string& ui_title, const std::string& ui_label);
 
-- 
cgit v1.2.3


From f59aa880395d4b744c89b0a375b21ee2bf429625 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 17 May 2012 02:51:18 +0300
Subject: CHUI-105 WIP Implemented collapsed/expanded state transitions for
 messages and conversation panes. The states and dimensions of Conversations
 floater panes are saved in per account settings.

---
 indra/llui/lllayoutstack.h                         |   2 +
 indra/llui/llmultifloater.cpp                      |  36 +++--
 indra/llui/llmultifloater.h                        |   3 +
 .../newview/app_settings/settings_per_account.xml  |  55 +++++++
 indra/newview/llimfloater.cpp                      |   4 +-
 indra/newview/llimfloatercontainer.cpp             | 133 ++++++++++++++---
 indra/newview/llimfloatercontainer.h               |  18 ++-
 .../skins/default/xui/en/floater_im_container.xml  | 158 ++++++++++++++-------
 8 files changed, 320 insertions(+), 89 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index d32caec5f9..58643868e8 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -177,6 +177,8 @@ public:
 	F32 getVisibleAmount() const;
 	S32 getVisibleDim() const;
 
+	bool isCollapsed() const { return mCollapsed;}
+
 	void setOrientation(LLLayoutStack::ELayoutOrientation orientation);
 	void storeOriginalDim();
 
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index f3a48835b1..540ac74aee 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -468,23 +468,12 @@ BOOL LLMultiFloater::postBuild()
 
 void LLMultiFloater::updateResizeLimits()
 {
-	static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
-	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
-	S32 floater_header_size = default_params.header_height;
-	S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
 	// initialize minimum size constraint to the original xml values.
 	S32 new_min_width = mOrigMinWidth;
 	S32 new_min_height = mOrigMinHeight;
-	// possibly increase minimum size constraint due to children's minimums.
-	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
-	{
-		LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
-		if (floaterp)
-		{
-			new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
-			new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
-		}
-	}
+
+	computeResizeLimits(new_min_width, new_min_height);
+
 	setResizeLimits(new_min_width, new_min_height);
 
 	S32 cur_height = getRect().getHeight();
@@ -510,3 +499,22 @@ void LLMultiFloater::updateResizeLimits()
 		gFloaterView->adjustToFitScreen(this, TRUE);
 	}
 }
+
+void LLMultiFloater::computeResizeLimits(S32& new_min_width, S32& new_min_height)
+{
+	static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
+	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
+	S32 floater_header_size = default_params.header_height;
+	S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
+
+	// possibly increase minimum size constraint due to children's minimums.
+	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+	{
+		LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
+		if (floaterp)
+		{
+			new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
+			new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
+		}
+	}
+}
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index 9fa917eca1..f299ae5dd3 100644
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -93,6 +93,9 @@ protected:
 	LLTabContainer::TabPosition mTabPos;
 	BOOL				mAutoResize;
 	S32					mOrigMinWidth, mOrigMinHeight;  // logically const but initialized late
+
+private:
+	virtual void computeResizeLimits(S32& new_min_width, S32& new_min_height);
 };
 
 #endif  // LL_MULTI_FLOATER_H
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 8cdd8ed838..fdc52b7394 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -22,6 +22,61 @@
         <key>Value</key>
             <string>The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>
         </map>
+    <key>ConversationsExpandMessagePaneFirst</key>
+    <map>
+        <key>Comment</key>
+            <string>Expand either messages or conversations list pane from Conversations compact mode.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>1</integer>
+    </map>
+    <key>ConversationsListPaneCollapsed</key>
+    <map>
+        <key>Comment</key>
+            <string>Stores the expanded/collapsed state of the conversations list pane in Conversations floater.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>0</integer>
+    </map>
+    <key>ConversationsListPaneWidth</key>
+    <map>
+        <key>Comment</key>
+            <string>Conversations floater list pane width.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>S32</string>
+        <key>Value</key>
+            <integer>268</integer>
+    </map>
+    <key>ConversationsMessagePaneCollapsed</key>
+    <map>
+        <key>Comment</key>
+            <string>Stores the expanded/collapsed state of Conversations floater message pane.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>0</integer>
+    </map>
+    <key>ConversationsMessagePaneWidth</key>
+    <map>
+        <key>Comment</key>
+            <string>Conversations floater message pane width.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>S32</string>
+        <key>Value</key>
+            <integer>412</integer>
+    </map>
     <key>InstantMessageLogPath</key>
         <map>
         <key>Comment</key>
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 1ca3545aae..051bb39540 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -188,7 +188,7 @@ void LLIMFloater::onOpen(const LLSD& key)
 	if (host_floater)
 	{
 		// Show the messages pane when opening a floater hosted in the Conversations
-		host_floater->toggleMessagesPane(true);
+		host_floater->collapseMessagesPane(false);
 	}
 }
 
@@ -536,7 +536,7 @@ void LLIMFloater::onSlide()
 	if (host_floater)
 	{
 		// Hide the messages pane if a floater is hosted in the Conversations
-		host_floater->toggleMessagesPane(false);
+		host_floater->collapseMessagesPane(true);
 	}
 	else ///< floater is torn off
 	{
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c8b8cb208d..b051440589 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -28,19 +28,23 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llimfloatercontainer.h"
+
 #include "llfloaterreg.h"
-#include "llimview.h"
+#include "lllayoutstack.h"
+
+#include "llagent.h"
 #include "llavatariconctrl.h"
 #include "llgroupiconctrl.h"
-#include "llagent.h"
+#include "llimview.h"
 #include "lltransientfloatermgr.h"
+#include "llviewercontrol.h"
 
 //
 // LLIMFloaterContainer
 //
 LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 :	LLMultiFloater(seed)
-    ,mMessagesPaneWidth(0)
+	,mExpandCollapseBtn(NULL)
 {
 	mAutoResize = FALSE;
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
@@ -50,6 +54,9 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 {
 	mNewMessageConnection.disconnect();
 	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
+
+	gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed());
+	gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
 }
 
 BOOL LLIMFloaterContainer::postBuild()
@@ -60,6 +67,16 @@ BOOL LLIMFloaterContainer::postBuild()
 	
 	setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
 
+	mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
+	mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel");
+	mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel");
+
+	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
+
+	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
+	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
+
 	return TRUE;
 }
 
@@ -146,6 +163,37 @@ void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
 	mSessions.erase(id);
 }
 
+// virtual
+void LLIMFloaterContainer::computeResizeLimits(S32& new_min_width, S32& new_min_height)
+{
+	bool is_left_pane_expanded = !mConversationsPane->isCollapsed();
+	bool is_right_pane_expanded = !mMessagesPane->isCollapsed();
+
+	S32 conversations_pane_min_dim = mConversationsPane->getMinDim();
+
+	if (is_right_pane_expanded)
+	{
+		S32 conversations_pane_width =
+				(is_left_pane_expanded ? gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") : conversations_pane_min_dim);
+
+		// possibly increase minimum size constraint due to children's minimums.
+		for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+		{
+			LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getPanelByIndex(tab_idx));
+			if (floaterp)
+			{
+				new_min_width = llmax(new_min_width,
+						floaterp->getMinWidth() + conversations_pane_width + LLPANEL_BORDER_WIDTH * 2);
+				new_min_height = llmax(new_min_height, floaterp->getMinHeight());
+			}
+		}
+	}
+	else
+	{
+		new_min_width = conversations_pane_min_dim;
+	}
+}
+
 void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data)
 {
 	LLUUID session_id = data["session_id"].asUUID();
@@ -160,6 +208,21 @@ void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data)
 	}
 }
 
+void LLIMFloaterContainer::onExpandCollapseButtonClicked()
+{
+	if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()
+			&& gSavedPerAccountSettings.getBOOL("ConversationsExpandMessagePaneFirst"))
+	{
+		// Expand the messages pane from ultra minimized state
+		// if it was collapsed last in order.
+		collapseMessagesPane(false);
+	}
+	else
+	{
+		collapseConversationsPane(!mConversationsPane->isCollapsed());
+	}
+}
+
 LLIMFloaterContainer* LLIMFloaterContainer::findInstance()
 {
 	return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container");
@@ -186,29 +249,67 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 	}
 }
 
-void LLIMFloaterContainer::toggleMessagesPane(bool expand)
+void LLIMFloaterContainer::collapseMessagesPane(bool collapse)
 {
-	LLView* messages_pane = getChild<LLView>("im_box_tab_container");
-	bool is_expanded = messages_pane->getVisible();
-	if (is_expanded == expand)
+	if (mMessagesPane->isCollapsed() == collapse)
 	{
 		return;
 	}
 
-	// Store the messages pane width before collapsing it.
-	if (!expand)
+	if (collapse)
 	{
-		LLView* conversations_pane = getChild<LLView>("conversations_pane");
-		S32 horizontal_pad = messages_pane->getRect().mLeft - conversations_pane->getRect().mRight;
-		mMessagesPaneWidth = messages_pane->getRect().getWidth() + horizontal_pad;
+		// Save the messages pane width before collapsing it.
+		gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", mMessagesPane->getRect().getWidth());
+
+		// Save the order in which the panels are closed to reverse user's last action.
+		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
 	}
 
 	// Show/hide the messages pane.
-	messages_pane->setVisible(expand);
+	mConversationsStack->collapsePanel(mMessagesPane, collapse);
+
+	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+}
+
+void LLIMFloaterContainer::collapseConversationsPane(bool collapse)
+{
+	if (mConversationsPane->isCollapsed() == collapse)
+	{
+		return;
+	}
+
+	LLView* button_panel = getChild<LLView>("conversations_pane_buttons_expanded");
+	button_panel->setVisible(!collapse);
+	mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon"));
+
+	if (collapse)
+	{
+		// Save the conversations pane width before collapsing it.
+		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", mConversationsPane->getRect().getWidth());
+
+		// Save the order in which the panels are closed to reverse user's last action.
+		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", !mMessagesPane->isCollapsed());
+	}
+
+	mConversationsStack->collapsePanel(mConversationsPane, collapse);
+
+	S32 collapsed_width = mConversationsPane->getMinDim();
+	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - collapsed_width);
+}
+
+void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
+{
+	LLRect floater_rect = getRect();
+	floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
+	setShape(floater_rect);
+
+	updateResizeLimits();
+
+	bool is_left_pane_expanded = !mConversationsPane->isCollapsed();
+	bool is_right_pane_expanded = !mMessagesPane->isCollapsed();
 
-	S32 floater_width = getRect().getWidth();
-	floater_width += (expand ? mMessagesPaneWidth : -mMessagesPaneWidth);
-	reshape(floater_width, getRect().getHeight());
+	setCanResize(is_left_pane_expanded || is_right_pane_expanded);
+	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
 }
 
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 045f053b1c..92938ff405 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -35,6 +35,9 @@
 #include "llavatarpropertiesprocessor.h"
 #include "llgroupmgr.h"
 
+class LLButton;
+class LLLayoutPanel;
+class LLLayoutStack;
 class LLTabContainer;
 
 class LLIMFloaterContainer : public LLMultiFloater
@@ -60,16 +63,27 @@ public:
 
 	virtual void setMinimized(BOOL b);
 
-	void toggleMessagesPane(bool expand);
+	void collapseMessagesPane(bool collapse);
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
 	avatarID_panel_map_t mSessions;
 	boost::signals2::connection mNewMessageConnection;
 
+	/*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height);
+
 	void onNewMessageReceived(const LLSD& data);
 
-	S32	mMessagesPaneWidth;
+	void onExpandCollapseButtonClicked();
+
+	void collapseConversationsPane(bool collapse);
+
+	void updateState(bool collapse, S32 delta_width);
+
+	LLButton* mExpandCollapseBtn;
+	LLLayoutPanel* mMessagesPane;
+	LLLayoutPanel* mConversationsPane;
+	LLLayoutStack* mConversationsStack;
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 8a0181bae4..ce40f44a64 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -5,7 +5,7 @@
  can_resize="true"
  height="430"
  layout="topleft"
- min_width="510"
+ min_height="50"
  name="floater_im_box"
  help_topic="floater_im_box"
  save_rect="true"
@@ -13,62 +13,110 @@
  single_instance="true"
  title="CONVERSATIONS"
  width="680">
-    <panel
-         border="true"
-         follows="top|bottom|left"
-         layout="topleft"
-         name="conversations_pane"
-         opaque="true"
-         top="0"
-         left="5"
-         height="425"
-         width="263">
-             <menu_button
-                 follows="top|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="OptionsMenu_Off"
-                 image_selected="Toolbar_Middle_Selected"
-                 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 left="5"
-                 name="sort_btn"
-                 top="5"
-                 width="31" />
-             <button
-                 follows="top|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="AddItem_Off"
-                 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left_pad="4"
-                 name="add_btn"
-                 tool_tip="Add button on the left panel"
-                 width="31">
-             </button>
-             <button
-                 follows="right|top"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="TabIcon_Open_Off"
-                 image_selected="Toolbar_Middle_Selected"
-                 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left="228"
-                 name="expand_collapse_btn"
-                 width="31" />
-    </panel>
-    <panel_container
+    <string
+     name="collapse_icon"
+     value="TabIcon_Open_Off"/>
+    <string
+     name="expand_icon"
+     value="TabIcon_Close_Off"/>
+    <layout_stack
+     animate="true" 
      follows="all"
      height="430"
      layout="topleft"
-     left_pad="15"
-     min_width="290"
-     name="im_box_tab_container"
+     left="0"
+     name="conversations_stack"
+     orientation="horizontal"
      top="0"
-     width="389"/>
+     width="680">
+        <layout_panel
+         auto_resize="true"
+         height="430"
+         name="conversations_layout_panel"
+         min_dim="41"
+         width="268">
+            <layout_stack
+             animate="false" 
+             follows="left|top|right"
+             height="35"
+             layout="topleft"
+             left="0"
+             name="conversations_pane_buttons_stack"
+             orientation="horizontal"
+             top="0"
+             width="268">
+                <layout_panel
+                 auto_resize="true"
+                 height="35"
+                 name="conversations_pane_buttons_expanded">
+                    <menu_button
+                     follows="top|left"
+                     height="25"
+                     image_hover_unselected="Toolbar_Middle_Over"
+                     image_overlay="OptionsMenu_Off"
+                     image_selected="Toolbar_Middle_Selected"
+                     image_unselected="Toolbar_Middle_Off"
+                     layout="topleft"
+                     left="10"
+                     name="sort_btn"
+                     top="5"
+                     width="31" />
+                    <button
+                     follows="top|left"
+                     height="25"
+                     image_hover_unselected="Toolbar_Middle_Over"
+                     image_overlay="AddItem_Off"
+                     image_selected="Toolbar_Middle_Selected"
+                      image_unselected="Toolbar_Middle_Off"
+                     layout="topleft"
+                     top="5"
+                     left_pad="4"
+                     name="add_btn"
+                     tool_tip="Add button on the left panel"
+                     width="31"/>
+                </layout_panel>
+                <layout_panel
+                 auto_resize="false"
+                 height="35"
+                 name="conversations_pane_buttons_collapsed"
+                 width="41">
+                    <button
+                     follows="right|top"
+                     height="25"
+                     image_hover_unselected="Toolbar_Middle_Over"
+                     image_overlay="TabIcon_Open_Off"
+                     image_selected="Toolbar_Middle_Selected"
+                     image_unselected="Toolbar_Middle_Off"
+                     layout="topleft"
+                     top="5"
+                     left="5"
+                     name="expand_collapse_btn"
+                     width="31" />
+                </layout_panel>
+            </layout_stack>
+            <panel
+             follows="all"
+             layout="topleft"
+             name="conversations_list_panel"
+             opaque="true"
+             top_pad="0"
+             left="5"
+             height="390"
+             width="263"/>
+        </layout_panel>
+        <layout_panel
+         auto_resize="true"
+         height="430"
+         name="messages_layout_panel"
+         width="412">
+            <panel_container
+             follows="all"
+             height="430"
+             layout="topleft"
+             left="10"
+             name="im_box_tab_container"
+             top="0"
+             width="402"/>
+        </layout_panel>
+    </layout_stack>
 </multi_floater>
-- 
cgit v1.2.3


From 4fc8000d6692290516eae1f865b6b41f1d56cc0b Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 17 May 2012 19:35:05 +0300
Subject: CHUI-105 ADD. FIX Implement changes to all open conversations and
 nearby chat

---
 indra/newview/llfloaterpreference.cpp |  21 +++----
 indra/newview/llimfloater.cpp         |  85 ++++++++++++++-------------
 indra/newview/llimfloater.h           |  14 +++--
 indra/newview/llimview.cpp            |  18 +++---
 indra/newview/llimview.h              |  14 ++---
 indra/newview/llnearbychat.cpp        | 104 +++++++++++++++++-----------------
 indra/newview/llnearbychat.h          |   8 ++-
 7 files changed, 140 insertions(+), 124 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 1c29323594..3ed575086c 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -423,13 +423,13 @@ void LLFloaterPreference::saveAvatarProperties( void )
 
 BOOL LLFloaterPreference::postBuild()
 {
-	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
+	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate));
 
-	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
+	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate));
 
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
+	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate));
 
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
+	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate));
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
 
@@ -457,14 +457,11 @@ BOOL LLFloaterPreference::postBuild()
 void LLFloaterPreference::onBusyResponseChanged()
 {
 	// set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
-	if (LLTrans::getString("BusyModeResponseDefault") != getChild<LLUICtrl>("busy_response")->getValue().asString())
-	{
-		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", TRUE );
-	}
-	else
-	{
-		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", FALSE );
-	}
+	bool busy_flag =
+			LLTrans::getString("BusyModeResponseDefault")
+					!= getChild<LLUICtrl>("busy_response")->getValue().asString();
+
+	gSavedPerAccountSettings.setBOOL("BusyResponseChanged", busy_flag );
 }
 
 LLFloaterPreference::~LLFloaterPreference()
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 051bb39540..c6608337c8 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -44,6 +44,7 @@
 #include "lllayoutstack.h"
 #include "lllineeditor.h"
 #include "lllogchat.h"
+#include "llnearbychat.h"
 #include "llpanelimcontrolpanel.h"
 #include "llscreenchannel.h"
 #include "llsyswellwindow.h"
@@ -63,13 +64,14 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mSessionID(session_id),
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
-	mChatHistory(NULL),
 	mInputEditor(NULL),
 	mExpandCollapseBtn(NULL),
 	mTearOffBtn(NULL),
 	mSavedTitle(),
 	mTypingStart(),
+	mIsP2PChat(false),
 	mShouldSendTypingState(false),
+	mChatHistory(NULL),
 	mMeTyping(false),
 	mOtherTyping(false),
 	mTypingTimer(),
@@ -77,12 +79,14 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mPositioned(false),
 	mSessionInitialized(false)
 {
-	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionID);
-	if (im_session)
+	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+	if (mSession)
 	{
-		mSessionInitialized = im_session->mSessionInitialized;
+		mIsP2PChat = mSession->isP2PSessionType();
+		mSessionInitialized = mSession->mSessionInitialized;
 		
-		mDialog = im_session->mType;
+		mDialog = mSession->mType;
 		switch (mDialog)
 		{
 		case IM_SESSION_CONFERENCE_START:
@@ -101,8 +105,6 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
 			}
 			break;
-		case IM_NOTHING_SPECIAL:
-		case IM_SESSION_P2P_INVITE:
 		default:
 			break;
 		}
@@ -135,14 +137,13 @@ bool LLIMFloater::onIMShowModesMenuItemCheck(const LLSD& userdata)
 	return gSavedSettings.getBOOL(userdata.asString());
 }
 
+// enable/disable states for the "show time" and "show names" items of the show-modes menu
 bool LLIMFloater::onIMShowModesMenuItemEnable(const LLSD& userdata)
 {
 	std::string item = userdata.asString();
 	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
 	bool is_not_names = (item != "IMShowNamesForP2PConv");
-	LLIMModel::LLIMSession* im_session = LLIMModel::instance().findIMSession(mSessionID);
-	bool is_p2p_chat = im_session && im_session->isP2PSessionType();
-	return (plain_text && (is_not_names || is_p2p_chat));
+	return (plain_text && (is_not_names || mIsP2PChat));
 }
 
 void LLIMFloater::onIMSessionMenuItemClicked(const LLSD& userdata)
@@ -159,7 +160,8 @@ void LLIMFloater::onIMSessionMenuItemClicked(const LLSD& userdata)
 		gSavedSettings.setBOOL(item, !prev_value);
 	}
 
-	reloadMessages();
+	LLIMFloater::processChatHistoryStyleUpdate();
+	LLNearbyChat::processChatHistoryStyleUpdate();
 }
 
 void LLIMFloater::onFocusLost()
@@ -353,18 +355,16 @@ BOOL LLIMFloater::postBuild()
 	mTypingStart = LLTrans::getString("IM_typing_start_string");
 
 	// Disable input editor if session cannot accept text
-	LLIMModel::LLIMSession* im_session =
-			LLIMModel::instance().findIMSession(mSessionID);
-	if ( im_session && !im_session->mTextIMPossible )
+	if ( mSession && !mSession->mTextIMPossible )
 	{
 		mInputEditor->setEnabled(FALSE);
 		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
 	}
 
-	if (im_session && im_session->isP2PSessionType())
+	if (mIsP2PChat)
 	{
 		// look up display name for window title
-		LLAvatarNameCache::get(im_session->mOtherParticipantID,
+		LLAvatarNameCache::get(mSession->mOtherParticipantID,
 				boost::bind(&LLIMFloater::onAvatarNameCache,
 						this, _1, _2));
 	}
@@ -424,16 +424,14 @@ void LLIMFloater::enableDisableCallBtn()
 	bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled()
 			&& LLVoiceClient::getInstance()->isVoiceWorking();
 
-	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionID);
-
-	if (!session)
+	if (!mSession)
 	{
 		getChildView("voice_call_btn")->setEnabled(false);
 		return;
 	}
 
-	bool session_initialized = session->mSessionInitialized;
-	bool callback_enabled = session->mCallBackEnabled;
+	bool session_initialized = mSession->mSessionInitialized;
+	bool callback_enabled = mSession->mCallBackEnabled;
 
 	BOOL enable_connect = session_initialized
 		&& voice_enabled
@@ -763,12 +761,16 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	if (mSessionID != im_session_id)
 	{
 		mSessionID = im_session_id;
+
 		setKey(im_session_id);
 		if (mControlPanel)
 		{
 			mControlPanel->setSessionId(im_session_id);
 		}
 		boundVoiceChannel();
+
+		mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+		mIsP2PChat = mSession && mSession->isP2PSessionType();
 	}
 
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
@@ -785,30 +787,35 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	}
 }
 
-void LLIMFloater::updateMessages()
+void LLIMFloater::appendMessage(const LLChat& chat, const LLSD &args)
 {
-	bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory");
+	LLChat& tmp_chat = const_cast<LLChat&>(chat);
+
+	if (!chat.mMuted)
+	{
+		tmp_chat.mFromName = chat.mFromName;
+		LLSD chat_args;
+		if (args) chat_args = args;
+		chat_args["use_plain_text_chat_history"] =
+				gSavedSettings.getBOOL("PlainTextChatHistory");
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] = !mIsP2PChat
+				|| gSavedSettings.getBOOL("IMShowNamesForP2PConv");
 
+		mChatHistory->appendMessage(chat, chat_args);
+	}
+}
+
+void LLIMFloater::updateMessages()
+{
 	std::list<LLSD> messages;
 
 	// we shouldn't reset unread message counters if IM floater doesn't have focus
-	if (hasFocus())
-	{
-		LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex + 1);
-	}
-	else
-	{
-		LLIMModel::instance().getMessagesSilently(mSessionID, messages, mLastMessageIndex + 1);
-	}
+    LLIMModel::instance().getMessages(
+    		mSessionID, messages, mLastMessageIndex + 1, hasFocus());
 
 	if (messages.size())
 	{
-		bool is_p2p_chat = (mDialog == IM_SESSION_P2P_INVITE || mDialog == IM_NOTHING_SPECIAL);
-		LLSD chat_args;
-		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
-		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
-		chat_args["show_names_for_p2p_conv"] = (!is_p2p_chat) || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
-
 		std::ostringstream message;
 		std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
 		std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
@@ -858,7 +865,7 @@ void LLIMFloater::updateMessages()
 				chat.mText = message;
 			}
 
-			mChatHistory->appendMessage(chat, chat_args);
+			appendMessage(chat);
 			mLastMessageIndex = msg["index"].asInteger();
 
 			// if it is a notification - next message is a notification history log, so skip it
@@ -1014,7 +1021,7 @@ void LLIMFloater::processAgentListUpdates(const LLSD& body)
 	}
 }
 
-void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue)
+void LLIMFloater::processChatHistoryStyleUpdate()
 {
 	LLFontGL* font = LLViewerChat::getChatFont();
 	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 03f52fb316..4cbdaccea5 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -27,12 +27,13 @@
 #ifndef LL_IMFLOATER_H
 #define LL_IMFLOATER_H
 
+#include "llimview.h"
 #include "llinstantmessage.h"
 #include "lllogchat.h"
 #include "lltooldraganddrop.h"
-#include "lltransientdockablefloater.h"
 #include "llvoicechannel.h"
 #include "llvoiceclient.h"
+#include "lltransientdockablefloater.h"
 
 class LLAvatarName;
 class LLButton;
@@ -47,7 +48,7 @@ class LLInventoryCategory;
  * optionally "docked" to the bottom tray.
  */
 class LLIMFloater
-	: public LLTransientDockableFloater
+    : public LLTransientDockableFloater
 	, public LLVoiceClientStatusObserver
 {
 	LOG_CLASS(LLIMFloater);
@@ -109,7 +110,7 @@ public:
 	void processAgentListUpdates(const LLSD& body);
 	void processSessionUpdate(const LLSD& session_update);
 
-	static void processChatHistoryStyleUpdate(const LLSD& newvalue);
+	static void processChatHistoryStyleUpdate();
 
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
 			BOOL drop, EDragAndDropType cargo_type,
@@ -153,7 +154,7 @@ private:
 
 	BOOL isInviteAllowed() const;
 	BOOL inviteToSession(const uuid_vec_t& agent_ids);
-
+	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
 	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
 	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
@@ -186,11 +187,13 @@ private:
 
 	LLPanelChatControlPanel* mControlPanel;
 	LLUUID mSessionID;
+	LLIMModel::LLIMSession* mSession;
 	S32 mLastMessageIndex;
 
+	LLChatHistory* mChatHistory;
+
 	EInstantMessage mDialog;
 	LLUUID mOtherParticipantUUID;
-	LLChatHistory* mChatHistory;
 	LLLineEditor* mInputEditor;
 	bool mPositioned;
 
@@ -199,6 +202,7 @@ private:
 	bool mMeTyping;
 	bool mOtherTyping;
 	bool mShouldSendTypingState;
+	bool mIsP2PChat;
 	LLFrameTimer mTypingTimer;
 	LLFrameTimer mTypingTimeoutTimer;
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a7c4618fa4..18d39b7aa4 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -716,6 +716,16 @@ bool LLIMModel::clearSession(const LLUUID& session_id)
 	return true;
 }
 
+void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index, const bool sendNoUnreadMsgs)
+{
+	getMessagesSilently(session_id, messages, start_index);
+
+	if (sendNoUnreadMsgs)
+	{
+		sendNoUnreadMessages(session_id);
+	}
+}
+
 void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
 {
 	LLIMSession* session = findIMSession(session_id);
@@ -757,13 +767,6 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id)
 	mNoUnreadMsgsSignal(arg);
 }
 
-void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
-{
-	getMessagesSilently(session_id, messages, start_index);
-
-	sendNoUnreadMessages(session_id);
-}
-
 bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) {
 	
 	LLIMSession* session = findIMSession(session_id);
@@ -2497,6 +2500,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 			gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
 		}
 		// log message to file
+
 		else
 		{
 			std::string session_name;
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 7c2cd03d97..9d19af4b62 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -191,12 +191,6 @@ public:
 	 */
 	bool clearSession(const LLUUID& session_id);
 
-	/**
-	 * Populate supplied std::list with messages starting from index specified by start_index without
-	 * emitting no unread messages signal.
-	 */
-	void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
-
 	/**
 	 * Sends no unread messages signal.
 	 */
@@ -205,7 +199,7 @@ public:
 	/**
 	 * Populate supplied std::list with messages starting from index specified by start_index
 	 */
-	void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
+	void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0, const bool sendNoUnreadMsgs = true);
 
 	/**
 	 * Add a message to an IM Model - the message is saved in a message store associated with a session specified by session_id
@@ -287,6 +281,12 @@ public:
 
 private:
 	
+	/**
+	 * Populate supplied std::list with messages starting from index specified by start_index without
+	 * emitting no unread messages signal.
+	 */
+	void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
+
 	/**
 	 * Add message to a list of message associated with session specified by session_id
 	 */
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 3a43750408..3c4b0b9aae 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -25,7 +25,6 @@
  */
 
 #include "llviewerprecompiledheaders.h"
-
 #include "llnearbychat.h"
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
@@ -55,8 +54,42 @@
 #include "llfloaterreg.h"
 #include "lltrans.h"
 
-static const S32 RESIZE_BAR_THICKNESS = 3;
+// --- 2 functions in the global namespace :( ---
+bool isWordsName(const std::string& name)
+{
+	// checking to see if it's display name plus username in parentheses
+	S32 open_paren = name.find(" (", 0);
+	S32 close_paren = name.find(')', 0);
+
+	if (open_paren != std::string::npos &&
+		close_paren == name.length()-1)
+	{
+		return true;
+	}
+	else
+	{
+		//checking for a single space
+		S32 pos = name.find(' ', 0);
+		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
+	}
+}
+
+std::string appendTime()
+{
+	time_t utc_time;
+	utc_time = time_corrected();
+	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+		+LLTrans::getString("TimeMin")+"]";
+
+	LLSD substitution;
+
+	substitution["datetime"] = (S32) utc_time;
+	LLStringUtil::format (timeStr, substitution);
 
+	return timeStr;
+}
+
+static const S32 RESIZE_BAR_THICKNESS = 3;
 
 static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat");
 
@@ -90,41 +123,32 @@ BOOL LLNearbyChat::postBuild()
 	return true;
 }
 
-std::string appendTime()
-{
-	time_t utc_time;
-	utc_time = time_corrected();
-	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
-		+LLTrans::getString("TimeMin")+"]";
-
-	LLSD substitution;
-
-	substitution["datetime"] = (S32) utc_time;
-	LLStringUtil::format (timeStr, substitution);
-
-	return timeStr;
-}
-
 
-void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args)
 {
 	LLChat& tmp_chat = const_cast<LLChat&>(chat);
 
 	if(tmp_chat.mTimeStr.empty())
 		tmp_chat.mTimeStr = appendTime();
 
-	bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory");
-	
 	if (!chat.mMuted)
 	{
 		tmp_chat.mFromName = chat.mFromName;
-		LLSD chat_args = args;
-		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
-		chat_args["show_time"] = true;
-		chat_args["show_names_for_p2p_conv"] = true;
+		LLSD chat_args;
+		if (args) chat_args = args;
+		chat_args["use_plain_text_chat_history"] =
+				gSavedSettings.getBOOL("PlainTextChatHistory");
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] = false
+				|| gSavedSettings.getBOOL("IMShowNamesForP2PConv");
 
 		mChatHistory->appendMessage(chat, chat_args);
 	}
+}
+
+void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+{
+	appendMessage(chat, args);
 
 	if(archive)
 	{
@@ -133,12 +157,9 @@ void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
 			mMessageArchive.erase(mMessageArchive.begin());
 	}
 
-	if (args["do_not_log"].asBoolean()) 
-	{
-		return;
-	}
-
-	if (gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
+	// logging
+	if (!args["do_not_log"].asBoolean()
+			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
 	{
 		std::string from_name = chat.mFromName;
 
@@ -165,10 +186,10 @@ void LLNearbyChat::onNearbySpeakers()
 	LLFloaterSidePanelContainer::showPanel("people", "panel_people", param);
 }
 
-
 void	LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
 {
 }
+
 bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
 {
 	std::string str = userdata.asString();
@@ -216,7 +237,7 @@ void LLNearbyChat::updateChatHistoryStyle()
 }
 
 //static 
-void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)
+void LLNearbyChat::processChatHistoryStyleUpdate()
 {
 	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
 	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
@@ -224,25 +245,6 @@ void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)
 		nearby_chat->updateChatHistoryStyle();
 }
 
-bool isWordsName(const std::string& name)
-{
-	// checking to see if it's display name plus username in parentheses 
-	S32 open_paren = name.find(" (", 0);
-	S32 close_paren = name.find(')', 0);
-
-	if (open_paren != std::string::npos &&
-		close_paren == name.length()-1)
-	{
-		return true;
-	}
-	else
-	{
-		//checking for a single space
-		S32 pos = name.find(' ', 0);
-		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
-	}
-}
-
 void LLNearbyChat::loadHistory()
 {
 	LLSD do_not_log;
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 7c5975cbc5..47f4de1c6d 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -34,7 +34,8 @@
 class LLResizeBar;
 class LLChatHistory;
 
-class LLNearbyChat: public LLPanel
+class LLNearbyChat
+: public LLPanel
 {
 public:
 	LLNearbyChat(const Params& p = LLPanel::getDefaultParams());
@@ -57,7 +58,7 @@ public:
 	
 	virtual void updateChatHistoryStyle();
 
-	static void processChatHistoryStyleUpdate(const LLSD& newvalue);
+	static void processChatHistoryStyleUpdate();
 
 	void loadHistory();
 
@@ -67,7 +68,8 @@ public:
 private:
 
 	void	getAllowedRect		(LLRect& rect);
-
+	// prepare chat's params and out one message to chatHistory
+	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	void	onNearbySpeakers	();
 
 
-- 
cgit v1.2.3


From acbce3248987d7e71be0fa0a251879c4066d9042 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 18 May 2012 02:04:22 +0300
Subject: CHUI-105 WIP Minor code clean up and optimization. Removed overloaded
 updateTitleButtons() and moved its functionality to a new method that should
 be called less frequently.

---
 indra/newview/llimfloater.cpp | 120 +++++++++++++++++++-----------------------
 indra/newview/llimfloater.h   |   9 ++--
 2 files changed, 61 insertions(+), 68 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index c6608337c8..981250d223 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -65,6 +65,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
 	mInputEditor(NULL),
+	mCloseBtn(NULL),
 	mExpandCollapseBtn(NULL),
 	mTearOffBtn(NULL),
 	mSavedTitle(),
@@ -192,6 +193,8 @@ void LLIMFloater::onOpen(const LLSD& key)
 		// Show the messages pane when opening a floater hosted in the Conversations
 		host_floater->collapseMessagesPane(false);
 	}
+
+	updateHeaderAndToolbar();
 }
 
 // virtual
@@ -308,7 +311,8 @@ BOOL LLIMFloater::postBuild()
 
 	boundVoiceChannel();
 
-	getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
+	mCloseBtn = getChild<LLButton>("close_btn");
+	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
 
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
@@ -328,7 +332,7 @@ BOOL LLIMFloater::postBuild()
 	}
 
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
-	mTearOffBtn->setCommitCallback(boost::bind(&LLFloater::onClickTearOff, this));
+	mTearOffBtn->setCommitCallback(boost::bind(&LLIMFloater::onTearOffClicked, this));
 
 	mInputEditor = getChild<LLLineEditor>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
@@ -391,10 +395,11 @@ BOOL LLIMFloater::postBuild()
 	}
 }
 
-void LLIMFloater::onTearOffClicked(LLIMFloater* self)
+void LLIMFloater::onTearOffClicked()
 {
-	onClickTearOff(self);
-	updateTitleButtons();
+	onClickTearOff(this);
+
+	updateHeaderAndToolbar();
 }
 
 void LLIMFloater::boundVoiceChannel()
@@ -1256,6 +1261,51 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 	}
 }
 
+void LLIMFloater::updateHeaderAndToolbar()
+{
+	bool is_hosted = getHost() != NULL;
+
+	if (is_hosted)
+	{
+		for (S32 i = 0; i < BUTTON_COUNT; i++)
+		{
+			if (!mButtons[i])
+			{
+				continue;
+			}
+
+			// Hide the standard header buttons in a docked IM floater.
+			mButtons[i]->setVisible(false);
+		}
+	}
+
+	// Display collapse image (<<) if the floater is hosted
+	// or if it is torn off but has an open control panel.
+	bool is_expanded = is_hosted || (mControlPanel && mControlPanel->getParent()->getVisible());
+	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
+	if (session)
+	{
+		// The button (>>) should be disabled for torn off P2P conversations.
+		mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType());
+	}
+	else
+	{
+		llwarns << "IM session not found." << llendl;
+	}
+
+	if (mDragHandle)
+	{
+		// toggle floater's drag handle and title visibility
+		mDragHandle->setVisible(!is_hosted);
+	}
+
+	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
+
+	mCloseBtn->setVisible(is_hosted);
+}
+
 // static
 void LLIMFloater::closeHiddenIMToasts()
 {
@@ -1376,63 +1426,3 @@ void LLIMFloater::onClickCloseBtn()
 
 	LLFloater::onClickCloseBtn();
 }
-
-// virtual
-void LLIMFloater::updateTitleButtons()
-{
-	// This gets called before LLIMFloater::postBuild() while some LLIMFloater members are NULL
-	if (   !mDragHandle
-		//|| !mControlPanel
-		|| !mExpandCollapseBtn
-		|| !mTearOffBtn)
-	{
-		return;
-	}
-
-	bool is_hosted = getHost() != NULL;
-
-	if (is_hosted) ///< floater is hosted
-	{
-		for (S32 i = 0; i < BUTTON_COUNT; i++)
-		{
-			if (!mButtons[i])
-			{
-				continue;
-			}
-
-			// Hide the standard header buttons in a docked IM floater.
-			mButtons[i]->setVisible(false);
-		}
-
-		mExpandCollapseBtn->setImageOverlay(getString("collapse_icon"));
-
-	}
-	else ///< floater is torn off
-	{
-		LLFloater::updateTitleButtons();
-
-		if (mControlPanel)
-		{
-			bool is_expanded = mControlPanel->getParent()->getVisible();
-			mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
-		}
-	}
-
-	getChild<LLButton>("close_btn")->setVisible(is_hosted);
-
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
-	if (session)
-	{
-		mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType());
-	}
-	else
-	{
-		llwarns << "Empty session." << llendl;
-		return;
-	}
-
-	// toggle floater's drag handle and title visibility
-	mDragHandle->setVisible(!is_hosted);
-
-	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
-}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 4cbdaccea5..8e7ab4cc21 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -134,15 +134,12 @@ public:
 
 protected:
 	/* virtual */ void onClickCloseBtn();
-	/* virtual */ void updateTitleButtons();
 
 private:
 	// process focus events to set a currently active session
 	/* virtual */ void onFocusLost();
 	/* virtual */ void onFocusReceived();
 
-	void onTearOffClicked(LLIMFloater *self);
-
 	// Update the window title, input field help text, etc.
 	void updateSessionName(const std::string& ui_title, const std::string& ui_label);
 
@@ -163,6 +160,8 @@ private:
 	static void* createPanelGroupControl(void* userdata);
 	static void* createPanelAdHocControl(void* userdata);
 
+	void onTearOffClicked();
+
 	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
@@ -181,6 +180,9 @@ private:
 	// Remove the "User is typing..." indicator.
 	void removeTypingIndicator(const LLIMInfo* im_info = NULL);
 
+	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
+	void updateHeaderAndToolbar();
+
 	static void closeHiddenIMToasts();
 
 	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
@@ -212,6 +214,7 @@ private:
 	// connection to voice channel state change signal
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
 
+	LLButton* mCloseBtn;
 	LLButton* mExpandCollapseBtn;
 	LLButton* mTearOffBtn;
 };
-- 
cgit v1.2.3


From a572f31ffb79ddfd61bcbb4b6fcb79bfa796d191 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 18 May 2012 20:50:50 +0300
Subject: CHUI-121 FIXED showing chat participants list only in torn off IM
 floaters.

---
 indra/newview/llimfloater.cpp | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 981250d223..97f59f9a15 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -1279,9 +1279,17 @@ void LLIMFloater::updateHeaderAndToolbar()
 		}
 	}
 
+	bool is_control_panel_visible = false;
+	if (mControlPanel)
+	{
+		// Control panel should be visible only in torn off floaters.
+		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
+		mControlPanel->getParent()->setVisible(is_control_panel_visible);
+	}
+
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
-	bool is_expanded = is_hosted || (mControlPanel && mControlPanel->getParent()->getVisible());
+	bool is_expanded = is_hosted || is_control_panel_visible;
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
 
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
-- 
cgit v1.2.3


From 296e55c1b323c05b6544b69ace04afe19102396b Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 18 May 2012 13:20:32 -0700
Subject: CHUI-112 FIX Clicking Show or Discard in an inventory offer toast
 does not dismiss toast removed special case logic for dealing with user
 online/offline collisions added ability to cancel old duplicate notifications

---
 indra/llui/llnotifications.cpp                     | 135 +++--
 indra/llui/llnotifications.h                       |  24 +-
 indra/llui/llnotificationtemplate.h                |  10 +-
 indra/newview/llavataractions.cpp                  |   1 -
 indra/newview/llcallingcard.cpp                    |   6 +-
 indra/newview/llchathistory.cpp                    |  30 +-
 indra/newview/llchatitemscontainerctrl.cpp         |   1 -
 indra/newview/llchatitemscontainerctrl.h           |   2 +-
 indra/newview/llimfloater.cpp                      |   1 +
 indra/newview/llnearbychathandler.cpp              |  70 +--
 indra/newview/llnotificationgrouphandler.cpp       |  11 -
 indra/newview/llnotificationhandler.h              |  21 +-
 indra/newview/llnotificationhandlerutil.cpp        |  68 +--
 indra/newview/llnotificationofferhandler.cpp       | 124 ++--
 indra/newview/llnotificationscripthandler.cpp      |  16 +-
 indra/newview/llnotificationtiphandler.cpp         |  15 -
 indra/newview/llscreenchannel.cpp                  | 104 ++--
 indra/newview/llscreenchannel.h                    |   8 +-
 indra/newview/lltoast.h                            |   7 +-
 indra/newview/lltoastimpanel.h                     |  10 +-
 indra/newview/lltoastnotifypanel.cpp               | 660 +++++++++++----------
 indra/newview/lltoastnotifypanel.h                 |  28 +-
 indra/newview/lltoastpanel.cpp                     |  11 +-
 indra/newview/lltoastpanel.h                       |   8 +-
 indra/newview/llviewermessage.cpp                  |  41 +-
 .../newview/skins/default/xui/en/notifications.xml |  22 +-
 indra/newview/skins/default/xui/en/strings.xml     |   2 +
 27 files changed, 721 insertions(+), 715 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 9ef9b4bbec..663749b983 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -60,7 +60,8 @@ void NotificationPriorityValues::declareValues()
 }
 
 LLNotificationForm::FormElementBase::FormElementBase()
-:	name("name")
+:	name("name"),
+	enabled("enabled", true)
 {}
 
 LLNotificationForm::FormIgnore::FormIgnore()
@@ -210,6 +211,14 @@ LLNotificationForm::LLNotificationForm()
 {
 }
 
+LLNotificationForm::LLNotificationForm( const LLNotificationForm& other )
+{
+	mFormData 	   = other.mFormData;
+	mIgnore 	   = other.mIgnore;
+	mIgnoreMsg 	   = other.mIgnoreMsg;
+	mIgnoreSetting = other.mIgnoreSetting;
+	mInvertSetting = other.mInvertSetting;
+}
 
 LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotificationForm::Params& p) 
 :	mIgnore(IGNORE_NO),
@@ -300,7 +309,7 @@ LLSD LLNotificationForm::getElement(const std::string& element_name)
 }
 
 
-bool LLNotificationForm::hasElement(const std::string& element_name)
+bool LLNotificationForm::hasElement(const std::string& element_name) const
 {
 	for (LLSD::array_const_iterator it = mFormData.beginArray();
 		it != mFormData.endArray();
@@ -311,7 +320,36 @@ bool LLNotificationForm::hasElement(const std::string& element_name)
 	return false;
 }
 
-void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value)
+bool LLNotificationForm::getElementEnabled(const std::string& element_name) const
+{
+	for (LLSD::array_const_iterator it = mFormData.beginArray();
+		it != mFormData.endArray();
+		++it)
+	{
+		if ((*it)["name"].asString() == element_name)
+		{
+			return (*it)["enabled"].asBoolean();
+		}
+	}
+
+	return false;
+}
+
+void LLNotificationForm::setElementEnabled(const std::string& element_name, bool enabled)
+{
+	for (LLSD::array_iterator it = mFormData.beginArray();
+		it != mFormData.endArray();
+		++it)
+	{
+		if ((*it)["name"].asString() == element_name)
+		{
+			(*it)["enabled"] = enabled;
+		}
+	}
+}
+
+
+void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value, bool enabled)
 {
 	LLSD element;
 	element["type"] = type;
@@ -319,6 +357,7 @@ void LLNotificationForm::addElement(const std::string& type, const std::string&
 	element["text"] = name;
 	element["value"] = value;
 	element["index"] = mFormData.size();
+	element["enabled"] = enabled;
 	mFormData.append(element);
 }
 
@@ -412,7 +451,8 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 	mPersist(p.persist),
 	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()),
 	mLogToChat(p.log_to_chat),
-	mLogToIM(p.log_to_im)
+	mLogToIM(p.log_to_im),
+	mShowToast(p.show_toast)
 {
 	if (p.sound.isProvided()
 		&& LLUI::sSettingGroups["config"]->controlExists(p.sound))
@@ -571,7 +611,6 @@ void LLNotification::updateFrom(LLNotificationPtr other)
 	mRespondedTo = other->mRespondedTo;
 	mResponse = other->mResponse;
 	mTemporaryResponder = other->mTemporaryResponder;
-	mIsReusable = other->isReusable();
 
 	update();
 }
@@ -670,7 +709,7 @@ void LLNotification::respond(const LLSD& response)
 		return;
 	}
 
-	if (mTemporaryResponder && !isReusable())
+	if (mTemporaryResponder)
 	{
 		LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
 		mResponseFunctorName = "";
@@ -899,6 +938,11 @@ bool LLNotification::canLogToIM() const
 	return mTemplatep->mLogToIM;
 }
 
+bool LLNotification::canShowToast() const
+{
+	return mTemplatep->mShowToast;
+}
+
 bool LLNotification::hasFormElements() const
 {
 	return mTemplatep->mForm->getNumElements() != 0;
@@ -909,6 +953,17 @@ LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const
 	return mTemplatep->mCombineBehavior;
 }
 
+void LLNotification::updateForm( const LLNotificationFormPtr& form )
+{
+	mForm = form;
+}
+
+void LLNotification::repost()
+{
+	mRespondedTo = false;
+	LLNotifications::instance().update(shared_from_this());
+}
+
 
 
 // =========================================================
@@ -1065,12 +1120,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 		if (wasFound)
 		{
 			abortProcessing = mChanged(payload);
-			// do not delete the notification to make LLChatHistory::appendMessage add notification panel to IM window
-			if( ! pNotification->isReusable() )
-			{
-				mItems.erase(pNotification);
-				onDelete(pNotification);
-			}
+			mItems.erase(pNotification);
+			onDelete(pNotification);
 		}
 	}
 	return abortProcessing;
@@ -1207,7 +1258,15 @@ bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif)
 		if (pNotif != existing_notification 
 			&& pNotif->isEquivalentTo(existing_notification))
 		{
-			return false;
+			if (pNotif->getCombineBehavior() == LLNotification::CANCEL_OLD)
+			{
+				cancel(existing_notification);
+				return true;
+			}
+			else
+			{
+				return false;
+			}
 		}
 	}
 
@@ -1247,26 +1306,35 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
 		return false;
 	}
 
-	if (pNotif->getCombineBehavior() == LLNotification::USE_NEWEST)
-	{
-	// Update the existing unique notification with the data from this particular instance...
-	// This guarantees that duplicate notifications will be collapsed to the one
-	// most recently triggered
-	for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
-		existing_it != mUniqueNotifications.end();
-		++existing_it)
+	switch(pNotif->getCombineBehavior())
 	{
-		LLNotificationPtr existing_notification = existing_it->second;
-		if (pNotif != existing_notification 
-			&& pNotif->isEquivalentTo(existing_notification))
+	case  LLNotification::REPLACE_WITH_NEW:
+		// Update the existing unique notification with the data from this particular instance...
+		// This guarantees that duplicate notifications will be collapsed to the one
+		// most recently triggered
+		for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
+			existing_it != mUniqueNotifications.end();
+			++existing_it)
 		{
-			// copy notification instance data over to oldest instance
-			// of this unique notification and update it
-			existing_notification->updateFrom(pNotif);
-			// then delete the new one
-			cancel(pNotif);
+			LLNotificationPtr existing_notification = existing_it->second;
+			if (pNotif != existing_notification 
+				&& pNotif->isEquivalentTo(existing_notification))
+			{
+				// copy notification instance data over to oldest instance
+				// of this unique notification and update it
+				existing_notification->updateFrom(pNotif);
+				// then delete the new one
+				cancel(pNotif);
+			}
 		}
-	}
+		break;
+	case LLNotification::KEEP_OLD:
+		break;
+	case LLNotification::CANCEL_OLD:
+		// already handled by filter logic
+		break;
+	default:
+		break;
 	}
 
 	return false;
@@ -1594,12 +1662,11 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
 	if (pNotif == NULL || pNotif->isCancelled()) return;
 
 	LLNotificationSet::iterator it=mItems.find(pNotif);
-	if (it == mItems.end())
+	if (it != mItems.end())
 	{
-		llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
+		pNotif->cancel();
+		updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
 	}
-	pNotif->cancel();
-	updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
 }
 
 void LLNotifications::cancelByName(const std::string& name)
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 21a4318aab..e9449eae69 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -165,6 +165,7 @@ public:
 	struct FormElementBase : public LLInitParam::Block<FormElementBase>
 	{
 		Optional<std::string>	name;
+		Optional<bool>			enabled;
 
 		FormElementBase();
 	};
@@ -234,16 +235,20 @@ public:
 	} EIgnoreType;
 
 	LLNotificationForm();
+	LLNotificationForm(const LLNotificationForm&);
 	LLNotificationForm(const LLSD& sd);
 	LLNotificationForm(const std::string& name, const Params& p);
 
+	void fromLLSD(const LLSD& sd);
 	LLSD asLLSD() const;
 
 	S32 getNumElements() { return mFormData.size(); }
 	LLSD getElement(S32 index) { return mFormData.get(index); }
 	LLSD getElement(const std::string& element_name);
-	bool hasElement(const std::string& element_name);
-	void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD());
+	bool hasElement(const std::string& element_name) const;
+	bool getElementEnabled(const std::string& element_name) const;
+	void setElementEnabled(const std::string& element_name, bool enabled);
+	void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD(), bool enabled = true);
 	void formatElements(const LLSD& substitutions);
 	// appends form elements from another form serialized as LLSD
 	void append(const LLSD& sub_form);
@@ -450,6 +455,11 @@ public:
 	// ["responseFunctor"] = name of registered functor that handles responses to notification;
 	LLSD asLLSD();
 
+	const LLNotificationFormPtr getForm();
+	void updateForm(const LLNotificationFormPtr& form);
+
+	void repost();
+
 	void respond(const LLSD& sd);
 	void respondWithDefault();
 
@@ -517,16 +527,18 @@ public:
     S32 getURLOpenExternally() const;
 	bool canLogToChat() const;
 	bool canLogToIM() const;
+	bool canShowToast() const;
 	bool hasFormElements() const;
 
 	typedef enum e_combine_behavior
 	{
-		USE_NEWEST,
-		USE_OLDEST
+		REPLACE_WITH_NEW,
+		KEEP_OLD,
+		CANCEL_OLD
+
 	} ECombineBehavior;
 	
 	ECombineBehavior getCombineBehavior() const;
-	const LLNotificationFormPtr getForm();
 
 	const LLDate getExpiration() const
 	{
@@ -545,8 +557,6 @@ public:
 
 	bool isReusable() { return mIsReusable; }
 
-	void setReusable(bool reusable) { mIsReusable = reusable; }
-	
 	// comparing two notifications normally means comparing them by UUID (so we can look them
 	// up quickly this way)
 	bool operator<(const LLNotification& rhs) const
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index f7d08ae1f4..ca9c4294c1 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -66,8 +66,9 @@ struct LLNotificationTemplate
 	{
 		static void declareValues()
 		{
-			declare("newest", LLNotification::USE_NEWEST);
-			declare("oldest", LLNotification::USE_OLDEST);
+			declare("replace_with_new", LLNotification::REPLACE_WITH_NEW);
+			declare("keep_old", LLNotification::KEEP_OLD);
+			declare("cancel_old", LLNotification::CANCEL_OLD);
 		}
 	};
 
@@ -109,7 +110,7 @@ struct LLNotificationTemplate
 
 		UniquenessConstraint()
 		:	contexts("context"),
-			combine("combine", LLNotification::USE_NEWEST),
+			combine("combine", LLNotification::REPLACE_WITH_NEW),
 			dummy_val("")
 		{}
 	};
@@ -185,6 +186,7 @@ struct LLNotificationTemplate
 		Mandatory<std::string>			name;
 		Optional<bool>					persist,
 										log_to_im,
+										show_toast,
 										log_to_chat;
 		Optional<std::string>			functor,
 										icon,
@@ -206,6 +208,7 @@ struct LLNotificationTemplate
 		:	name("name"),
 			persist("persist", false),
 			log_to_im("log_to_im", false),
+			show_toast("show_toast", true),
 			log_to_chat("log_to_chat", true),
 			functor("functor"),
 			icon("icon"),
@@ -313,6 +316,7 @@ struct LLNotificationTemplate
 	// inject these notifications into chat/IM streams
 	bool mLogToChat;
 	bool mLogToIM;
+	bool mShowToast;
 };
 
 #endif //LL_LLNOTIFICATION_TEMPLATE_H
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index ac14ec2cc0..aa626a9a30 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -1024,7 +1024,6 @@ void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::stri
 
 	LLSD payload;
 	payload["from_id"] = target_id;
-	payload["SUPPRESS_TOAST"] = true;
 	LLNotificationsUtil::add("FriendshipOffered", args, payload);
 }
 
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 0d55c4429a..60d60abd45 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -54,6 +54,7 @@
 #include "llresmgr.h"
 #include "llslurl.h"
 #include "llimview.h"
+#include "lltrans.h"
 #include "llviewercontrol.h"
 #include "llviewernetwork.h"
 #include "llviewerobjectlist.h"
@@ -723,12 +724,13 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
 	// Use display name only because this user is your friend
 	LLSD args;
 	args["NAME"] = av_name.mDisplayName;
+	args["STATUS"] = online ? LLTrans::getString("OnlineStatus") : LLTrans::getString("OfflineStatus");
 
 	LLNotificationPtr notification;
 	if (online)
 	{
 		notification =
-			LLNotificationsUtil::add("FriendOnline",
+			LLNotificationsUtil::add("FriendOnlineOffline",
 									 args,
 									 payload.with("respond_on_mousedown", TRUE),
 									 boost::bind(&LLAvatarActions::startIM, agent_id));
@@ -736,7 +738,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
 	else
 	{
 		notification =
-			LLNotificationsUtil::add("FriendOffline", args, payload);
+			LLNotificationsUtil::add("FriendOnlineOffline", args, payload);
 	}
 
 	// If there's an open IM session with this agent, send a notification there too.
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 5bdfb5adbc..3da868945b 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -877,35 +877,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		if (notification != NULL)
 		{
 			LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
-					notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history);
-			//we can't set follows in xml since it broke toasts behavior
-			notify_box->setFollowsLeft();
-			notify_box->setFollowsRight();
-			notify_box->setFollowsTop();
-
-			ctrl_list_t ctrls = notify_box->getControlPanel()->getCtrlList();
-			S32 offset = 0;
-			// Children were added by addChild() which uses push_front to insert them into list,
-			// so to get buttons in correct order reverse iterator is used (EXT-5906) 
-			for (ctrl_list_t::reverse_iterator it = ctrls.rbegin(); it != ctrls.rend(); it++)
-			{
-				LLButton * button = dynamic_cast<LLButton*> (*it);
-				if (button != NULL)
-				{
-					button->setOrigin( offset,
-							button->getRect().mBottom);
-					button->setLeftHPad(2 * HPAD);
-					button->setRightHPad(2 * HPAD);
-					// set zero width before perform autoResize()
-					button->setRect(LLRect(button->getRect().mLeft,
-							button->getRect().mTop, button->getRect().mLeft,
-							button->getRect().mBottom));
-					button->setAutoResize(true);
-					button->autoResize();
-					offset += HPAD + button->getRect().getWidth();
-					button->setFollowsNone();
-				}
-			}
+					notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor);
 
 			//Prepare the rect for the view
 			LLRect target_rect = mEditor->getDocumentView()->getRect();
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 9a84280f25..7477fbd656 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -372,7 +372,6 @@ void LLNearbyChatToastPanel::draw()
 		}
 		mIsDirty = false;
 	}
-	LLToastPanelBase::draw();
 }
 
 
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index 1d700dcede..89b0c4f37a 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -40,7 +40,7 @@ typedef enum e_show_item_header
 	CHATITEMHEADER_SHOW_BOTH
 } EShowItemHeader;
 
-class LLNearbyChatToastPanel: public LLToastPanelBase
+class LLNearbyChatToastPanel : public LLPanel
 {
 protected:
         LLNearbyChatToastPanel()
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index f67464078b..724ae3c25e 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -56,6 +56,7 @@
 #include "llrootview.h"
 #include "llspeakers.h"
 #include "llviewerchat.h"
+#include "llnotificationmanager.h"
 
 
 LLIMFloater::LLIMFloater(const LLUUID& session_id)
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 4d9db01e0d..f26cc85019 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file LLNearbyChatHandler.cpp
- * @brief Nearby chat notification managment
+ * @brief Nearby chat chat managment
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -47,15 +47,17 @@
 //add LLNearbyChatHandler to LLNotificationsUI namespace
 using namespace LLNotificationsUI;
 
-//-----------------------------------------------------------------------------------------------
-//LLNearbyChatScreenChannel
-//-----------------------------------------------------------------------------------------------	
-LLToastPanelBase* createToastPanel()
+static LLNearbyChatToastPanel* createToastPanel()
 {
 	LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
 	return item;
 }
 
+
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------	
+
 class LLNearbyChatScreenChannel: public LLScreenChannelBase
 {
 	LOG_CLASS(LLNearbyChatScreenChannel);
@@ -81,10 +83,10 @@ public:
 		}
 	}
 
-	void addNotification	(LLSD& notification);
+	void addChat	(LLSD& chat);
 	void arrangeToasts		();
 	
-	typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
+	typedef boost::function<LLNearbyChatToastPanel* (void )> create_toast_panel_callback_t;
 	void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
 
 	void onToastDestroyed	(LLToast* toast, bool app_quitting);
@@ -152,6 +154,8 @@ protected:
 	bool	mChannelRect;
 };
 
+
+
 //-----------------------------------------------------------------------------------------------
 // LLNearbyChatToast
 //-----------------------------------------------------------------------------------------------
@@ -255,7 +259,7 @@ void LLNearbyChatScreenChannel::updateToastFadingTime()
 
 bool	LLNearbyChatScreenChannel::createPoolToast()
 {
-	LLToastPanelBase* panel= m_create_toast_panel_callback_t();
+	LLNearbyChatToastPanel* panel= m_create_toast_panel_callback_t();
 	if(!panel)
 		return false;
 	
@@ -277,7 +281,7 @@ bool	LLNearbyChatScreenChannel::createPoolToast()
 	return true;
 }
 
-void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
+void LLNearbyChatScreenChannel::addChat(LLSD& chat)
 {
 	//look in pool. if there is any message
 	if(mStopProcessing)
@@ -289,8 +293,8 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
 
 	if(m_active_toasts.size())
 	{
-		LLUUID fromID = notification["from_id"].asUUID();		// agent id or object id
-		std::string from = notification["from"].asString();
+		LLUUID fromID = chat["from_id"].asUUID();		// agent id or object id
+		std::string from = chat["from"].asString();
 		LLToast* toast = m_active_toasts[0].get();
 		if (toast)
 		{
@@ -298,7 +302,7 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
   
 			if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText())
 			{
-				panel->addMessage(notification);
+				panel->addMessage(chat);
 				toast->reshapeToPanel();
 				toast->startTimer();
 	  
@@ -316,11 +320,11 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
 		LL_DEBUGS("NearbyChat") << "Empty pool" << llendl;
 		if(!createPoolToast())//created toast will go to pool. so next call will find it
 			return;
-		addNotification(notification);
+		addChat(chat);
 		return;
 	}
 
-	int chat_type = notification["chat_type"].asInteger();
+	int chat_type = chat["chat_type"].asInteger();
 	
 	if( ((EChatType)chat_type == CHAT_TYPE_DEBUG_MSG))
 	{
@@ -339,10 +343,10 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
 	m_toast_pool.pop_back();
 
 
-	LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
+	LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel());
 	if(!panel)
 		return;
-	panel->init(notification);
+	panel->init(chat);
 
 	toast->reshapeToPanel();
 	toast->startTimer();
@@ -488,23 +492,23 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
 
 	// Build notification data 
-	LLSD notification;
-	notification["message"] = chat_msg.mText;
-	notification["from"] = chat_msg.mFromName;
-	notification["from_id"] = chat_msg.mFromID;
-	notification["time"] = chat_msg.mTime;
-	notification["source"] = (S32)chat_msg.mSourceType;
-	notification["chat_type"] = (S32)chat_msg.mChatType;
-	notification["chat_style"] = (S32)chat_msg.mChatStyle;
+	LLSD chat;
+	chat["message"] = chat_msg.mText;
+	chat["from"] = chat_msg.mFromName;
+	chat["from_id"] = chat_msg.mFromID;
+	chat["time"] = chat_msg.mTime;
+	chat["source"] = (S32)chat_msg.mSourceType;
+	chat["chat_type"] = (S32)chat_msg.mChatType;
+	chat["chat_style"] = (S32)chat_msg.mChatStyle;
 	// Pass sender info so that it can be rendered properly (STORM-1021).
-	notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
+	chat["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
 
 	if (chat_msg.mChatType == CHAT_TYPE_DIRECT &&
 		chat_msg.mText.length() > 0 &&
 		chat_msg.mText[0] == '@')
 	{
 		// Send event on to LLEventStream and exit
-		sChatWatcher->post(notification);
+		sChatWatcher->post(chat);
 		return;
 	}
 
@@ -551,7 +555,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	}
 
 	// Send event on to LLEventStream
-	sChatWatcher->post(notification);
+	sChatWatcher->post(chat);
 
 
 	if( !chat_bar->isMinimized()
@@ -602,16 +606,16 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 		// Add a nearby chat toast.
 		LLUUID id;
 		id.generate();
-		notification["id"] = id;
+		chat["id"] = id;
 		std::string r_color_name = "White";
 		F32 r_color_alpha = 1.0f; 
 		LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
 		
-		notification["text_color"] = r_color_name;
-		notification["color_alpha"] = r_color_alpha;
-		notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
-		notification["message"] = toast_msg;
-		channel->addNotification(notification);	
+		chat["text_color"] = r_color_name;
+		chat["color_alpha"] = r_color_alpha;
+		chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
+		chat["message"] = toast_msg;
+		channel->addChat(chat);	
 	}
 }
 
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 6946b78cbf..18cd94e685 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -44,7 +44,6 @@ LLGroupHandler::LLGroupHandler()
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
 	if(channel)
 	{
-		channel->addOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
@@ -94,16 +93,6 @@ bool LLGroupHandler::processNotification(const LLNotificationPtr& notification)
 	return false;
 }
 
-//--------------------------------------------------------------------------
-void LLGroupHandler::onRejectToast(LLUUID& id)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(id);
-
-	if (notification && mItems.find(notification) != mItems.end())
-	{
-		LLNotifications::instance().cancel(notification);
-	}
-}
 
 //--------------------------------------------------------------------------
 
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 83d228e799..4d54bb78fc 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -95,16 +95,9 @@ public:
 	// base interface functions
 	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
 	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->killToastByNotificationID(p->getID());}
+	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
 
 	virtual bool processNotification(const LLNotificationPtr& notify)=0;
-
-protected :
-	static void init();
-	void removeExclusiveNotifications(const LLNotificationPtr& notif);
-
-	typedef std::list< std::set<std::string> > exclusive_notif_sets;
-	static exclusive_notif_sets sExclusiveNotificationGroups;
 };
 
 /**
@@ -148,7 +141,6 @@ public:
 	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	/*virtual*/ void onRejectToast(const LLUUID& id);
 	/*virtual*/ void initChannel();
 };
 
@@ -169,9 +161,6 @@ public:
 protected:
 	/*virtual*/ void onDeleteToast(LLToast* toast);
 	/*virtual*/ void initChannel();
-
-	// own handlers
-	void onRejectToast(LLUUID& id);
 };
 
 
@@ -190,9 +179,6 @@ public:
 
 protected:
 	virtual void initChannel();
-
-	// own handlers
-	void onRejectToast(LLUUID& id);
 };
 
 /**
@@ -225,15 +211,12 @@ public:
 	virtual ~LLOfferHandler();
 
 	// base interface functions
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ void onChange(LLNotificationPtr p);
 	/*virtual*/ void onDelete(LLNotificationPtr notification);
 	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	/*virtual*/ void initChannel();
-
-	// own handlers
-	void onRejectToast(LLUUID& id);
 };
 
 /**
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 1494ac6b5c..cba22b233b 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -41,75 +41,9 @@
 
 using namespace LLNotificationsUI;
 
-// static
-std::list< std::set<std::string> > LLSysHandler::sExclusiveNotificationGroups;
-
-// static
-void LLSysHandler::init()
-{
-	std::set<std::string> online_offline_group;
-	online_offline_group.insert("FriendOnline");
-	online_offline_group.insert("FriendOffline");
-
-	sExclusiveNotificationGroups.push_back(online_offline_group);
-}
-
 LLSysHandler::LLSysHandler(const std::string& name, const std::string& notification_type)
 :	LLNotificationChannel(name, "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
-{
-	if(sExclusiveNotificationGroups.empty())
-	{
-		init();
-	}
-}
-
-void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)
-{
-	LLScreenChannel* channel = dynamic_cast<LLScreenChannel *>(mChannel.get());
-	if (channel == NULL)
-	{
-		return;
-	}
-
-	class ExclusiveMatcher: public LLScreenChannel::Matcher
-	{
-	public:
-		ExclusiveMatcher(const std::set<std::string>& excl_group,
-				const std::string& from_name) :
-			mExclGroup(excl_group), mFromName(from_name)
-		{
-		}
-		bool matches(const LLNotificationPtr notification) const
-		{
-			for (std::set<std::string>::const_iterator it = mExclGroup.begin(); it
-					!= mExclGroup.end(); it++)
-			{
-				std::string from_name = LLHandlerUtil::getSubstitutionName(notification);
-				if (notification->getName() == *it && from_name == mFromName)
-				{
-					return true;
-				}
-			}
-			return false;
-		}
-	private:
-		const std::set<std::string>& mExclGroup;
-		const std::string& mFromName;
-	};
-
-
-	for (exclusive_notif_sets::iterator it = sExclusiveNotificationGroups.begin(); it
-			!= sExclusiveNotificationGroups.end(); it++)
-	{
-		std::set<std::string> group = *it;
-		std::set<std::string>::iterator g_it = group.find(notif->getName());
-		if (g_it != group.end())
-		{
-			channel->killMatchedToasts(ExclusiveMatcher(group,
-					LLHandlerUtil::getSubstitutionName(notif)));
-		}
-	}
-}
+{}
 
 // static
 bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 2112b0d35e..6e641575fa 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -48,7 +48,6 @@ LLOfferHandler::LLOfferHandler()
 	if(channel)
 	{
 		channel->setControlHovering(true);
-		channel->addOnRejectToastCallback(boost::bind(&LLOfferHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
@@ -81,92 +80,95 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 	}
 
 
-		if( notification->getPayload().has("give_inventory_notification")
+	if( notification->getPayload().has("give_inventory_notification")
 		&& notification->getPayload()["give_inventory_notification"].asBoolean() == false)
-		{
-			// This is an original inventory offer, so add a script floater
-			LLScriptFloaterManager::instance().onAddNotification(notification->getID());
-		}
-		else
-		{
+	{
+		// This is an original inventory offer, so add a script floater
+		LLScriptFloaterManager::instance().onAddNotification(notification->getID());
+	}
+	else
+	{
 		bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements();
 
-		notification->setReusable(add_notif_to_im);
-
-			LLUUID session_id;
 		if (add_notif_to_im)
-			{
-				const std::string name = LLHandlerUtil::getSubstitutionName(notification);
+		{
+			const std::string name = LLHandlerUtil::getSubstitutionName(notification);
 
-				LLUUID from_id = notification->getPayload()["from_id"];
+			LLUUID from_id = notification->getPayload()["from_id"];
 
-				session_id = LLHandlerUtil::spawnIMSession(name, from_id);
-				LLHandlerUtil::addNotifPanelToIM(notification);
-			}
+			LLHandlerUtil::spawnIMSession(name, from_id);
+			LLHandlerUtil::addNotifPanelToIM(notification);
+		}
 
-			if (notification->getPayload().has("SUPPRESS_TOAST")
-						&& notification->getPayload()["SUPPRESS_TOAST"])
-			{
-				LLNotificationsUtil::cancel(notification);
-			}
+		if (!notification->canShowToast())
+		{
+			LLNotificationsUtil::cancel(notification);
+		}
 		else if(!notification->canLogToIM() || !LLHandlerUtil::isIMFloaterOpened(notification))
-			{
-				LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
-				// don't close notification on panel destroy since it will be used by IM floater
-			notify_box->setCloseNotificationOnDestroy(!add_notif_to_im);
-				LLToast::Params p;
-				p.notif_id = notification->getID();
-				p.notification = notification;
-				p.panel = notify_box;
-				// we not save offer notifications to the syswell floater that should be added to the IM floater
+		{
+			LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+			LLToast::Params p;
+			p.notif_id = notification->getID();
+			p.notification = notification;
+			p.panel = notify_box;
+			// we not save offer notifications to the syswell floater that should be added to the IM floater
 			p.can_be_stored = !add_notif_to_im;
 
-				LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-				if(channel)
-					channel->addToast(p);
-			}
+			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+			if(channel)
+				channel->addToast(p);
+		}
 
 		if (notification->canLogToIM())
-			{
-				// log only to file if notif panel can be embedded to IM and IM is opened
+		{
+			// log only to file if notif panel can be embedded to IM and IM is opened
 			bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification);
 			LLHandlerUtil::logToIMP2P(notification, file_only);
-				}
-				}
+		}
+	}
 
 	return false;
-			}
+}
 
-/*virtual*/ void LLOfferHandler::onDelete(LLNotificationPtr notification)
+/*virtual*/ void LLOfferHandler::onChange(LLNotificationPtr p)
+{
+	LLToastNotifyPanel* panelp = LLToastNotifyPanel::getInstance(p->getID());
+	if (panelp)
 	{
-		if( notification->getPayload().has("give_inventory_notification")
-			&& !notification->getPayload()["give_inventory_notification"] )
+		//
+		// HACK: if we're dealing with a notification embedded in IM, update it
+		// otherwise remove its toast
+		//
+		if (dynamic_cast<LLIMToastNotifyPanel*>(panelp))
 		{
-			// Remove original inventory offer script floater
-			LLScriptFloaterManager::instance().onRemoveNotification(notification->getID());
+			panelp->updateNotification();
 		}
 		else
 		{
-		if (notification->canLogToIM() 
-			&& notification->hasFormElements()
-					&& !LLHandlerUtil::isIMFloaterOpened(notification))
-			{
-				LLHandlerUtil::decIMMesageCounter(notification);
-			}
-			mChannel.get()->killToastByNotificationID(notification->getID());
+			// if notification has changed, hide it
+			mChannel.get()->removeToastByNotificationID(p->getID());
 		}
 	}
+}
 
-//--------------------------------------------------------------------------
-void LLOfferHandler::onRejectToast(LLUUID& id)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(id);
 
-	if (notification
-		&& mItems.find(notification) != mItems.end()
-					// don't delete notification since it may be used by IM floater
-		&& (!notification->canLogToIM() || !notification->hasFormElements()))
+/*virtual*/ void LLOfferHandler::onDelete(LLNotificationPtr notification)
+{
+	if( notification->getPayload().has("give_inventory_notification")
+		&& !notification->getPayload()["give_inventory_notification"] )
+	{
+		// Remove original inventory offer script floater
+		LLScriptFloaterManager::instance().onRemoveNotification(notification->getID());
+	}
+	else
 	{
-		LLNotifications::instance().cancel(notification);
+		if (notification->canLogToIM() 
+			&& notification->hasFormElements()
+			&& !LLHandlerUtil::isIMFloaterOpened(notification))
+		{
+			LLHandlerUtil::decIMMesageCounter(notification);
+		}
+		mChannel.get()->removeToastByNotificationID(notification->getID());
 	}
 }
+
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 8472f9b2ae..9f7d0cc2f5 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -46,7 +46,6 @@ LLScriptHandler::LLScriptHandler()
 	if(channel)
 	{
 		channel->setControlHovering(true);
-		channel->addOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
@@ -116,7 +115,7 @@ void LLScriptHandler::onDelete( LLNotificationPtr notification )
 		}
 		else
 		{
-			mChannel.get()->killToastByNotificationID(notification->getID());
+			mChannel.get()->removeToastByNotificationID(notification->getID());
 		}
 	}
 
@@ -135,19 +134,6 @@ void LLScriptHandler::onDeleteToast(LLToast* toast)
 	}
 }
 
-//--------------------------------------------------------------------------
-void LLScriptHandler::onRejectToast(LLUUID& id)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(id);
-
-	if (notification && mItems.find(notification) != mItems.end())
-	{
-		LLNotifications::instance().cancel(notification);
-	}
-}
-
-//--------------------------------------------------------------------------
-
 
 
 
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 3588721849..a1d5db2e27 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -48,7 +48,6 @@ LLTipHandler::LLTipHandler()
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
 	if(channel)
 	{
-		channel->addOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
@@ -127,22 +126,8 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 	p.is_tip = true;
 	p.can_be_stored = false;
 		
-	removeExclusiveNotifications(notification);
-
 	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
 	if(channel)
 		channel->addToast(p);
 	return false;
 }
-
-//--------------------------------------------------------------------------
-
-void LLTipHandler::onRejectToast(const LLUUID& id)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(id);
-
-	if (notification && mItems.find(notification) != mItems.end())
-	{
-		LLNotifications::instance().cancel(notification);
-	}
-}
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 003b53b28c..839ca0f9c5 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -265,7 +265,14 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
 
 	if(!show_toast && !store_toast)
 	{
-		mRejectToastSignal(p.notif_id);
+		LLNotificationPtr notification = LLNotifications::instance().find(p.notif_id);
+
+		if (notification &&
+			(!notification->canLogToIM() || !notification->hasFormElements()))
+		{
+			// only cancel notification if it isn't being used in IM session
+			LLNotifications::instance().cancel(notification);
+		}
 		return;
 	}
 
@@ -431,35 +438,13 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
 	redrawToasts();
 }
 
-//--------------------------------------------------------------------------
-void LLScreenChannel::removeStoredToastByNotificationID(LLUUID id)
-{
-	// *TODO: may be remove this function
-	std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-
-	if( it == mStoredToastList.end() )
-		return;
-
-	const LLToast* toast = it->getToast();
-	if (toast)
-	{
-		mRejectToastSignal(toast->getNotificationID());
-	}
-
-	// Call find() once more, because the mStoredToastList could have been changed
-	// in mRejectToastSignal callback and the iterator could have become invalid.
-	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-	if (it != mStoredToastList.end())
-	{
-	mStoredToastList.erase(it);
-	}
-}
-
 //--------------------------------------------------------------------------
 void LLScreenChannel::killToastByNotificationID(LLUUID id)
 {
 	// searching among toasts on a screen
 	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
+	LLNotificationPtr notification = LLNotifications::instance().find(id);
+	if (!notification) return;
 	
 	if( it != mToastList.end())
 	{
@@ -472,42 +457,67 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)
 		//			the toast will be destroyed.
 		if(toast && toast->isNotificationValid())
 		{
-			mRejectToastSignal(toast->getNotificationID());
+			if (!notification->canLogToIM() || !notification->hasFormElements())
+			{
+				// only cancel notification if it isn't being used in IM session
+				LLNotifications::instance().cancel(notification);
+			}
 		}
 		else
 		{
-
-			deleteToast(toast);
-			mToastList.erase(it);
-			redrawToasts();
+			removeToastByNotificationID(id);
 		}
-		return;
 	}
-
-	// searching among stored toasts
-	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-
-	if( it != mStoredToastList.end() )
+	else
 	{
-		LLToast* toast = it->getToast();
-		if (toast)
+		// searching among stored toasts
+		it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+
+		if( it != mStoredToastList.end() )
+		{
+			LLToast* toast = it->getToast();
+			if (toast)
+			{
+				if (!notification->canLogToIM() || !notification->hasFormElements())
+				{
+					// only cancel notification if it isn't being used in IM session
+					LLNotifications::instance().cancel(notification);
+				}
+				deleteToast(toast);
+			}
+		}
+	
+		// Call find() once more, because the mStoredToastList could have been changed
+		// via notification cancellation and the iterator could have become invalid.
+		it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+		if (it != mStoredToastList.end())
 		{
-		// send signal to a listener to let him perform some action on toast rejecting
-		mRejectToastSignal(toast->getNotificationID());
-		deleteToast(toast);
+			mStoredToastList.erase(it);
+		}
 	}
 }
 
-	// Call find() once more, because the mStoredToastList could have been changed
-	// in mRejectToastSignal callback and the iterator could have become invalid.
-	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-	if (it != mStoredToastList.end())
+void LLScreenChannel::removeToastByNotificationID(LLUUID id)
+{
+	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
+	if( it != mToastList.end())
 	{
-		mStoredToastList.erase(it);
+		deleteToast(it->getToast());
+		mToastList.erase(it);
+		redrawToasts();
+	}
+	else
+	{
+		it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+		if (it != mStoredToastList.end())
+		{
+			deleteToast(it->getToast());
+			mStoredToastList.erase(it);
+		}
 	}
-
 }
 
+
 void LLScreenChannel::killMatchedToasts(const Matcher& matcher)
 {
 	std::list<const LLToast*> to_delete = findToasts(matcher);
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index eaff61a0f4..e5f4807ab7 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -84,6 +84,7 @@ public:
 	// kill or modify a toast by its ID
 	virtual void		killToastByNotificationID(LLUUID id) {};
 	virtual void		modifyToastNotificationByID(LLUUID id, LLSD data) {};
+	virtual void		removeToastByNotificationID(LLUUID id){};
 	
 	// hide all toasts from screen, but not remove them from a channel
 	virtual void		hideToastsFromScreen() {};
@@ -175,6 +176,7 @@ public:
 	void		addToast(const LLToast::Params& p);
 	// kill or modify a toast by its ID
 	void		killToastByNotificationID(LLUUID id);
+	void		removeToastByNotificationID(LLUUID id);
 	void		killMatchedToasts(const Matcher& matcher);
 	void		modifyToastByNotificationID(LLUUID id, LLPanel* panel);
 	// hide all toasts from screen, but not remove them from a channel
@@ -195,8 +197,6 @@ public:
 	void		loadStoredToastsToChannel();
 	// finds a toast among stored by its Notification ID and throws it on a screen to a channel
 	void		loadStoredToastByNotificationIDToChannel(LLUUID id);
-	// removes a toast from stored finding it by its Notification ID 
-	void		removeStoredToastByNotificationID(LLUUID id);
 	// removes from channel all toasts that belongs to the certain IM session 
 	void		removeToastsBySessionID(LLUUID id);
 	// remove all storable toasts from screen and store them
@@ -229,13 +229,9 @@ public:
 	// signal on storing of faded toasts event
 	typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_toast_signal_t;
 	boost::signals2::connection addOnStoreToastCallback(store_toast_signal_t::slot_type cb) { return mOnStoreToast.connect(cb); }
-	// signal on rejecting of a toast event
-	typedef boost::signals2::signal<void (LLUUID id)> reject_toast_signal_t;
-	boost::signals2::connection addOnRejectToastCallback(reject_toast_signal_t::slot_type cb) { return mRejectToastSignal.connect(cb); }
 
 private:
 	store_toast_signal_t mOnStoreToast;	
-	reject_toast_signal_t mRejectToastSignal; 
 
 	class ToastElem
 	{
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index e1d99b1bcb..ea62f758f8 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -169,6 +169,7 @@ public:
 	// get/set Toast's flags or states
 	// get information whether the notification corresponding to the toast is valid or not
 	bool isNotificationValid();
+
 	// get toast's Notification ID
 	const LLUUID getNotificationID() const { return mNotificationID;}
 	// get toast's Session ID
@@ -212,7 +213,7 @@ private:
 
 	//LLRootHandle<LLToast>	mHandle;
 		
-	LLPanel* mWrapperPanel;
+	LLPanel*	 mWrapperPanel;
 
 	// timer counts a lifetime of a toast
 	std::auto_ptr<LLToastLifeTimer> mTimer;
@@ -220,8 +221,8 @@ private:
 	F32			mToastLifetime; // in seconds
 	F32			mToastFadingTime; // in seconds
 	
-	LLPanel*		mPanel;
-	LLButton*		mHideBtn;
+	LLPanel*	mPanel;
+	LLButton*	mHideBtn;
 
 	LLColor4	mBgColor;
 	bool		mCanFade;
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index a803387576..279dd69bc7 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -41,11 +41,11 @@ public:
 	struct Params
 	{
 		LLNotificationPtr	notification;
-		LLUUID				avatar_id;
-		LLUUID				session_id;
-		std::string			from;
-		std::string			time;
-		std::string			message;
+		LLUUID				avatar_id,
+							session_id;
+		std::string			from,
+							time,
+							message;
 
 		Params() {}
 	};
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index dc5cc88dc4..77a5a5d17d 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -45,6 +45,9 @@
 const S32 BOTTOM_PAD = VPAD * 3;
 const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding
 S32 BUTTON_WIDTH = 90;
+// *TODO: magic numbers(???) - copied from llnotify.cpp(250)
+const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; 
+
 
 //static
 const LLFontGL* LLToastNotifyPanel::sFont = NULL;
@@ -52,171 +55,24 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
 
 LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
 
-LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) : 
-LLToastPanel(notification),
-mTextBox(NULL),
-mInfoPanel(NULL),
-mControlPanel(NULL),
-mNumOptions(0),
-mNumButtons(0),
-mAddedDefaultBtn(false),
-mCloseNotificationOnDestroy(true)
+LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) 
+:	LLToastPanel(notification),
+	LLInstanceTracker(notification->getID())
 {
-	buildFromFile( "panel_notification.xml");
-	if(rect != LLRect::null)
-	{
-		this->setShape(rect);
-	}		 
-	mInfoPanel = getChild<LLPanel>("info_panel");
-	mControlPanel = getChild<LLPanel>("control_panel");
-	BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
-	// customize panel's attributes
-	// is it intended for displaying a tip?
-	mIsTip = notification->getType() == "notifytip";
-	// is it a script dialog?
-	mIsScriptDialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
-	// is it a caution?
-	//
-	// caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
-	// notify xml template specifies that it is a caution
-	// tip-style notification handle 'caution' differently -they display the tip in a different color
-	mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
+	init(rect, show_images);
 
-	// setup parameters
-	// get a notification message
-	mMessage = notification->getMessage();
-	// init font variables
-	if (!sFont)
-	{
-		sFont = LLFontGL::getFontSansSerif();
-		sFontSmall = LLFontGL::getFontSansSerifSmall();
-	}
-	// initialize
-	setFocusRoot(!mIsTip);
-	// get a form for the notification
-	LLNotificationFormPtr form(notification->getForm());
-	// get number of elements
-	mNumOptions = form->getNumElements();
 
-	// customize panel's outfit
-	// preliminary adjust panel's layout
-	//move to the end 
-	//mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);
-
-	// adjust text options according to the notification type
-	// add a caution textbox at the top of a caution notification
-	if (mIsCaution && !mIsTip)
-	{
-		mTextBox = getChild<LLTextBox>("caution_text_box");
-	}
-	else
-	{
-		mTextBox = getChild<LLTextEditor>("text_editor_box"); 
-	}
-
-	// *TODO: magic numbers(???) - copied from llnotify.cpp(250)
-	const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; 
-
-	mTextBox->setMaxTextLength(MAX_LENGTH);
-	mTextBox->setVisible(TRUE);
-	mTextBox->setPlainText(!show_images);
-	mTextBox->setValue(notification->getMessage());
-
-	// add buttons for a script notification
-	if (mIsTip)
-	{
-		adjustPanelForTipNotice();
-	}
-	else
-	{
-		std::vector<index_button_pair_t> buttons;
-		buttons.reserve(mNumOptions);
-		S32 buttons_width = 0;
-		// create all buttons and accumulate they total width to reshape mControlPanel
-		for (S32 i = 0; i < mNumOptions; i++)
-		{
-			LLSD form_element = form->getElement(i);
-			if (form_element["type"].asString() != "button")
-			{
-				// not a button.
-				continue;
-			}
-			if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
-			{
-				// a textbox pretending to be a button.
-				continue;
-			}
-			LLButton* new_button = createButton(form_element, TRUE);
-			buttons_width += new_button->getRect().getWidth();
-			S32 index = form_element["index"].asInteger();
-			buttons.push_back(index_button_pair_t(index,new_button));
-		}
-		if (buttons.empty())
-		{
-			addDefaultButton();
-		}
-		else
-		{
-			const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
-			S32 button_panel_height = mControlPanel->getRect().getHeight();
-			//try get an average h_pad to spread out buttons
-			S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
-			if(h_pad < 2*HPAD)
-			{
-				/*
-				 * Probably it is a scriptdialog toast
-				 * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
-				 * In last case set default h_pad to avoid heaping of buttons 
-				 */
-				S32 button_per_row = button_panel_width / BUTTON_WIDTH;
-				h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1  because we do not need space after last button in a row   
-				if(h_pad < 2*HPAD) // still not enough space between buttons ?
-				{
-					h_pad = 2*HPAD;
-				}
-			}
-			if (mIsScriptDialog)
-			{
-				// we are using default width for script buttons so we can determinate button_rows
-				//to get a number of rows we divide the required width of the buttons to button_panel_width
-				S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
-				//S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
-				//reserve one row for the ignore_btn
-				button_rows++;
-				//calculate required panel height for scripdialog notification.
-				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
-			}
-			else
-			{
-				// in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
-				//S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
-				S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
-				//calculate required panel height 
-				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ BOTTOM_PAD;
-			}
-		
-			// we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
-			adjustPanelForScriptNotice(button_panel_width, button_panel_height);
-			updateButtonsLayout(buttons, h_pad);
-			// save buttons for later use in disableButtons()
-			mButtons.assign(buttons.begin(), buttons.end());
-		}
-	}
-	// adjust panel's height to the text size
-	mInfoPanel->setFollowsAll();
-	snapToMessageHeight(mTextBox, MAX_LENGTH);
-
-	if(notification->isReusable())
-	{
-		mButtonClickConnection = sButtonClickSignal.connect(
-			boost::bind(&LLToastNotifyPanel::onToastPanelButtonClicked, this, _1, _2));
-
-		if(notification->isRespondedTo())
-		{
-			// User selected an option in toast, now disable required buttons in IM window
-			disableRespondedOptions(notification);
-		}
-	}
+	//if(notification->isRespondedTo())
+	//{
+	//	// User selected an option in toast, now disable required buttons in IM window
+	//	disableRespondedOptions(notification);
+	//}
+	//
+	//if(notification->isReusable())
+	//{
+	//	mButtonClickConnection = sButtonClickSignal.connect(
+	//		boost::bind(&LLToastNotifyPanel::disableRespondedOptions, this, notification));
+	//}
 }
 void LLToastNotifyPanel::addDefaultButton()
 {
@@ -235,7 +91,6 @@ void LLToastNotifyPanel::addDefaultButton()
 }
 LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_option)
 {
-
 	InstanceAndS32* userdata = new InstanceAndS32;
 	userdata->mSelf = this;
 	userdata->mButtonName = is_option ? form_element["name"].asString() : "";
@@ -245,14 +100,15 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt
 	LLButton::Params p;
 	bool is_ignore_btn = form_element["index"].asInteger() == -1;
 	const LLFontGL* font = is_ignore_btn ? sFontSmall: sFont; // for ignore button in script dialog
-	p.name(form_element["name"].asString());
-	p.label(form_element["text"].asString());
-	p.font(font);
+	p.name = form_element["name"].asString();
+	p.label = form_element["text"].asString();
+	p.font = font;
 	p.rect.height = BTN_HEIGHT;
 	p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata));
 	p.rect.width = BUTTON_WIDTH;
 	p.auto_resize = false;
 	p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+	p.enabled = !form_element.has("enabled") || form_element["enabled"].asBoolean();
 	if (mIsCaution)
 	{
 		p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
@@ -287,14 +143,9 @@ LLToastNotifyPanel::~LLToastNotifyPanel()
 	mButtonClickConnection.disconnect();
 
 	std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
-	if (mCloseNotificationOnDestroy && LLNotificationsUtil::find(mNotification->getID()) != NULL)
+	if (mIsTip)
 	{
-		// let reusable notification be deleted
-		mNotification->setReusable(false);
-		if (!mNotification->isPersistent())
-		{
-			LLNotifications::getInstance()->cancel(mNotification);
-		}
+		LLNotifications::getInstance()->cancel(mNotification);
 	}
 }
 
@@ -393,103 +244,103 @@ void LLToastNotifyPanel::adjustPanelForTipNotice()
 	}
 }
 
-typedef std::set<std::string> button_name_set_t;
-typedef std::map<std::string, button_name_set_t> disable_button_map_t;
-
-disable_button_map_t initUserGiveItemDisableButtonMap()
-{
-	// see EXT-5905 for disable rules
-
-	disable_button_map_t disable_map;
-	button_name_set_t buttons;
-
-	buttons.insert("Show");
-	disable_map.insert(std::make_pair("Show", buttons));
-
-	buttons.insert("Discard");
-	disable_map.insert(std::make_pair("Discard", buttons));
-
-	buttons.insert("Mute");
-	disable_map.insert(std::make_pair("Mute", buttons));
-
-	return disable_map;
-}
-
-disable_button_map_t initTeleportOfferedDisableButtonMap()
-{
-	disable_button_map_t disable_map;
-	button_name_set_t buttons;
-
-	buttons.insert("Teleport");
-	buttons.insert("Cancel");
-
-	disable_map.insert(std::make_pair("Teleport", buttons));
-	disable_map.insert(std::make_pair("Cancel", buttons));
-
-	return disable_map;
-}
-
-disable_button_map_t initFriendshipOfferedDisableButtonMap()
-{
-	disable_button_map_t disable_map;
-	button_name_set_t buttons;
-
-	buttons.insert("Accept");
-	buttons.insert("Decline");
-
-	disable_map.insert(std::make_pair("Accept", buttons));
-	disable_map.insert(std::make_pair("Decline", buttons));
-
-	return disable_map;
-}
-
-button_name_set_t getButtonDisableList(const std::string& notification_name, const std::string& button_name)
-{
-	static disable_button_map_t user_give_item_disable_map = initUserGiveItemDisableButtonMap();
-	static disable_button_map_t teleport_offered_disable_map = initTeleportOfferedDisableButtonMap();
-	static disable_button_map_t friendship_offered_disable_map = initFriendshipOfferedDisableButtonMap();
-
-	disable_button_map_t::const_iterator it;
-	disable_button_map_t::const_iterator it_end;
-	disable_button_map_t search_map;
-
-	if("UserGiveItem" == notification_name)
-	{
-		search_map = user_give_item_disable_map;
-	}
-	else if("TeleportOffered" == notification_name)
-	{
-		search_map = teleport_offered_disable_map;
-	}
-	else if("OfferFriendship" == notification_name)
-	{
-		search_map = friendship_offered_disable_map;
-	}
-
-	it = search_map.find(button_name);
-	it_end = search_map.end();
-
-	if(it_end != it)
-	{
-		return it->second;
-	}
-	return button_name_set_t();
-}
-
-void LLToastNotifyPanel::disableButtons(const std::string& notification_name, const std::string& selected_button)
-{
-	button_name_set_t buttons = getButtonDisableList(notification_name, selected_button);
-
-	std::vector<index_button_pair_t>::const_iterator it = mButtons.begin();
-	for ( ; it != mButtons.end(); it++)
-	{
-		LLButton* btn = it->second;
-		if(buttons.find(btn->getName()) != buttons.end())
-		{
-			btn->setEnabled(FALSE);
-		}
-	}
-}
+//typedef std::set<std::string> button_name_set_t;
+//typedef std::map<std::string, button_name_set_t> disable_button_map_t;
+//
+//disable_button_map_t initUserGiveItemDisableButtonMap()
+//{
+//	// see EXT-5905 for disable rules
+//
+//	disable_button_map_t disable_map;
+//	button_name_set_t buttons;
+//
+//	buttons.insert("Show");
+//	disable_map.insert(std::make_pair("Show", buttons));
+//
+//	buttons.insert("Discard");
+//	disable_map.insert(std::make_pair("Discard", buttons));
+//
+//	buttons.insert("Mute");
+//	disable_map.insert(std::make_pair("Mute", buttons));
+//
+//	return disable_map;
+//}
+//
+//disable_button_map_t initTeleportOfferedDisableButtonMap()
+//{
+//	disable_button_map_t disable_map;
+//	button_name_set_t buttons;
+//
+//	buttons.insert("Teleport");
+//	buttons.insert("Cancel");
+//
+//	disable_map.insert(std::make_pair("Teleport", buttons));
+//	disable_map.insert(std::make_pair("Cancel", buttons));
+//
+//	return disable_map;
+//}
+//
+//disable_button_map_t initFriendshipOfferedDisableButtonMap()
+//{
+//	disable_button_map_t disable_map;
+//	button_name_set_t buttons;
+//
+//	buttons.insert("Accept");
+//	buttons.insert("Decline");
+//
+//	disable_map.insert(std::make_pair("Accept", buttons));
+//	disable_map.insert(std::make_pair("Decline", buttons));
+//
+//	return disable_map;
+//}
+//
+//button_name_set_t getButtonDisableList(const std::string& notification_name, const std::string& button_name)
+//{
+//	static disable_button_map_t user_give_item_disable_map = initUserGiveItemDisableButtonMap();
+//	static disable_button_map_t teleport_offered_disable_map = initTeleportOfferedDisableButtonMap();
+//	static disable_button_map_t friendship_offered_disable_map = initFriendshipOfferedDisableButtonMap();
+//
+//	disable_button_map_t::const_iterator it;
+//	disable_button_map_t::const_iterator it_end;
+//	disable_button_map_t search_map;
+//
+//	if("UserGiveItem" == notification_name)
+//	{
+//		search_map = user_give_item_disable_map;
+//	}
+//	else if("TeleportOffered" == notification_name)
+//	{
+//		search_map = teleport_offered_disable_map;
+//	}
+//	else if("OfferFriendship" == notification_name)
+//	{
+//		search_map = friendship_offered_disable_map;
+//	}
+//
+//	it = search_map.find(button_name);
+//	it_end = search_map.end();
+//
+//	if(it_end != it)
+//	{
+//		return it->second;
+//	}
+//	return button_name_set_t();
+//}
+
+//void LLToastNotifyPanel::disableButtons(const std::string& notification_name, const std::string& selected_button)
+//{
+	//button_name_set_t buttons = getButtonDisableList(notification_name, selected_button);
+
+	//std::vector<index_button_pair_t>::const_iterator it = mButtons.begin();
+	//for ( ; it != mButtons.end(); it++)
+	//{
+	//	LLButton* btn = it->second;
+	//	if(buttons.find(btn->getName()) != buttons.end())
+	//	{
+	//		btn->setEnabled(FALSE);
+	//	}
+	//}
+//}
 
 // static
 void LLToastNotifyPanel::onClickButton(void* data)
@@ -515,88 +366,263 @@ void LLToastNotifyPanel::onClickButton(void* data)
 		self->mNotification->setResponder(new_info);
 	}
 
+	// disable all buttons
+	self->mControlPanel->setEnabled(FALSE);
+
+	// this might repost notification with new form data/enabled buttons
 	self->mNotification->respond(response);
+}
 
-	if(is_reusable)
+void LLToastNotifyPanel::init( LLRect rect, bool show_images )
+{
+	deleteAllChildren();
+
+	mTextBox = NULL;
+	mInfoPanel = NULL;
+	mControlPanel = NULL;
+	mNumOptions = 0;
+	mNumButtons = 0;
+	mAddedDefaultBtn = false;
+
+	buildFromFile( "panel_notification.xml");
+	if(rect != LLRect::null)
 	{
-		sButtonClickSignal(self->mNotification->getID(), button_name);
+		this->setShape(rect);
+	}		 
+	mInfoPanel = getChild<LLPanel>("info_panel");
+	mInfoPanel->setFollowsAll();
+
+	mControlPanel = getChild<LLPanel>("control_panel");
+	BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
+	// customize panel's attributes
+	// is it intended for displaying a tip?
+	mIsTip = mNotification->getType() == "notifytip";
+	// is it a script dialog?
+	mIsScriptDialog = (mNotification->getName() == "ScriptDialog" || mNotification->getName() == "ScriptDialogGroup");
+	// is it a caution?
+	//
+	// caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
+	// notify xml template specifies that it is a caution
+	// tip-style notification handle 'caution' differently -they display the tip in a different color
+	mIsCaution = mNotification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
+
+	// setup parameters
+	// get a notification message
+	mMessage = mNotification->getMessage();
+	// init font variables
+	if (!sFont)
+	{
+		sFont = LLFontGL::getFontSansSerif();
+		sFontSmall = LLFontGL::getFontSansSerifSmall();
+	}
+	// initialize
+	setFocusRoot(!mIsTip);
+	// get a form for the notification
+	LLNotificationFormPtr form(mNotification->getForm());
+	// get number of elements
+	mNumOptions = form->getNumElements();
+
+	// customize panel's outfit
+	// preliminary adjust panel's layout
+	//move to the end 
+	//mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);
+
+	// adjust text options according to the notification type
+	// add a caution textbox at the top of a caution notification
+	if (mIsCaution && !mIsTip)
+	{
+		mTextBox = getChild<LLTextBox>("caution_text_box");
 	}
 	else
 	{
-		// disable all buttons
-		self->mControlPanel->setEnabled(FALSE);
+		mTextBox = getChild<LLTextEditor>("text_editor_box"); 
 	}
-}
 
-void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id, const std::string btn_name)
-{
-	if(mNotification->getID() == notification_id)
+	mTextBox->setMaxTextLength(MAX_LENGTH);
+	mTextBox->setVisible(TRUE);
+	mTextBox->setPlainText(!show_images);
+	mTextBox->setValue(mNotification->getMessage());
+
+	// add buttons for a script notification
+	if (mIsTip)
 	{
-		disableButtons(mNotification->getName(), btn_name);
+		adjustPanelForTipNotice();
 	}
-}
-
-void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification)
-{
-	LLSD response = notification->getResponse();
-	for (LLSD::map_const_iterator response_it = response.beginMap(); 
-		response_it != response.endMap(); ++response_it)
+	else
 	{
-		if (response_it->second.isBoolean() && response_it->second.asBoolean())
+		std::vector<index_button_pair_t> buttons;
+		buttons.reserve(mNumOptions);
+		S32 buttons_width = 0;
+		// create all buttons and accumulate they total width to reshape mControlPanel
+		for (S32 i = 0; i < mNumOptions; i++)
 		{
-			// that after multiple responses there can be many pressed buttons
-			// need to process them all
-			disableButtons(notification->getName(), response_it->first);
+			LLSD form_element = form->getElement(i);
+			if (form_element["type"].asString() != "button")
+			{
+				// not a button.
+				continue;
+			}
+			if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
+			{
+				// a textbox pretending to be a button.
+				continue;
+			}
+			LLButton* new_button = createButton(form_element, TRUE);
+			buttons_width += new_button->getRect().getWidth();
+			S32 index = form_element["index"].asInteger();
+			buttons.push_back(index_button_pair_t(index,new_button));
+		}
+		if (buttons.empty())
+		{
+			addDefaultButton();
+		}
+		else
+		{
+			const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
+			S32 button_panel_height = mControlPanel->getRect().getHeight();
+			//try get an average h_pad to spread out buttons
+			S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
+			if(h_pad < 2*HPAD)
+			{
+				/*
+				* Probably it is a scriptdialog toast
+				* for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
+				* In last case set default h_pad to avoid heaping of buttons 
+				*/
+				S32 button_per_row = button_panel_width / BUTTON_WIDTH;
+				h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1  because we do not need space after last button in a row   
+				if(h_pad < 2*HPAD) // still not enough space between buttons ?
+				{
+					h_pad = 2*HPAD;
+				}
+			}
+			if (mIsScriptDialog)
+			{
+				// we are using default width for script buttons so we can determinate button_rows
+				//to get a number of rows we divide the required width of the buttons to button_panel_width
+				S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
+				//S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
+				//reserve one row for the ignore_btn
+				button_rows++;
+				//calculate required panel height for scripdialog notification.
+				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
+			}
+			else
+			{
+				// in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
+				//S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
+				S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
+				//calculate required panel height 
+				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ BOTTOM_PAD;
+			}
+
+			// we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
+			adjustPanelForScriptNotice(button_panel_width, button_panel_height);
+			updateButtonsLayout(buttons, h_pad);
+			// save buttons for later use in disableButtons()
+			//mButtons.assign(buttons.begin(), buttons.end());
 		}
 	}
+	// adjust panel's height to the text size
+	snapToMessageHeight(mTextBox, MAX_LENGTH);
 }
 
 
+
+//void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id, const std::string btn_name)
+//{
+//	if(mNotification->getID() == notification_id)
+//	{
+//		disableButtons(mNotification->getName(), btn_name);
+//	}
+//}
+
+//void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification)
+//{
+//	LLSD response = notification->getResponse();
+//	for (LLSD::map_const_iterator response_it = response.beginMap(); 
+//		response_it != response.endMap(); ++response_it)
+//	{
+//		if (response_it->second.isBoolean() && response_it->second.asBoolean())
+//		{
+//			// that after multiple responses there can be many pressed buttons
+//			// need to process them all
+//			disableButtons(notification->getName(), response_it->first);
+//		}
+//	}
+//}
+
+
 //////////////////////////////////////////////////////////////////////////
 
 LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */,
-										   bool show_images /* = true */)
- : mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images)
+										   bool show_images /* = true */, LLTextBase* parent_text)
+:	mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images),
+	mParentText(parent_text)
 {
-	mTextBox->setFollowsAll();
+	compactButtons();
 }
 
 LLIMToastNotifyPanel::~LLIMToastNotifyPanel()
 {
-	// We shouldn't delete notification when IM floater exists
-	// since that notification will be reused by IM floater.
-	// This may happened when IM floater reloads messages, exactly when user
-	// changes layout of IM chat log(disable/enable plaintext mode).
-	// See EXT-6500
-	LLIMFloater* im_floater = LLIMFloater::findInstance(mSessionID);
-	if (im_floater != NULL && !im_floater->isDead())
-	{
-		mCloseNotificationOnDestroy = false;
-	}
 }
 
 void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
 {
-	S32 text_height = mTextBox->getTextBoundingRect().getHeight();
-	S32 widget_height = mTextBox->getRect().getHeight();
-	S32 delta = text_height - widget_height;
-	LLRect rc = getRect();
+	LLToastPanel::reshape(width, height, called_from_parent);
 
-	rc.setLeftTopAndSize(rc.mLeft, rc.mTop, width, height + delta);
-	height = rc.getHeight();
-	width = rc.getWidth();
+	snapToMessageHeight(mTextBox, MAX_LENGTH);
+}
 
-	bool is_width_changed = width != getRect().getWidth();
+void LLIMToastNotifyPanel::compactButtons()
+{
+	mTextBox->setFollowsAll();
 
-	LLToastPanel::reshape(width, height, called_from_parent);
+	//we can't set follows in xml since it broke toasts behavior
+	setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP);
 
-	// Notification height required to display the text message depends on
-	// the width of the text box thus if panel width is changed the text box
-	// width is also changed then reshape() is called to adjust proper height.
-	if (is_width_changed)
+	const child_list_t* children = getControlPanel()->getChildList();
+	S32 offset = 0;
+	// Children were added by addChild() which uses push_front to insert them into list,
+	// so to get buttons in correct order reverse iterator is used (EXT-5906) 
+	for (child_list_t::const_reverse_iterator it = children->rbegin(); it != children->rend(); it++)
 	{
-		reshape(width, height, called_from_parent);
+		LLButton * button = dynamic_cast<LLButton*> (*it);
+		if (button != NULL)
+		{
+			button->setOrigin( offset,button->getRect().mBottom);
+			button->setLeftHPad(2 * HPAD);
+			button->setRightHPad(2 * HPAD);
+			// set zero width before perform autoResize()
+			button->setRect(LLRect(button->getRect().mLeft,
+				button->getRect().mTop, 
+				button->getRect().mLeft,
+				button->getRect().mBottom));
+			button->setAutoResize(true);
+			button->autoResize();
+			offset += HPAD + button->getRect().getWidth();
+			button->setFollowsNone();
+		}
 	}
+
+	if (mParentText)
+	{
+		mParentText->needsReflow();
+	}
+}
+
+void LLIMToastNotifyPanel::updateNotification()
+{
+	init(LLRect(), true);
+}
+
+void LLIMToastNotifyPanel::init( LLRect rect, bool show_images )
+{
+	LLToastNotifyPanel::init(LLRect(), show_images);
+
+	compactButtons();
 }
 
+
 // EOF
+
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index db517ec858..f93c7745af 100644
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -47,7 +47,7 @@ class LLNotificationForm;
  * @deprecated this class will be removed after all toast panel types are
  *  implemented in separate classes.
  */
-class LLToastNotifyPanel: public LLToastPanel 
+class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID>
 {
 public:
 	/**
@@ -61,10 +61,14 @@ public:
 	 * implement right class for desired toast panel. @see LLGenericTipPanel as example.
 	 */
 	LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
+
+	virtual void init( LLRect rect, bool show_images );
+
 	virtual ~LLToastNotifyPanel();
 	LLPanel * getControlPanel() { return mControlPanel; }
 
-	void setCloseNotificationOnDestroy(bool close) { mCloseNotificationOnDestroy = close; }
+	virtual void updateNotification() {}
+
 protected:
 	LLButton* createButton(const LLSD& form_element, BOOL is_option);
 
@@ -76,8 +80,6 @@ protected:
 	};
 	std::vector<InstanceAndS32*> mBtnCallbackData;
 
-	bool mCloseNotificationOnDestroy;
-
 	typedef std::pair<int,LLButton*> index_button_pair_t; 
 	void adjustPanelForScriptNotice(S32 max_width, S32 max_height);
 	void adjustPanelForTipNotice();
@@ -93,9 +95,9 @@ protected:
 	/**
 	 * Disable specific button(s) based on notification name and clicked button
 	 */
-	void disableButtons(const std::string& notification_name, const std::string& selected_button);
+	//void disableButtons(const std::string& notification_name, const std::string& selected_button);
 
-	std::vector<index_button_pair_t> mButtons;
+	//std::vector<index_button_pair_t> mButtons;
 
 	// panel elements
 	LLTextBase*		mTextBox;
@@ -118,7 +120,7 @@ protected:
 	/**
 	 * Process response data. Will disable selected options
 	 */
-	void disableRespondedOptions(const LLNotificationPtr& notification);
+	//void disableRespondedOptions(const LLNotificationPtr& notification);
 
 	bool mIsTip;
 	bool mAddedDefaultBtn;
@@ -137,13 +139,23 @@ class LLIMToastNotifyPanel : public LLToastNotifyPanel
 {
 public:
 
-	LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect = LLRect::null, bool show_images = true);
+	LLIMToastNotifyPanel(LLNotificationPtr& pNotification, 
+						const LLUUID& session_id, 
+						const LLRect& rect = LLRect::null, 
+						bool show_images = true, 
+						LLTextBase* parent_text = NULL);
+
+	void compactButtons();
+
+	virtual void updateNotification();
+	virtual void init( LLRect rect, bool show_images );
 
 	~LLIMToastNotifyPanel();
 
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 
 protected:
+	LLTextBase* mParentText;
 	LLUUID	mSessionID;
 };
 
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index d2a4ce8745..e20d516392 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -78,11 +78,14 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 		S32 requiredTextHeight = message->getTextBoundingRect().getHeight();
 		S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
 
-		//Calculate last delta height deducting previous heightDelta 
-		heightDelta = newTextHeight - oldTextHeight - heightDelta;
+		heightDelta = newTextHeight - oldTextHeight;
+		S32 new_panel_height = llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT);
 
 		//reshape the panel with new height
-		reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT));
+		if (new_panel_height != getRect().getHeight())
+		{
+			reshape( getRect().getWidth(), new_panel_height);
+		}
 	}
 }
 
@@ -96,7 +99,7 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
 	if ("notifytip" == notification->getType())
 	{
 		// if it is online/offline notification
-		if ("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName())
+		if ("FriendOnlineOffline" == notification->getName())
 		{
 			res = new LLPanelOnlineStatus(notification);
 		}
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 346e014d73..c22557206b 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -33,19 +33,13 @@
 
 #include <string>
 
-class LLToastPanelBase: public LLPanel 
-{
-public:
-	virtual void init(LLSD& data){};
-};
-
 /**
  * Base class for all panels that can be added to the toast.
  * All toast panels should contain necessary logic for representing certain notification
  * but shouldn't contain logic related to this panel lifetime control and positioning
  * on the parent view.
  */
-class LLToastPanel: public LLPanel {
+class LLToastPanel : public LLPanel {
 public:
 	LLToastPanel(const LLNotificationPtr&);
 	virtual ~LLToastPanel() = 0;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index c2bafd043d..cefd9ef91d 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -179,6 +179,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	LLMessageSystem* msg = gMessageSystem;
 	const LLSD& payload = notification["payload"];
+	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
 
 	// add friend to recent people list
 	LLRecentPeople::instance().add(payload["from_id"]);
@@ -204,7 +205,6 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 		msg->sendReliable(LLHost(payload["sender"].asString()));
 
 		LLSD payload = notification["payload"];
-		payload["SUPPRESS_TOAST"] = true;
 		LLNotificationsUtil::add("FriendshipAcceptedByMe",
 				notification["substitutions"], payload);
 		break;
@@ -212,7 +212,6 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 	case 1: // Decline
 	{
 		LLSD payload = notification["payload"];
-		payload["SUPPRESS_TOAST"] = true;
 		LLNotificationsUtil::add("FriendshipDeclinedByMe",
 				notification["substitutions"], payload);
 	}
@@ -241,6 +240,12 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 		break;
 	}
 
+	LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+	modified_form->setElementEnabled("Accept", false);
+	modified_form->setElementEnabled("Decline", false);
+	notification_ptr->updateForm(modified_form);
+	notification_ptr->repost();
+
 	return false;
 }
 static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
@@ -1471,16 +1476,16 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 		itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
 	}
 	 
+	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+	llassert(notification_ptr != NULL);
+	
 	// For muting, we need to add the mute, then decline the offer.
 	// This must be done here because:
 	// * callback may be called immediately,
 	// * adding the mute sends a message,
 	// * we can't build two messages at once.
-	if (2 == button) // Block
+	if (IOR_MUTE == button) // Block
 	{
-		LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
-
-		llassert(notification_ptr != NULL);
 		if (notification_ptr != NULL)
 		{
 			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
@@ -1495,6 +1500,8 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	
 	bool busy = gAgent.getBusy();
 	
+	LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+
 	switch(button)
 	{
 	case IOR_SHOW:
@@ -1538,6 +1545,8 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
 			break;
 		}
+
+		modified_form->setElementEnabled("Show", false);
 		break;
 		// end switch (mIM)
 			
@@ -1550,9 +1559,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			args["MESSAGE"] = log_message;
 			LLNotificationsUtil::add("SystemMessageTip", args);
 		}
+
 		break;
 
 	case IOR_MUTE:
+		modified_form->setElementEnabled("Mute", false);
 		// MUTE falls through to decline
 	case IOR_DECLINE:
 		{
@@ -1588,6 +1599,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			{
 				busy_message(gMessageSystem, mFromID);
 			}
+
+			modified_form->setElementEnabled("Show", false);
+			modified_form->setElementEnabled("Discard", false);
+
 			break;
 		}
 	default:
@@ -1607,6 +1622,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	{
 		delete this;
 	}
+
+	notification_ptr->updateForm(modified_form);
+	notification_ptr->repost();
+
 	return false;
 }
 
@@ -1984,6 +2003,15 @@ bool lure_callback(const LLSD& notification, const LLSD& response)
 					   lure_id);
 		break;
 	}
+
+	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+	LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+	modified_form->setElementEnabled("Teleport", false);
+	modified_form->setElementEnabled("Cancel", false);
+	notification_ptr->updateForm(modified_form);
+	notification_ptr->repost();
+
 	return false;
 }
 static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
@@ -6394,7 +6422,6 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response)
 				
 				//*TODO please rewrite all keys to the same case, lower or upper
 				payload["from_id"] = target_id;
-				payload["SUPPRESS_TOAST"] = true;
 				LLNotificationsUtil::add("TeleportOfferSent", args, payload);
 
 				// Add the recepient to the recent people list.
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index d35cebbd16..5b7222c180 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5208,20 +5208,14 @@ Topic: [SUBJECT], Message: [MESSAGE]
 
   <notification
    icon="notifytip.tga"
-   name="FriendOnline"
+   name="FriendOnlineOffline"
    log_to_chat="false"
    type="notifytip">
     <tag>friendship</tag>
-&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Online
-  </notification>
-
-  <notification
-   icon="notifytip.tga"
-   name="FriendOffline"
-   log_to_chat="false"
-   type="notifytip">
-    <tag>friendship</tag>
-&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Offline
+&lt;nolink&gt;[NAME]&lt;/nolink&gt; is [STATUS]
+    <unique combine="cancel_old">
+      <context>NAME</context>
+    </unique>
   </notification>
 
   <notification
@@ -6160,7 +6154,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="TeleportOfferSent"
-   log_to_im="true"   
+   log_to_im="true"
+   show_toast="false"
    type="offer">
 	Teleport offer sent to [TO_NAME]
   </notification>
@@ -6213,6 +6208,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    icon="notify.tga"
    name="FriendshipOffered"
    log_to_im="true"   
+   show_toast="false"   
    type="offer">
     <tag>friendship</tag>
 	You have offered friendship to [TO_NAME]
@@ -6262,6 +6258,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    icon="notify.tga"
    name="FriendshipAcceptedByMe"
    log_to_im="true"   
+   show_toast="false"
    type="offer">
     <tag>friendship</tag>
 Friendship offer accepted.
@@ -6271,6 +6268,7 @@ Friendship offer accepted.
    icon="notify.tga"
    name="FriendshipDeclinedByMe"
    log_to_im="true"   
+   show_toast="false"   
    type="offer">
     <tag>friendship</tag>
 Friendship offer declined.
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 9752652679..e932310622 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3242,6 +3242,8 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 	<string name="IM_moderator_label">(Moderator)</string>
 	<string name="Saved_message">(Saved [LONG_TIMESTAMP])</string>
 	<string name="IM_unblock_only_groups_friends">To see this message, you must uncheck &apos;Only friends and groups can call or IM me&apos; in Preferences/Privacy.</string>
+  <string name="OnlineStatus">Online</string>
+  <string name="OfflineStatus">Offline</string>
 
 	<!-- voice calls -->
 	<string name="answered_call">Your call has been answered</string>
-- 
cgit v1.2.3


From 4c7142f4836da9da77ac6ff2910aaa19506a655b Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 18 May 2012 15:28:08 -0700
Subject: CHUI-96 FIX Cannot dismiss modal dialogs related to merchant outbox
 notification duplicate suppression now doesn't generate multiple dialogs

---
 indra/newview/llnotificationalerthandler.cpp | 62 ++++++++++++++--------------
 indra/newview/llnotificationhandler.h        |  2 +-
 indra/newview/llscreenchannel.cpp            | 17 ++++----
 3 files changed, 40 insertions(+), 41 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index d13e2b629d..2bc9cdd3c1 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -82,39 +82,39 @@ bool LLAlertHandler::processNotification(const LLNotificationPtr& notification)
 	}
 
 	if (notification->canLogToIM() && notification->hasFormElements())
-		{
-			const std::string name = LLHandlerUtil::getSubstitutionName(notification);
-
-			LLUUID from_id = notification->getPayload()["from_id"];
-
-			// firstly create session...
-			LLHandlerUtil::spawnIMSession(name, from_id);
-
-			// ...then log message to have IM Well notified about new message
-			LLHandlerUtil::logToIMP2P(notification);
-		}
-
-		LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.notification = notification;
-		p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
-		p.enable_hide_btn = false;
-		p.can_fade = false;
-		p.is_modal = mIsModal;
-		p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
-
-		// Show alert in middle of progress view (during teleport) (EXT-1093)
-		LLProgressView* progress = gViewerWindow->getProgressView();
-		LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
-		mChannel.get()->updatePositionAndSize(rc);
-
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->addToast(p);
+	{
+		const std::string name = LLHandlerUtil::getSubstitutionName(notification);
+
+		LLUUID from_id = notification->getPayload()["from_id"];
+
+		// firstly create session...
+		LLHandlerUtil::spawnIMSession(name, from_id);
+
+		// ...then log message to have IM Well notified about new message
+		LLHandlerUtil::logToIMP2P(notification);
+	}
+
+	LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.notification = notification;
+	p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
+	p.enable_hide_btn = false;
+	p.can_fade = false;
+	p.is_modal = mIsModal;
+	p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
+
+	// Show alert in middle of progress view (during teleport) (EXT-1093)
+	LLProgressView* progress = gViewerWindow->getProgressView();
+	LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
+	mChannel.get()->updatePositionAndSize(rc);
+
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	if(channel)
+		channel->addToast(p);
 	
 	return false;
-	}
+}
 
 void LLAlertHandler::onChange( LLNotificationPtr notification )
 {
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 4d54bb78fc..0899625242 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -258,7 +258,7 @@ public:
 	:	LLNotificationChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"))
 	{}
 	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
+	/*virtual*/ void onChange(LLNotificationPtr p) { }
 	/*virtual*/ void onDelete(LLNotificationPtr p);
 	bool processNotification(const LLNotificationPtr& p);
 };
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 839ca0f9c5..157821d554 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -499,21 +499,20 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)
 
 void LLScreenChannel::removeToastByNotificationID(LLUUID id)
 {
-	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
-	if( it != mToastList.end())
+	std::vector<ToastElem>::iterator it = mToastList.begin();
+	while( it != mToastList.end())
 	{
+		// find next toast with matching id
+		it = find(it, mToastList.end(), id);
 		deleteToast(it->getToast());
 		mToastList.erase(it);
 		redrawToasts();
 	}
-	else
+	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+	if (it != mStoredToastList.end())
 	{
-		it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-		if (it != mStoredToastList.end())
-		{
-			deleteToast(it->getToast());
-			mStoredToastList.erase(it);
-		}
+		deleteToast(it->getToast());
+		mStoredToastList.erase(it);
 	}
 }
 
-- 
cgit v1.2.3


From 32717690ee6a9f33ca909f0df0226e9533f69399 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Mon, 21 May 2012 17:45:28 +0300
Subject: gcc build fix.

---
 indra/newview/lltoastnotifypanel.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 77a5a5d17d..3692fd5672 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -57,7 +57,7 @@ LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal
 
 LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) 
 :	LLToastPanel(notification),
-	LLInstanceTracker(notification->getID())
+	LLInstanceTracker<LLToastNotifyPanel, LLUUID>(notification->getID())
 {
 	init(rect, show_images);
 
-- 
cgit v1.2.3


From 61bc25211be31ad28b8ae342c17b4ea1c32d955c Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 21 May 2012 17:16:11 -0700
Subject: CHUI-111 FIX Saved notifications are not sorted in same order after
 logout and relog. sort notifications in separate list llnotification now uses
 param block to serialize to llsd

---
 indra/llui/llnotifications.cpp          | 138 ++++++++---------------------
 indra/llui/llnotifications.h            | 148 +++++++++++++++++---------------
 indra/llui/llsdparam.cpp                |   8 +-
 indra/llxuixml/llinitparam.h            |   4 +-
 indra/newview/llnotificationstorage.cpp |  18 +++-
 indra/newview/lltoastnotifypanel.cpp    |  24 ------
 6 files changed, 137 insertions(+), 203 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 663749b983..08b93ead40 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -105,39 +105,7 @@ LLNotificationForm::Params::Params()
 	form_elements("")
 {}
 
-// Local channel for persistent notifications
-// Stores only persistent notifications.
-// Class users can use connectChanged() to process persistent notifications
-// (see LLNotificationStorage for example).
-class LLPersistentNotificationChannel : public LLNotificationChannel
-{
-	LOG_CLASS(LLPersistentNotificationChannel);
-public:
-	LLPersistentNotificationChannel() :
-		LLNotificationChannel("Persistent", "Visible", &notificationFilter, LLNotificationComparators::orderByUUID())
-	{
-	}
 
-private:
-
-	// The channel gets all persistent notifications except those that have been canceled
-	static bool notificationFilter(LLNotificationPtr pNotification)
-	{
-		bool handle_notification = false;
-
-		handle_notification = pNotification->isPersistent()
-			&& !pNotification->isCancelled();
-
-		return handle_notification;
-	}
-
-	void onDelete(LLNotificationPtr pNotification)
-	{
-		// we want to keep deleted notifications in our log, otherwise some 
-		// notifications will be lost on exit.
-		mItems.insert(pNotification);
-	}
-};
 
 bool filterIgnoredNotifications(LLNotificationPtr notification)
 {
@@ -502,18 +470,18 @@ LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationV
 	}
 }
 
-LLNotification::LLNotification(const LLNotification::Params& p) : 
+LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) : 
 	mTimestamp(p.time_stamp), 
 	mSubstitutions(p.substitutions),
 	mPayload(p.payload),
-	mExpiresAt(0),
+	mExpiresAt(p.expiry),
 	mTemporaryResponder(false),
 	mRespondedTo(false),
 	mPriority(p.priority),
 	mCancelled(false),
 	mIgnored(false),
 	mResponderObj(NULL),
-	mIsReusable(false)
+	mId(p.id.isProvided() ? p.id : LLUUID::generateNewID())
 {
 	if (p.functor.name.isChosen())
 	{
@@ -536,52 +504,32 @@ LLNotification::LLNotification(const LLNotification::Params& p) :
 		mResponderObj = p.responder;
 	}
 
-	mId.generate();
 	init(p.name, p.form_elements);
 }
 
 
-LLNotification::LLNotification(const LLSD& sd) :
-	mTemporaryResponder(false),
-	mRespondedTo(false),
-	mCancelled(false),
-	mIgnored(false),
-	mResponderObj(NULL),
-	mIsReusable(false)
-{ 
-	mId.generate();
-	mSubstitutions = sd["substitutions"];
-	mPayload = sd["payload"]; 
-	mTimestamp = sd["time"]; 
-	mExpiresAt = sd["expiry"];
-	mPriority = (ENotificationPriority)sd["priority"].asInteger();
-	mResponseFunctorName = sd["responseFunctor"].asString();
-	std::string templatename = sd["name"].asString();
-	init(templatename, LLSD());
-	// replace form with serialized version
-	mForm = LLNotificationFormPtr(new LLNotificationForm(sd["form"]));
-}
-
-
 LLSD LLNotification::asLLSD()
 {
-	LLSD output;
-	output["id"] = mId;
-	output["name"] = mTemplatep->mName;
-	output["form"] = getForm()->asLLSD();
-	output["substitutions"] = mSubstitutions;
-	output["payload"] = mPayload;
-	output["time"] = mTimestamp;
-	output["expiry"] = mExpiresAt;
-	output["priority"] = (S32)mPriority;
-	output["responseFunctor"] = mResponseFunctorName;
-	output["reusable"] = mIsReusable;
+	LLParamSDParser parser;
 
-	if(mResponder)
+	Params p;
+	p.id = mId;
+	p.name = mTemplatep->mName;
+	p.form_elements = getForm()->asLLSD();
+
+	p.substitutions = mSubstitutions;
+	p.payload = mPayload;
+	p.time_stamp = mTimestamp;
+	p.expiry = mExpiresAt;
+	p.priority = mPriority;
+
+	if(!mResponseFunctorName.empty())
 	{
-		output["responder"] = mResponder->asLLSD();
+		p.functor.name = mResponseFunctorName;
 	}
 
+	LLSD output;
+	parser.writeSD(output, p);
 	return output;
 }
 
@@ -1056,8 +1004,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 		{
 			// not in our list, add it and say so
 			mItems.insert(pNotification);
-			abortProcessing = mChanged(payload);
 			onLoad(pNotification);
+			abortProcessing = mChanged(payload);
 		}
 	}
 	else if (cmd == "change")
@@ -1072,18 +1020,18 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 			{
 				// it already existed, so this is a change
 				// since it changed in place, all we have to do is resend the signal
-				abortProcessing = mChanged(payload);
 				onChange(pNotification);
+				abortProcessing = mChanged(payload);
 			}
 			else
 			{
 				// not in our list, add it and say so
 				mItems.insert(pNotification);
+				onChange(pNotification);
 				// our payload is const, so make a copy before changing it
 				LLSD newpayload = payload;
 				newpayload["sigtype"] = "add";
 				abortProcessing = mChanged(newpayload);
-				onChange(pNotification);
 			}
 		}
 		else
@@ -1092,11 +1040,11 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 			{
 				// it already existed, so this is a delete
 				mItems.erase(pNotification);
+				onChange(pNotification);
 				// our payload is const, so make a copy before changing it
 				LLSD newpayload = payload;
 				newpayload["sigtype"] = "delete";
 				abortProcessing = mChanged(newpayload);
-				onChange(pNotification);
 			}
 			// didn't pass, not on our list, do nothing
 		}
@@ -1110,8 +1058,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 		{
 			// not in our list, add it and say so
 			mItems.insert(pNotification);
-			abortProcessing = mChanged(payload);
 			onAdd(pNotification);
+			abortProcessing = mChanged(payload);
 		}
 	}
 	else if (cmd == "delete")
@@ -1119,16 +1067,16 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 		// if we have it in our list, pass on the delete, then delete it, else do nothing
 		if (wasFound)
 		{
-			abortProcessing = mChanged(payload);
 			mItems.erase(pNotification);
 			onDelete(pNotification);
+			abortProcessing = mChanged(payload);
 		}
 	}
 	return abortProcessing;
 }
 
 LLNotificationChannel::LLNotificationChannel(const Params& p)
-:	LLNotificationChannelBase(p.filter(), p.comparator()),
+:	LLNotificationChannelBase(p.filter()),
 	LLInstanceTracker<LLNotificationChannel, std::string>(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()),
 	mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString())
 {
@@ -1141,9 +1089,8 @@ LLNotificationChannel::LLNotificationChannel(const Params& p)
 
 LLNotificationChannel::LLNotificationChannel(const std::string& name, 
 											 const std::string& parent,
-											 LLNotificationFilter filter, 
-											 LLNotificationComparator comparator) 
-:	LLNotificationChannelBase(filter, comparator),
+											 LLNotificationFilter filter) 
+:	LLNotificationChannelBase(filter),
 	LLInstanceTracker<LLNotificationChannel, std::string>(name),
 	mName(name)
 {
@@ -1151,18 +1098,6 @@ LLNotificationChannel::LLNotificationChannel(const std::string& name,
 	connectToChannel(parent);
 }
 
-
-void LLNotificationChannel::setComparator(LLNotificationComparator comparator) 
-{ 
-	mComparator = comparator; 
-	LLNotificationSet s2(mComparator);
-	s2.insert(mItems.begin(), mItems.end());
-	mItems.swap(s2);
-	
-	// notify clients that we've been resorted
-	mChanged(LLSD().with("sigtype", "sort")); 
-}
-
 bool LLNotificationChannel::isEmpty() const
 {
 	return mItems.empty();
@@ -1178,6 +1113,11 @@ LLNotificationChannel::Iterator LLNotificationChannel::end()
 	return mItems.end();
 }
 
+size_t LLNotificationChannel::size()
+{
+	return mItems.size();
+}
+
 std::string LLNotificationChannel::summarize()
 {
 	std::string s("Channel '");
@@ -1205,19 +1145,17 @@ void LLNotificationChannel::connectToChannel( const std::string& channel_name )
 	}
 }
 
-
-
 // ---
 // END OF LLNotificationChannel implementation
 // =========================================================
 
 
-// =========================================================
+// ==============================================	===========
 // LLNotifications implementation
 // ---
-LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
-															   LLNotificationComparators::orderByUUID()),
-									mIgnoreAllNotifications(false)
+LLNotifications::LLNotifications() 
+:	LLNotificationChannelBase(LLNotificationFilters::includeEverything),
+	mIgnoreAllNotifications(false)
 {
 	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
 
@@ -1705,7 +1643,7 @@ void LLNotifications::update(const LLNotificationPtr pNotif)
 
 LLNotificationPtr LLNotifications::find(LLUUID uuid)
 {
-	LLNotificationPtr target = LLNotificationPtr(new LLNotification(uuid));
+	LLNotificationPtr target = LLNotificationPtr(new LLNotification(LLNotification::Params().id(uuid)));
 	LLNotificationSet::iterator it=mItems.find(target);
 	if (it == mItems.end())
 	{
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index e9449eae69..783e9ffc88 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -88,10 +88,6 @@
 #include <boost/enable_shared_from_this.hpp>
 #include <boost/type_traits.hpp>
 
-// we want to minimize external dependencies, but this one is important
-#include "llsd.h"
-
-// and we need this to manage the notification callbacks
 #include "llevents.h"
 #include "llfunctorregistry.h"
 #include "llinitparam.h"
@@ -99,6 +95,7 @@
 #include "llnotificationptr.h"
 #include "llpointer.h"
 #include "llrefcount.h"
+#include "llsdparam.h"
 
 class LLAvatarName;
 typedef enum e_notification_priority
@@ -309,13 +306,13 @@ public:
 		friend class LLNotification;
 	
 		Mandatory<std::string>					name;
-
-		// optional
-		Optional<LLSD>							substitutions;
-		Optional<LLSD>							payload;
+		Optional<LLUUID>						id;
+		Optional<LLSD>							substitutions,
+												form_elements,
+												payload;
 		Optional<ENotificationPriority, NotificationPriorityValues>	priority;
-		Optional<LLSD>							form_elements;
-		Optional<LLDate>						time_stamp;
+		Optional<LLDate>						time_stamp,
+												expiry;
 		Optional<LLNotificationContext*>		context;
 		Optional<void*>							responder;
 
@@ -326,7 +323,7 @@ public:
 			Alternative<LLNotificationResponderPtr>						responder;
 
 			Functor()
-			:	name("functor_name"),
+			:	name("responseFunctor"),
 				function("functor"),
 				responder("responder")
 			{}
@@ -335,10 +332,13 @@ public:
 
 		Params()
 		:	name("name"),
+			id("id"),
 			priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
-			time_stamp("time_stamp"),
+			time_stamp("time"),
 			payload("payload"),
-			form_elements("form_elements")
+			form_elements("form"),
+			substitutions("substitutions"),
+			expiry("expiry")
 		{
 			time_stamp = LLDate::now();
 			responder = NULL;
@@ -347,9 +347,11 @@ public:
 		Params(const std::string& _name) 
 		:	name("name"),
 			priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
-			time_stamp("time_stamp"),
+			time_stamp("time"),
 			payload("payload"),
-			form_elements("form_elements")
+			form_elements("form"),
+			substitutions("substitutions"),
+			expiry("expiry")
 		{
 			functor.name = _name;
 			name = _name;
@@ -362,7 +364,7 @@ public:
 
 private:
 	
-	LLUUID mId;
+	const LLUUID mId;
 	LLSD mPayload;
 	LLSD mSubstitutions;
 	LLDate mTimestamp;
@@ -374,7 +376,6 @@ private:
 	ENotificationPriority mPriority;
 	LLNotificationFormPtr mForm;
 	void* mResponderObj; // TODO - refactor/remove this field
-	bool mIsReusable;
 	LLNotificationResponderPtr mResponder;
 
 	// a reference to the template
@@ -399,18 +400,10 @@ private:
 
 	void init(const std::string& template_name, const LLSD& form_elements);
 
-	LLNotification(const Params& p);
-
-	// this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT
-	// for anything real!
- LLNotification(LLUUID uuid) : mId(uuid), mCancelled(false), mRespondedTo(false), mIgnored(false), mPriority(NOTIFICATION_PRIORITY_UNSPECIFIED), mTemporaryResponder(false) {}
-
 	void cancel();
 
 public:
-
-	// constructor from a saved notification
-	LLNotification(const LLSD& sd);
+	LLNotification(const LLSDParamAdapter<Params>& p);
 
 	void setResponseFunctor(std::string const &responseFunctorName);
 
@@ -555,8 +548,6 @@ public:
 		return mId;
 	}
 
-	bool isReusable() { return mIsReusable; }
-
 	// comparing two notifications normally means comparing them by UUID (so we can look them
 	// up quickly this way)
 	bool operator<(const LLNotification& rhs) const
@@ -668,44 +659,18 @@ namespace LLNotificationFilters
 
 namespace LLNotificationComparators
 {
-	typedef enum e_direction { ORDER_DECREASING, ORDER_INCREASING } EDirection;
-
-	// generic order functor that takes method or member variable reference
-	template<typename T>
-	struct orderBy
+	struct orderByUUID
 	{
-		typedef boost::function<T (LLNotificationPtr)> field_t;
-        	orderBy(field_t field, EDirection direction = ORDER_INCREASING) : mField(field), mDirection(direction) {}
 		bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs)
 		{
-			if (mDirection == ORDER_DECREASING)
-			{
-				return mField(lhs) > mField(rhs);
-			}
-			else
-			{
-				return mField(lhs) < mField(rhs);
-			}
+			return lhs->id() < rhs->id();
 		}
-
-		field_t mField;
-		EDirection mDirection;
-	};
-
-	struct orderByUUID : public orderBy<const LLUUID&>
-	{
-		orderByUUID(EDirection direction = ORDER_INCREASING) : orderBy<const LLUUID&>(&LLNotification::id, direction) {}
-	};
-
-	struct orderByDate : public orderBy<const LLDate&>
-	{
-		orderByDate(EDirection direction = ORDER_INCREASING) : orderBy<const LLDate&>(&LLNotification::getDate, direction) {}
 	};
 };
 
 typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
 typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
-typedef std::set<LLNotificationPtr, LLNotificationComparator> LLNotificationSet;
+typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet;
 typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
 
 // ========================================================
@@ -731,8 +696,9 @@ class LLNotificationChannelBase :
 {
 	LOG_CLASS(LLNotificationChannelBase);
 public:
-	LLNotificationChannelBase(LLNotificationFilter filter, LLNotificationComparator comp) : 
-		mFilter(filter), mItems(comp) 
+	LLNotificationChannelBase(LLNotificationFilter filter) 
+	:	mFilter(filter), 
+		mItems() 
 	{}
 	virtual ~LLNotificationChannelBase() {}
 	// you can also connect to a Channel, so you can be notified of
@@ -829,18 +795,11 @@ public:
 	{
 		Mandatory<std::string>				name;
 		Optional<LLNotificationFilter>		filter;
-		Optional<LLNotificationComparator>	comparator;
 		Multiple<std::string>				sources;
-
-		Params()
-		:	comparator("", LLNotificationComparators::orderByUUID())
-		{}
 	};
 
 	LLNotificationChannel(const Params& p = Params());
-
-	LLNotificationChannel(const std::string& name, const std::string& parent,
-		LLNotificationFilter filter, LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
+	LLNotificationChannel(const std::string& name, const std::string& parent, LLNotificationFilter filter);
 
 	virtual ~LLNotificationChannel() {}
 	typedef LLNotificationSet::iterator Iterator;
@@ -853,11 +812,8 @@ public:
     
     Iterator begin();
     Iterator end();
+	size_t size();
 
-    // Channels have a comparator to control sort order;
-	// the default sorts by arrival date
-    void setComparator(LLNotificationComparator comparator);
-	
 	std::string summarize();
 
 private:
@@ -1047,5 +1003,55 @@ protected:
 	std::string mName;
 };
 
+// Stores only persistent notifications.
+// Class users can use connectChanged() to process persistent notifications
+// (see LLNotificationStorage for example).
+class LLPersistentNotificationChannel : public LLNotificationChannel
+{
+	LOG_CLASS(LLPersistentNotificationChannel);
+public:
+	LLPersistentNotificationChannel() 
+		:	LLNotificationChannel("Persistent", "Visible", &notificationFilter)
+	{
+	}
+
+	typedef std::vector<LLNotificationPtr> history_list_t;
+	history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); }
+	history_list_t::iterator endHistory() { return mHistory.end(); }
+
+private:
+
+	void sortHistory()
+	{
+		struct sortByTime
+		{
+			S32 operator ()(const LLNotificationPtr& a, const LLNotificationPtr& b)
+			{
+				return a->getDate() < b->getDate();
+			}
+		};
+		std::sort(mHistory.begin(), mHistory.end(), sortByTime());
+	}
+
+
+	// The channel gets all persistent notifications except those that have been canceled
+	static bool notificationFilter(LLNotificationPtr pNotification)
+	{
+		bool handle_notification = false;
+
+		handle_notification = pNotification->isPersistent()
+			&& !pNotification->isCancelled();
+
+		return handle_notification;
+	}
+
+	void onAdd(LLNotificationPtr p) 
+	{
+		mHistory.push_back(p);
+	}
+
+	std::vector<LLNotificationPtr> mHistory;
+};
+
 #endif//LL_LLNOTIFICATIONS_H
 
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index bcfb38aa11..811e20e810 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -283,7 +283,10 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI
 			it != sd.endArray();
 			++it)
 		{
-			stack.back().second = true;
+			if (!stack.empty())
+			{
+				stack.back().second = true;
+			}
 			readSDValues(cb, *it, stack);
 		}
 	}
@@ -336,7 +339,6 @@ namespace LLInitParam
 	void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
 	{
 		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
-		Parser::name_stack_t stack;
-		LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack);
+		LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
 	}
 }
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 29f4a09cb7..435db1699c 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -1024,7 +1024,9 @@ namespace LLInitParam
 				if (!parser.writeValue(typed_param.getValue(), name_stack)) 
 				{
 					std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
-					if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key))
+					if (calculated_key.size() 
+						&& (!diff_param 
+							|| !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)))
 					{
 						parser.writeValue(calculated_key, name_stack);
 					}
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index fb1adc7ddf..a31b95811e 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -84,9 +84,11 @@ bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& pay
 	return false;
 }
 
+static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
+
 void LLPersistentNotificationStorage::saveNotifications()
 {
-	// TODO - think about save optimization.
+	LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
 
 	llofstream notify_file(mFileName.c_str());
 	if (!notify_file.is_open())
@@ -98,10 +100,15 @@ void LLPersistentNotificationStorage::saveNotifications()
 	LLSD output;
 	LLSD& data = output["data"];
 
-	LLNotificationChannelPtr history_channel = LLNotifications::instance().getChannel("Persistent");
-	LLNotificationSet::iterator it = history_channel->begin();
+	boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
+	if (!history_channel)
+	{
+		return;
+	}
 
-	for ( ; history_channel->end() != it; ++it)
+	for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
+		it != end_it;
+		++it)
 	{
 		LLNotificationPtr notification = *it;
 
@@ -120,8 +127,11 @@ void LLPersistentNotificationStorage::saveNotifications()
 	formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
 }
 
+static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
+
 void LLPersistentNotificationStorage::loadNotifications()
 {
+	LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
 	LLResponderRegistry::registerResponders();
 
 	LLNotifications::instance().getChannel("Persistent")->
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 77a5a5d17d..884df27a18 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -60,19 +60,6 @@ LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, co
 	LLInstanceTracker(notification->getID())
 {
 	init(rect, show_images);
-
-
-	//if(notification->isRespondedTo())
-	//{
-	//	// User selected an option in toast, now disable required buttons in IM window
-	//	disableRespondedOptions(notification);
-	//}
-	//
-	//if(notification->isReusable())
-	//{
-	//	mButtonClickConnection = sButtonClickSignal.connect(
-	//		boost::bind(&LLToastNotifyPanel::disableRespondedOptions, this, notification));
-	//}
 }
 void LLToastNotifyPanel::addDefaultButton()
 {
@@ -354,17 +341,6 @@ void LLToastNotifyPanel::onClickButton(void* data)
 	{
 		response[button_name] = true;
 	}
-	
-	bool is_reusable = self->mNotification->isReusable();
-	// When we call respond(), LLOfferInfo will delete itself in inventory_offer_callback(), 
-	// lets copy it while it's still valid.
-	LLOfferInfo* old_info = static_cast<LLOfferInfo*>(self->mNotification->getResponder());
-	LLOfferInfo* new_info = NULL;
-	if(is_reusable && old_info)
-	{
-		new_info = new LLOfferInfo(*old_info);
-		self->mNotification->setResponder(new_info);
-	}
 
 	// disable all buttons
 	self->mControlPanel->setEnabled(FALSE);
-- 
cgit v1.2.3


From f89d94434c6e9d96ad71586d55c2b32d933a1e05 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 21 May 2012 18:26:18 -0700
Subject: made param blocks smaller by making param overhead 3 bytes instead of
 4 Optional<bool> should now be 4 bytes smaller.

---
 indra/llui/tests/llurlentry_stub.cpp |  4 +++-
 indra/llui/tests/llurlmatch_test.cpp |  4 +++-
 indra/llxuixml/llinitparam.cpp       |  6 ++++--
 indra/llxuixml/llinitparam.h         | 13 ++++++++++---
 4 files changed, 20 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index 9cb6a89eee..61e30d89d0 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -110,7 +110,9 @@ namespace LLInitParam
 	{
 		const U8* my_addr = reinterpret_cast<const U8*>(this);
 		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
-		mEnclosingBlockOffset = (U16)(my_addr - block_addr);
+		U32 enclosing_block_offset = 0x7FFFffff & (U32)(my_addr - block_addr);
+		mEnclosingBlockOffsetLow = enclosing_block_offset & 0x0000ffff;
+		mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;
 	}
 
 	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name){}
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 36402f5b27..97fe5b2eea 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -88,7 +88,9 @@ namespace LLInitParam
 	{
 		const U8* my_addr = reinterpret_cast<const U8*>(this);
 		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
-		mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr));
+		U32 enclosing_block_offset = 0x7FFFffff & (U32)(my_addr - block_addr);
+		mEnclosingBlockOffsetLow = enclosing_block_offset & 0x0000ffff;
+		mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;
 	}
 
 	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 3cf145cdde..3c0d0aaa7e 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -40,7 +40,9 @@ namespace LLInitParam
 	{
 		const U8* my_addr = reinterpret_cast<const U8*>(this);
 		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
-		mEnclosingBlockOffset = 0x7FFFffff & (U32)(my_addr - block_addr);
+		U32 enclosing_block_offset = 0x7FFFffff & (U32)(my_addr - block_addr);
+		mEnclosingBlockOffsetLow = enclosing_block_offset & 0x0000ffff;
+		mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;
 	}
 
 	//
@@ -459,7 +461,7 @@ namespace LLInitParam
 			if (merge_func)
 			{
 				Param* paramp = getParamFromHandle((*it)->mParamHandle);
-				llassert(paramp->mEnclosingBlockOffset == (*it)->mParamHandle);
+				llassert(paramp->getEnclosingBlockOffset() == (*it)->mParamHandle);
 				some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
 			}
 		}
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 435db1699c..ce59401e87 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -908,14 +908,21 @@ namespace LLInitParam
 			// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
 			return *const_cast<BaseBlock*>
 				(reinterpret_cast<const BaseBlock*>
-					(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
+					(my_addr - (ptrdiff_t)getEnclosingBlockOffset()));
+		}
+
+		U32 getEnclosingBlockOffset() const
+		{
+			return ((U32)mEnclosingBlockOffsetHigh << 16) | (U32)mEnclosingBlockOffsetLow;
 		}
 
 	private:
 		friend class BaseBlock;
 
-		U32		mEnclosingBlockOffset:31;
-		U32		mIsProvided:1;
+		//24 bits for member offset field and 1 bit for provided flag
+		U16		mEnclosingBlockOffsetLow;
+		U8		mEnclosingBlockOffsetHigh:7;
+		U8		mIsProvided:1;
 
 	};
 
-- 
cgit v1.2.3


From 4dffa3351401bd8ba8326958b38a3d500805b5d1 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 22 May 2012 20:34:34 +0300
Subject: Linux build fix

GCC does not allow local functor classes to be used with template algorithms, because template arguments must refer to an entity with external linkage.
---
 indra/llui/llnotifications.h | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 783e9ffc88..12479f0788 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -1021,15 +1021,16 @@ public:
 
 private:
 
-	void sortHistory()
+	struct sortByTime
 	{
-		struct sortByTime
+		S32 operator ()(const LLNotificationPtr& a, const LLNotificationPtr& b)
 		{
-			S32 operator ()(const LLNotificationPtr& a, const LLNotificationPtr& b)
-			{
-				return a->getDate() < b->getDate();
-			}
-		};
+			return a->getDate() < b->getDate();
+		}
+	};
+
+	void sortHistory()
+	{
 		std::sort(mHistory.begin(), mHistory.end(), sortByTime());
 	}
 
-- 
cgit v1.2.3


From 61d550ee85b371add15d174b4f6fbd93624c3490 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 24 May 2012 19:20:37 +0300
Subject: CHUI-78 FIXED group actions gear menu in People->Groups. Used the
 same menu for groups list context menu and gear menu in People->Groups.
 Changed the type of groups list context menu to toggleable.

---
 indra/llui/lltoggleablemenu.h                       |  2 ++
 indra/newview/llgrouplist.cpp                       |  4 ++--
 indra/newview/llgrouplist.h                         |  9 +++++++--
 indra/newview/llpanelpeople.cpp                     | 13 +++++++++++++
 indra/newview/skins/default/xui/en/panel_people.xml |  2 --
 5 files changed, 24 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h
index 2094bd776f..dd9ac5b8c1 100644
--- a/indra/llui/lltoggleablemenu.h
+++ b/indra/llui/lltoggleablemenu.h
@@ -58,6 +58,8 @@ public:
 	// its visibility off.
 	bool toggleVisibility();
 	
+	LLHandle<LLToggleableMenu> getHandle() { return getDerivedHandle<LLToggleableMenu>(); }
+
 protected:
 	bool mClosedByButtonClick;
 	LLRect mButtonRect;
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 129cddda45..2de891565c 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -86,7 +86,7 @@ LLGroupList::LLGroupList(const Params& p)
 	registrar.add("People.Groups.Action",			boost::bind(&LLGroupList::onContextMenuItemClick,	this, _2));
 	enable_registrar.add("People.Groups.Enable",	boost::bind(&LLGroupList::onContextMenuItemEnable,	this, _2));
 
-	LLMenuGL* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_groups.xml",
+	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups.xml",
 			gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 	if(context_menu)
 		mContextMenuHandle = context_menu->getHandle();
@@ -112,7 +112,7 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
 
-	LLMenuGL* context_menu = (LLMenuGL*)mContextMenuHandle.get();
+	LLToggleableMenu* context_menu = mContextMenuHandle.get();
 	if (context_menu && size() > 0)
 	{
 		context_menu->buildDrawLabels();
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 8abf14b3d0..6c8f4406ab 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -28,10 +28,13 @@
 #define LL_LLGROUPLIST_H
 
 #include "llevent.h"
+#include "llpointer.h"
+
 #include "llflatlistview.h"
 #include "llpanel.h"
-#include "llpointer.h"
 #include "llstyle.h"
+#include "lltoggleablemenu.h"
+
 #include "llgroupmgr.h"
 
 /**
@@ -57,6 +60,8 @@ public:
 	void toggleIcons();
 	bool getIconsVisible() const { return mShowIcons; }
 
+	LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
+
 private:
 	void setDirty(bool val = true)		{ mDirty = val; }
 	void refresh();
@@ -66,7 +71,7 @@ private:
 	bool onContextMenuItemClick(const LLSD& userdata);
 	bool onContextMenuItemEnable(const LLSD& userdata);
 
-	LLHandle<LLView>	mContextMenuHandle;
+	LLHandle<LLToggleableMenu>	mContextMenuHandle;
 
 	bool mShowIcons;
 	bool mDirty;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 9b06d05b4b..260de40eef 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -630,6 +630,19 @@ BOOL LLPanelPeople::postBuild()
 	mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
 	mGroupList->setReturnCallback(boost::bind(&LLPanelPeople::onChatButtonClicked, this));
 
+	LLMenuButton* groups_gear_btn = getChild<LLMenuButton>("groups_gear_btn");
+
+	// Use the context menu of the Groups list for the Groups tab gear menu.
+	LLToggleableMenu* groups_gear_menu = mGroupList->getContextMenu();
+	if (groups_gear_menu)
+	{
+		groups_gear_btn->setMenu(groups_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+	}
+	else
+	{
+		llwarns << "People->Groups list menu not found" << llendl;
+	}
+
 	LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>("tab_all");
 	accordion_tab->setDropDownStateChangedCallback(
 		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mAllFriendList));
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index abfb9c7a36..ceb03d03a9 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -418,8 +418,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left_pad="8"
-                 menu_filename="menu_people_groups.xml"
-                 menu_position="bottomleft"
                  name="groups_gear_btn"
                  top="3"
                  width="31" />
-- 
cgit v1.2.3


From d713925f435add08f6e48fec2472671fae58f170 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 25 May 2012 11:39:37 -0700
Subject: CHUI-132 FIX Modal dialogs cannot be dismissed

---
 indra/llui/llnotifications.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 08b93ead40..487a2e5fe7 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1067,9 +1067,9 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 		// if we have it in our list, pass on the delete, then delete it, else do nothing
 		if (wasFound)
 		{
-			mItems.erase(pNotification);
 			onDelete(pNotification);
 			abortProcessing = mChanged(payload);
+			mItems.erase(pNotification);
 		}
 	}
 	return abortProcessing;
-- 
cgit v1.2.3


From 8a2b6f7d2e56625c59c3e40d4a23942a91b824a1 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 25 May 2012 12:04:12 -0700
Subject: CHUI-131 FIX Crash when selecting Show on inventory offer
 notification if other notifications are being received

---
 indra/newview/llscreenchannel.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 157821d554..a4a0198305 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -499,15 +499,16 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)
 
 void LLScreenChannel::removeToastByNotificationID(LLUUID id)
 {
-	std::vector<ToastElem>::iterator it = mToastList.begin();
+	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
 	while( it != mToastList.end())
 	{
-		// find next toast with matching id
-		it = find(it, mToastList.end(), id);
 		deleteToast(it->getToast());
 		mToastList.erase(it);
 		redrawToasts();
+		// find next toast with matching id
+		it = find(mToastList.begin(), mToastList.end(), id);
 	}
+
 	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
 	if (it != mStoredToastList.end())
 	{
-- 
cgit v1.2.3


From 2286dcb73bfddb9bd4102869005b14241053377d Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Tue, 29 May 2012 02:12:51 +0300
Subject: CHUI-105 WIP Fixed "is not a child of" warning when removing a tab
 from LLSideTrayPanelContainer.

---
 indra/llui/lltabcontainer.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 5fc2cc350d..d0920685bf 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1209,7 +1209,11 @@ void LLTabContainer::removeTabPanel(LLPanel* child)
 				update_images(mTabList[mTabList.size()-2], mLastTabParams, getTabPosition());
 			}
 
-			removeChild( tuple->mButton );
+			if (!getTabsHidden())
+			{
+				// We need to remove tab buttons only if the tabs are not hidden.
+				removeChild( tuple->mButton );
+			}
  			delete tuple->mButton;
 
  			removeChild( tuple->mTabPanel );
-- 
cgit v1.2.3


From 47ec4faeb4dc67f9614e218a75d4957ccf6f794c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 30 May 2012 19:58:20 +0300
Subject: CHUI-119 WIP Prepare the nearby chat for hosting it by the
 IM-container

---
 indra/llui/llfloater.cpp                           |   2 +
 indra/llui/llfloater.h                             |   2 +
 indra/llui/llview.cpp                              |   2 +-
 indra/newview/CMakeLists.txt                       |   2 +
 indra/newview/llfloaterpreference.cpp              |   8 +-
 indra/newview/llimconversation.cpp                 | 280 ++++++++++
 indra/newview/llimconversation.h                   |  97 ++++
 indra/newview/llimfloater.cpp                      | 600 +++++++--------------
 indra/newview/llimfloater.h                        |  58 +-
 indra/newview/llimfloatercontainer.cpp             |   1 +
 indra/newview/llimview.cpp                         |   2 +-
 indra/newview/llnearbychat.cpp                     |  26 +-
 indra/newview/llnearbychat.h                       |  10 +-
 indra/newview/llnearbychatbar.cpp                  | 110 ++--
 indra/newview/llnearbychatbar.h                    |  16 +-
 .../skins/default/xui/en/floater_chat_bar.xml      | 162 +++++-
 .../skins/default/xui/en/panel_nearby_chat.xml     |  21 +-
 17 files changed, 847 insertions(+), 552 deletions(-)
 create mode 100644 indra/newview/llimconversation.cpp
 create mode 100644 indra/newview/llimconversation.h

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index b087205a5c..5635905327 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1635,6 +1635,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		// give focus to new window to keep continuity for the user
 		self->setFocus(TRUE);
 		self->setTornOff(true);
+
 	}
 	else  //Attach to parent.
 	{
@@ -1649,6 +1650,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		self->setTornOff(false);
 	}
 	self->updateTitleButtons();
+	self->setOpenPositioning(LLFloaterEnums::OPEN_POSITIONING_NONE);
 }
 
 // static
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index a7cc9ae961..cd02310bf8 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -329,6 +329,8 @@ public:
 	virtual void    setDocked(bool docked, bool pop_on_undock = true);
 
 	virtual void    setTornOff(bool torn_off) { mTornOff = torn_off; }
+	bool getTornOff() {return mTornOff;}
+	void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mOpenPositioning = pos;}
 
 	// Return a closeable floater, if any, given the current focus.
 	static LLFloater* getClosableFloaterFromFocus(); 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 421166dcd4..166cd99d03 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -349,7 +349,7 @@ void LLView::removeChild(LLView* child)
 	}
 	else
 	{
-		llwarns << child->getName() << "is not a child of " << getName() << llendl;
+		llwarns << "\"" << child->getName() << "\" is not a child of " << getName() << llendl;
 	}
 	updateBoundingRect();
 }
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b780a27ce2..86d30c239f 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -277,6 +277,7 @@ set(viewer_SOURCE_FILES
     llhudrender.cpp
     llhudtext.cpp
     llhudview.cpp
+    llimconversation.cpp
     llimfloater.cpp
     llimfloatercontainer.cpp
     llimhandler.cpp
@@ -834,6 +835,7 @@ set(viewer_HEADER_FILES
     llhudrender.h
     llhudtext.h
     llhudview.h
+    llimconversation.h
     llimfloater.h
     llimfloatercontainer.h
     llimview.h
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3ed575086c..18ab9dc264 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -423,13 +423,9 @@ void LLFloaterPreference::saveAvatarProperties( void )
 
 BOOL LLFloaterPreference::postBuild()
 {
-	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate));
+//	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
-	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate));
-
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate));
-
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate));
+	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
 
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
new file mode 100644
index 0000000000..7220ab6a82
--- /dev/null
+++ b/indra/newview/llimconversation.cpp
@@ -0,0 +1,280 @@
+/**
+ * @file llimconversation.cpp
+ * @brief LLIMConversation class implements the common behavior of LNearbyChatBar
+ * @brief and LLIMFloater for hosting both in LLIMContainer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llpanelimcontrolpanel.h"
+
+#include "lldraghandle.h"
+#include "llfloaterreg.h"
+#include "llimconversation.h"
+#include "llimfloater.h"
+#include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
+#include "lllayoutstack.h"
+#include "llnearbychat.h"
+#include "llnearbychatbar.h"
+
+LLIMConversation::LLIMConversation(const LLUUID& session_id)
+  : LLTransientDockableFloater(NULL, true, session_id)
+  ,  mControlPanel(NULL)
+  ,  mIsP2PChat(false)
+  ,  mExpandCollapseBtn(NULL)
+  ,  mTearOffBtn(NULL)
+  ,  mCloseBtn(NULL)
+  ,  mSessionID(session_id)
+{
+	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
+			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2));
+//	mCommitCallbackRegistrar.add("IMSession.ExpCollapseBtn.Click",
+//			boost::bind(&LLIMConversation::onSlide,  this));
+//	mCommitCallbackRegistrar.add("IMSession.CloseBtn.Click",
+//			boost::bind(&LLFloater::onClickClose, this));
+	mCommitCallbackRegistrar.add("IMSession.TearOffBtn.Click",
+			boost::bind(&LLIMConversation::onTearOffClicked, this));
+	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
+			boost::bind(&LLIMConversation::onIMCompactExpandedMenuItemCheck, this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
+			boost::bind(&LLIMConversation::onIMShowModesMenuItemCheck,   this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
+			boost::bind(&LLIMConversation::onIMShowModesMenuItemEnable,  this, _2));
+}
+
+BOOL LLIMConversation::postBuild()
+{
+	mCloseBtn = getChild<LLButton>("close_btn");
+	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
+
+	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this));
+
+	if (mControlPanel)
+	{
+	    mControlPanel->setSessionId(mSessionID);
+	    mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
+
+		mExpandCollapseBtn->setImageOverlay(
+				getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon"));
+	}
+	else
+	{
+		mExpandCollapseBtn->setEnabled(false);
+		getChild<LLLayoutPanel>("im_control_panel_holder")->setVisible(false);
+	}
+
+	mTearOffBtn = getChild<LLButton>("tear_off_btn");
+	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
+
+	if (!getTornOff())
+	{
+		setOpenPositioning(LLFloaterEnums::OPEN_POSITIONING_NONE);
+	}
+
+	if (isChatMultiTab())
+	{
+		return LLFloater::postBuild();
+	}
+	else
+	{
+		return LLDockableFloater::postBuild();
+	}
+
+}
+
+void LLIMConversation::onIMSessionMenuItemClicked(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+
+	if (item == "compact_view" || item == "expanded_view")
+	{
+		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
+	}
+	else
+	{
+		bool prev_value = gSavedSettings.getBOOL(item);
+		gSavedSettings.setBOOL(item, !prev_value);
+	}
+
+	LLIMConversation::processChatHistoryStyleUpdate();
+}
+
+
+bool LLIMConversation::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
+
+	return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
+}
+
+
+bool LLIMConversation::onIMShowModesMenuItemCheck(const LLSD& userdata)
+{
+	return gSavedSettings.getBOOL(userdata.asString());
+}
+
+// enable/disable states for the "show time" and "show names" items of the show-modes menu
+bool LLIMConversation::onIMShowModesMenuItemEnable(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
+	bool is_not_names = (item != "IMShowNamesForP2PConv");
+	return (plain_text && (is_not_names || mIsP2PChat));
+}
+
+void LLIMConversation::updateHeaderAndToolbar()
+{
+	bool is_hosted = getHost() != NULL;
+
+	if (is_hosted)
+	{
+		for (S32 i = 0; i < BUTTON_COUNT; i++)
+		{
+			if (mButtons[i])
+			{
+				// Hide the standard header buttons in a docked IM floater.
+				mButtons[i]->setVisible(false);
+			}
+		}
+	}
+
+	bool is_control_panel_visible = false;
+	if (mControlPanel)
+	{
+		// Control panel should be visible only in torn off floaters.
+		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
+		mControlPanel->getParent()->setVisible(is_control_panel_visible);
+	}
+
+	// Display collapse image (<<) if the floater is hosted
+	// or if it is torn off but has an open control panel.
+	bool is_expanded = is_hosted || is_control_panel_visible;
+	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
+	if (session)
+	{
+		// The button (>>) should be disabled for torn off P2P conversations.
+		mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType());
+	}
+	else
+	{
+		if (!mIsNearbyChat)
+		{
+			llwarns << "IM session not found." << llendl;
+		}
+	}
+
+	if (mDragHandle)
+	{
+		// toggle floater's drag handle and title visibility
+		mDragHandle->setVisible(!is_hosted);
+	}
+
+	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
+
+	mCloseBtn->setVisible(is_hosted);
+
+	enableDisableCallBtn();
+}
+
+// static
+void LLIMConversation::processChatHistoryStyleUpdate()
+{
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+			iter != inst_list.end(); ++iter)
+	{
+		LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
+		if (floater)
+		{
+			floater->reloadMessages();
+		}
+	}
+
+	LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
+	if (nearby_chat_bar)
+	{
+		nearby_chat_bar->reloadMessages();
+	}
+}
+
+void LLIMConversation::updateCallBtnState(bool callIsActive)
+{
+	getChild<LLButton>("voice_call_btn")->setImageOverlay(
+			callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
+    enableDisableCallBtn();
+
+}
+
+void LLIMConversation::onSlide(LLIMConversation* self)
+{
+	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(self->getHost());
+	if (host_floater)
+	{
+		// Hide the messages pane if a floater is hosted in the Conversations
+		host_floater->collapseMessagesPane(true);
+	}
+	else ///< floater is torn off
+	{
+		if (self->mControlPanel)
+		{
+			bool expand = !self->mControlPanel->getParent()->getVisible();
+
+			// Expand/collapse the IM control panel
+			self->mControlPanel->getParent()->setVisible(expand);
+
+			gSavedSettings.setBOOL("IMShowControlPanel", expand);
+
+			self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon"));
+		}
+	}
+}
+
+/*virtual*/
+void LLIMConversation::onOpen(const LLSD& key)
+{
+	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
+	if (host_floater)
+	{
+		// Show the messages pane when opening a floater hosted in the Conversations
+		host_floater->collapseMessagesPane(false);
+	}
+
+	updateHeaderAndToolbar();
+}
+
+void LLIMConversation::onTearOffClicked()
+{
+	onClickTearOff(this);
+	updateHeaderAndToolbar();
+}
+
+// static
+bool LLIMConversation::isChatMultiTab()
+{
+	// Restart is required in order to change chat window type.
+	static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1;
+	return is_single_window;
+}
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
new file mode 100644
index 0000000000..501977e061
--- /dev/null
+++ b/indra/newview/llimconversation.h
@@ -0,0 +1,97 @@
+/**
+ * @file llimconversation.h
+ * @brief LLIMConversation class implements the common behavior of LNearbyChatBar
+ * @brief and LLIMFloater for hosting both in LLIMContainer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_IMCONVERSATION_H
+#define LL_IMCONVERSATION_H
+
+#include "lltransientdockablefloater.h"
+#include "llviewercontrol.h"
+
+class LLPanelChatControlPanel;
+
+class LLIMConversation
+	: public LLTransientDockableFloater
+{
+
+public:
+	LOG_CLASS(LLIMConversation);
+
+	LLIMConversation(const LLUUID& session_id);
+
+	// reload all message with new settings of visual modes
+	static void processChatHistoryStyleUpdate();
+
+	/**
+	 * Returns true if chat is displayed in multi tabbed floater
+	 *         false if chat is displayed in multiple windows
+	 */
+	static bool isChatMultiTab();
+
+	// LLFloater overrides
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ BOOL postBuild();
+
+protected:
+
+	// callback for click on any items of the visual states menu
+	void onIMSessionMenuItemClicked(const LLSD& userdata);
+
+	// callback for check/uncheck of the expanded/collapse mode's switcher
+	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
+
+	//
+	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
+	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
+	static void onSlide(LLIMConversation *self);
+	void onTearOffClicked();
+
+	// refresh a visual state of the Call button
+	void updateCallBtnState(bool callIsActive);
+
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn() = 0;
+
+//	/* virtual */ void updateTitleButtons();
+
+
+	LLPanelChatControlPanel* mControlPanel;
+	bool mIsNearbyChat;
+	bool mIsP2PChat;
+
+	LLUUID mSessionID;
+
+	LLButton* mExpandCollapseBtn;
+	LLButton* mTearOffBtn;
+	LLButton* mCloseBtn;
+
+private:
+	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
+	void updateHeaderAndToolbar();
+};
+
+
+#endif // LL_IMCONVERSATION_H
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index cd795fcfc7..5339bcb936 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -41,10 +41,9 @@
 #include "llfloaterreg.h"
 #include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
 #include "llinventoryfunctions.h"
-#include "lllayoutstack.h"
+//#include "lllayoutstack.h"
 #include "lllineeditor.h"
 #include "lllogchat.h"
-#include "llnearbychat.h"
 #include "llpanelimcontrolpanel.h"
 #include "llscreenchannel.h"
 #include "llsyswellwindow.h"
@@ -60,18 +59,12 @@
 #include "llnotificationmanager.h"
 
 LLIMFloater::LLIMFloater(const LLUUID& session_id)
-  : LLTransientDockableFloater(NULL, true, session_id),
-	mControlPanel(NULL),
-	mSessionID(session_id),
+  : LLIMConversation(session_id),
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
 	mInputEditor(NULL),
-	mCloseBtn(NULL),
-	mExpandCollapseBtn(NULL),
-	mTearOffBtn(NULL),
 	mSavedTitle(),
 	mTypingStart(),
-	mIsP2PChat(false),
 	mShouldSendTypingState(false),
 	mChatHistory(NULL),
 	mMeTyping(false),
@@ -81,6 +74,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mPositioned(false),
 	mSessionInitialized(false)
 {
+	mIsNearbyChat = false;
+
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
 	if (mSession)
@@ -97,7 +92,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 		case IM_SESSION_GROUP_START:
 			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
 			break;
-		case IM_SESSION_INVITE:		
+		case IM_SESSION_INVITE:
 			if (gAgent.isInGroup(mSessionID))
 			{
 				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
@@ -116,60 +111,30 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
 
 	setDocked(true);
-	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
-			boost::bind(&LLIMFloater::onIMSessionMenuItemClicked,  this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
-			boost::bind(&LLIMFloater::onIMCompactExpandedMenuItemCheck, this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
-			boost::bind(&LLIMFloater::onIMShowModesMenuItemCheck,   this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
-			boost::bind(&LLIMFloater::onIMShowModesMenuItemEnable,  this, _2));
-}
-
-bool LLIMFloater::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-	bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
-
-	return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
-}
-
-bool LLIMFloater::onIMShowModesMenuItemCheck(const LLSD& userdata)
-{
-	return gSavedSettings.getBOOL(userdata.asString());
 }
 
-// enable/disable states for the "show time" and "show names" items of the show-modes menu
-bool LLIMFloater::onIMShowModesMenuItemEnable(const LLSD& userdata)
+// static
+void* LLIMFloater::createPanelGroupControl(void* userdata)
 {
-	std::string item = userdata.asString();
-	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
-	bool is_not_names = (item != "IMShowNamesForP2PConv");
-	return (plain_text && (is_not_names || mIsP2PChat));
+	LLIMFloater *self = (LLIMFloater*) userdata;
+	self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID);
+	self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
+	return self->mControlPanel;
 }
 
-void LLIMFloater::onIMSessionMenuItemClicked(const LLSD& userdata)
+// static
+void* LLIMFloater::createPanelAdHocControl(void* userdata)
 {
-	std::string item = userdata.asString();
-
-	if (item == "compact_view" || item == "expanded_view")
-	{
-		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
-	}
-	else
-	{
-		bool prev_value = gSavedSettings.getBOOL(item);
-		gSavedSettings.setBOOL(item, !prev_value);
-	}
-
-	LLIMFloater::processChatHistoryStyleUpdate();
-	LLNearbyChat::processChatHistoryStyleUpdate();
+	LLIMFloater *self = (LLIMFloater*) userdata;
+	self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID);
+	self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml");
+	return self->mControlPanel;
 }
 
 void LLIMFloater::onFocusLost()
 {
 	LLIMModel::getInstance()->resetActiveSessionID();
-	
+
 	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, false);
 }
 
@@ -185,19 +150,6 @@ void LLIMFloater::onFocusReceived()
 	}
 }
 
-/*virtual*/
-void LLIMFloater::onOpen(const LLSD& key)
-{
-	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
-	if (host_floater)
-	{
-		// Show the messages pane when opening a floater hosted in the Conversations
-		host_floater->collapseMessagesPane(false);
-	}
-
-	updateHeaderAndToolbar();
-}
-
 // virtual
 void LLIMFloater::onClose(bool app_quitting)
 {
@@ -219,10 +171,9 @@ void LLIMFloater::newIMCallback(const LLSD& data)
 		LLUUID session_id = data["session_id"].asUUID();
 
 		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-		if (floater == NULL) return;
 
         // update if visible, otherwise will be updated when opened
-		if (floater->getVisible())
+		if (floater && floater->getVisible())
 		{
 			floater->updateMessages();
 		}
@@ -255,38 +206,39 @@ void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
 
 void LLIMFloater::sendMsg()
 {
-	if (!gAgent.isGodlike() 
-		&& (mDialog == IM_NOTHING_SPECIAL)
-		&& mOtherParticipantUUID.isNull())
-	{
-		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
-		return;
-	}
-
-	if (mInputEditor)
+	if (gAgent.isGodlike()
+		|| (mDialog != IM_NOTHING_SPECIAL)
+		|| !mOtherParticipantUUID.isNull())
 	{
-		LLWString text = mInputEditor->getConvertedText();
-		if(!text.empty())
+		if (mInputEditor)
 		{
-			// Truncate and convert to UTF8 for transport
-			std::string utf8_text = wstring_to_utf8str(text);
-			utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
-			
-			if (mSessionInitialized)
+			LLWString text = mInputEditor->getConvertedText();
+			if(!text.empty())
 			{
-				LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
-			}
-			else
-			{
-				//queue up the message to send once the session is initialized
-				mQueuedMsgsForInit.append(utf8_text);
-			}
+				// Truncate and convert to UTF8 for transport
+				std::string utf8_text = wstring_to_utf8str(text);
+				utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
 
-			mInputEditor->setText(LLStringUtil::null);
+				if (mSessionInitialized)
+				{
+					LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
+				}
+				else
+				{
+					//queue up the message to send once the session is initialized
+					mQueuedMsgsForInit.append(utf8_text);
+				}
+
+				mInputEditor->setText(LLStringUtil::null);
 
-			updateMessages();
+				updateMessages();
+			}
 		}
 	}
+	else
+	{
+		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
+	}
 }
 
 LLIMFloater::~LLIMFloater()
@@ -312,28 +264,6 @@ BOOL LLIMFloater::postBuild()
 
 	boundVoiceChannel();
 
-	mCloseBtn = getChild<LLButton>("close_btn");
-	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
-
-	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
-	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
-	if (mControlPanel)
-	{
-	mControlPanel->setSessionId(mSessionID);
-	mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
-
-		mExpandCollapseBtn->setImageOverlay(
-				getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon"));
-	}
-	else
-	{
-		mExpandCollapseBtn->setEnabled(false);
-		getChild<LLLayoutPanel>("im_control_panel_holder")->setVisible(false);
-	}
-
-	mTearOffBtn = getChild<LLButton>("tear_off_btn");
-	mTearOffBtn->setCommitCallback(boost::bind(&LLIMFloater::onTearOffClicked, this));
 
 	mInputEditor = getChild<LLLineEditor>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
@@ -386,21 +316,7 @@ BOOL LLIMFloater::postBuild()
 	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
 	//see LLFloaterIMPanel for how it is done (IB)
 
-	if(isChatMultiTab())
-	{
-		return LLFloater::postBuild();
-	}
-	else
-	{
-		return LLDockableFloater::postBuild();
-	}
-}
-
-void LLIMFloater::onTearOffClicked()
-{
-	onClickTearOff(this);
-
-	updateHeaderAndToolbar();
+	return LLIMConversation::postBuild();
 }
 
 void LLIMFloater::boundVoiceChannel()
@@ -412,37 +328,29 @@ void LLIMFloater::boundVoiceChannel()
 				boost::bind(&LLIMFloater::onVoiceChannelStateChanged, this, _1, _2));
 
 		//call (either p2p, group or ad-hoc) can be already in started state
-		updateCallState(voice_channel->getState());
+		bool callIsActive = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+		updateCallBtnState(callIsActive);
 	}
 }
 
-void LLIMFloater::updateCallState(LLVoiceChannel::EState state)
-{
-	bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
-	getChild<LLButton>("voice_call_btn")->setImageOverlay(
-			is_call_started? getString("call_btn_stop") : getString("call_btn_start"));
-    enableDisableCallBtn();
-
-}
-
 void LLIMFloater::enableDisableCallBtn()
 {
 	bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled()
 			&& LLVoiceClient::getInstance()->isVoiceWorking();
 
-	if (!mSession)
+	if (mSession)
+	{
+		bool session_initialized = mSession->mSessionInitialized;
+		bool callback_enabled = mSession->mCallBackEnabled;
+
+		BOOL enable_connect =
+				session_initialized && voice_enabled && callback_enabled;
+		getChildView("voice_call_btn")->setEnabled(enable_connect);
+	}
+	else
 	{
 		getChildView("voice_call_btn")->setEnabled(false);
-		return;
 	}
-
-	bool session_initialized = mSession->mSessionInitialized;
-	bool callback_enabled = mSession->mCallBackEnabled;
-
-	BOOL enable_connect = session_initialized
-		&& voice_enabled
-		&& callback_enabled;
-	getChildView("voice_call_btn")->setEnabled(enable_connect);
 }
 
 
@@ -470,18 +378,17 @@ void LLIMFloater::onCallButtonClicked()
 
 void LLIMFloater::onChange(EStatusType status, const std::string &channelURI, bool proximal)
 {
-	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+	if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL)
 	{
-		return;
+		enableDisableCallBtn();
 	}
-
-	enableDisableCallBtn();
 }
 
 void LLIMFloater::onVoiceChannelStateChanged(
 		const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
 {
-	updateCallState(new_state);
+	bool callIsActive = new_state >= LLVoiceChannel::STATE_CALL_STARTED;
+	updateCallBtnState(callIsActive);
 }
 
 void LLIMFloater::updateSessionName(const std::string& ui_title,
@@ -516,48 +423,6 @@ void LLIMFloater::draw()
 	LLTransientDockableFloater::draw();
 }
 
-// static
-void* LLIMFloater::createPanelGroupControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*)userdata;
-	self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID);
-	self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
-	return self->mControlPanel;
-}
-
-// static
-void* LLIMFloater::createPanelAdHocControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*)userdata;
-	self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID);
-	self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml");
-	return self->mControlPanel;
-}
-
-void LLIMFloater::onSlide()
-{
-	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
-	if (host_floater)
-	{
-		// Hide the messages pane if a floater is hosted in the Conversations
-		host_floater->collapseMessagesPane(true);
-	}
-	else ///< floater is torn off
-	{
-		if (mControlPanel)
-		{
-			bool expand = !mControlPanel->getParent()->getVisible();
-
-			// Expand/collapse the IM control panel
-			mControlPanel->getParent()->setVisible(expand);
-
-			gSavedSettings.setBOOL("IMShowControlPanel", expand);
-
-			mExpandCollapseBtn->setImageOverlay(getString(expand ? "collapse_icon" : "expand_icon"));
-		}
-	}
-}
-
 //static
 LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 {
@@ -635,6 +500,22 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 
 	return floater;
 }
+//static
+LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
+{
+    LLIMFloater* conversation =
+    		LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+
+	return conversation;
+}
+
+LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
+{
+	LLIMFloater* conversation =
+				LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
+
+	return conversation;
+}
 
 void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 {
@@ -697,6 +578,8 @@ void LLIMFloater::setVisible(BOOL visible)
 
 BOOL LLIMFloater::getVisible()
 {
+	bool visible;
+
 	if(isChatMultiTab())
 	{
 		LLIMFloaterContainer* im_container =
@@ -708,17 +591,21 @@ BOOL LLIMFloater::getVisible()
 		//torn off floater is always inactive
 		if (!is_active && getHost() != im_container)
 		{
-			return LLTransientDockableFloater::getVisible();
+			visible = LLTransientDockableFloater::getVisible();
+		}
+		else
+		{
+			// getVisible() returns TRUE when Tabbed IM window is minimized.
+			visible = is_active && !im_container->isMinimized()
+						&& im_container->getVisible();
 		}
-
-		// getVisible() returns TRUE when Tabbed IM window is minimized.
-		return is_active && !im_container->isMinimized()
-				&& im_container->getVisible();
 	}
 	else
 	{
-		return LLTransientDockableFloater::getVisible();
+		visible = LLTransientDockableFloater::getVisible();
 	}
+
+	return visible;
 }
 
 //static
@@ -748,17 +635,6 @@ bool LLIMFloater::toggle(const LLUUID& session_id)
 	return true;
 }
 
-//static
-LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
-{
-	return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
-LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
-{
-	return LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
 void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 {
 	mSessionInitialized = true;
@@ -782,14 +658,15 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
 
 	//need to send delayed messaged collected while waiting for session initialization
-	if (!mQueuedMsgsForInit.size())
-		return;
-	LLSD::array_iterator iter;
-	for ( iter = mQueuedMsgsForInit.beginArray();
-			iter != mQueuedMsgsForInit.endArray(); ++iter)
+	if (mQueuedMsgsForInit.size())
 	{
-		LLIMModel::sendMessage(iter->asString(), mSessionID,
-			mOtherParticipantUUID, mDialog);
+		LLSD::array_iterator iter;
+		for ( iter = mQueuedMsgsForInit.beginArray();
+				iter != mQueuedMsgsForInit.endArray(); ++iter)
+		{
+			LLIMModel::sendMessage(iter->asString(), mSessionID,
+				mOtherParticipantUUID, mDialog);
+		}
 	}
 }
 
@@ -878,16 +755,16 @@ void LLIMFloater::updateMessages()
 			if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
 			{
 				if (++iter == iter_end)
-				{
-					break;
-				}
-				else
-				{
-					mLastMessageIndex++;
-				}
-			}
-		}
-	}
+			    {
+				    break;
+			    }
+			    else
+			    {
+				    mLastMessageIndex++;
+			    }
+		    }
+	    }
+    }
 }
 
 void LLIMFloater::reloadMessages()
@@ -895,6 +772,7 @@ void LLIMFloater::reloadMessages()
 	mChatHistory->clear();
 	mLastMessageIndex = -1;
 	updateMessages();
+	mInputEditor->setFont(LLViewerChat::getChatFont());
 }
 
 // static
@@ -923,28 +801,22 @@ void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userd
 // static
 void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
 {
-	LLIMFloater* self = (LLIMFloater*)userdata;
+	LLIMFloater* self = (LLIMFloater*) userdata;
 	std::string text = self->mInputEditor->getText();
-	if (!text.empty())
-	{
-		self->setTyping(true);
-	}
-	else
-	{
-		// Deleting all text counts as stopping typing.
-		self->setTyping(false);
-	}
+
+	// Deleting all text counts as stopping typing.
+	self->setTyping(!text.empty());
 }
 
 void LLIMFloater::setTyping(bool typing)
 {
-	if ( typing )
+	if (typing)
 	{
 		// Started or proceeded typing, reset the typing timeout timer
 		mTypingTimeoutTimer.reset();
 	}
 
-	if ( mMeTyping != typing )
+	if (mMeTyping != typing)
 	{
 		// Typing state is changed
 		mMeTyping = typing;
@@ -956,24 +828,16 @@ void LLIMFloater::setTyping(bool typing)
 
 	// Don't want to send typing indicators to multiple people, potentially too
 	// much network traffic. Only send in person-to-person IMs.
-	if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
+	if (mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL)
 	{
-		if ( mMeTyping )
-		{
-			if ( mTypingTimer.getElapsedTimeF32() > 1.f )
-			{
-				// Still typing, send 'start typing' notification
-				LLIMModel::instance().sendTypingState(mSessionID,
-						mOtherParticipantUUID, TRUE);
-				mShouldSendTypingState = false;
-			}
-		}
-		else
+		// Still typing, send 'start typing' notification or
+		// send 'stop typing' notification immediately
+		if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f)
 		{
-			// Send 'stop typing' notification immediately
 			LLIMModel::instance().sendTypingState(mSessionID,
-					mOtherParticipantUUID, FALSE);
+					mOtherParticipantUUID, mMeTyping);
 			mShouldSendTypingState = false;
+
 		}
 	}
 
@@ -985,7 +849,7 @@ void LLIMFloater::setTyping(bool typing)
 
 void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
 {
-	if ( typing )
+	if (typing)
 	{
 		// other user started typing
 		addTypingIndicator(im_info);
@@ -999,10 +863,7 @@ void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
 
 void LLIMFloater::processAgentListUpdates(const LLSD& body)
 {
-	if (!body.isMap())
-		return;
-
-	if ( body.has("agent_updates") && body["agent_updates"].isMap() )
+	if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap())
 	{
 		LLSD agent_data = body["agent_updates"].get(gAgentID.asString());
 		if (agent_data.isMap() && agent_data.has("info"))
@@ -1011,7 +872,7 @@ void LLIMFloater::processAgentListUpdates(const LLSD& body)
 
 			if (agent_info.has("mutes"))
 			{
-				BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean(); 
+				BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean();
 				mInputEditor->setEnabled(!moderator_muted_text);
 				std::string label;
 				if (moderator_muted_text)
@@ -1027,27 +888,11 @@ void LLIMFloater::processAgentListUpdates(const LLSD& body)
 	}
 }
 
-void LLIMFloater::processChatHistoryStyleUpdate()
-{
-	LLFontGL* font = LLViewerChat::getChatFont();
-	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
-	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
-		 iter != inst_list.end(); ++iter)
-	{
-		LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
-		if (floater)
-		{
-			floater->reloadMessages();
-			floater->mInputEditor->setFont(font);
-		}
-	}
-}
-
 void LLIMFloater::processSessionUpdate(const LLSD& session_update)
 {
 	// *TODO : verify following code when moderated mode will be implemented
-	if ( false && session_update.has("moderated_mode") &&
-		 session_update["moderated_mode"].has("voice") )
+	if (false && session_update.has("moderated_mode") &&
+			session_update["moderated_mode"].has("voice"))
 	{
 		BOOL voice_moderated = session_update["moderated_mode"]["voice"];
 		const std::string session_label = LLIMModel::instance().getName(mSessionID);
@@ -1069,14 +914,14 @@ void LLIMFloater::processSessionUpdate(const LLSD& session_update)
 }
 
 BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
-						   BOOL drop, EDragAndDropType cargo_type,
-						   void *cargo_data, EAcceptance *accept,
-						   std::string& tooltip_msg)
+		BOOL drop, EDragAndDropType cargo_type,
+		void *cargo_data, EAcceptance *accept,
+		std::string& tooltip_msg)
 {
 	if (mDialog == IM_NOTHING_SPECIAL)
 	{
 		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
-												 cargo_type, cargo_data, accept);
+				cargo_type, cargo_data, accept);
 	}
 
 	// handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites
@@ -1086,14 +931,14 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
 
 		if (cargo_type == DAD_CALLINGCARD)
 		{
-			if (dropCallingCard((LLInventoryItem*)cargo_data, drop))
+			if (dropCallingCard((LLInventoryItem*) cargo_data, drop))
 			{
 				*accept = ACCEPT_YES_MULTI;
 			}
 		}
 		else if (cargo_type == DAD_CATEGORY)
 		{
-			if (dropCategory((LLInventoryCategory*)cargo_data, drop))
+			if (dropCategory((LLInventoryCategory*) cargo_data, drop))
 			{
 				*accept = ACCEPT_YES_MULTI;
 			}
@@ -1105,9 +950,9 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
 BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
 {
 	BOOL rv = isInviteAllowed();
-	if(rv && item && item->getCreatorUUID().notNull())
+	if (rv && item && item->getCreatorUUID().notNull())
 	{
-		if(drop)
+		if (drop)
 		{
 			uuid_vec_t ids;
 			ids.push_back(item->getCreatorUUID());
@@ -1125,26 +970,26 @@ BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
 BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
 {
 	BOOL rv = isInviteAllowed();
-	if(rv && category)
+	if (rv && category)
 	{
 		LLInventoryModel::cat_array_t cats;
 		LLInventoryModel::item_array_t items;
 		LLUniqueBuddyCollector buddies;
 		gInventory.collectDescendentsIf(category->getUUID(),
-										cats,
-										items,
-										LLInventoryModel::EXCLUDE_TRASH,
-										buddies);
+				cats,
+				items,
+				LLInventoryModel::EXCLUDE_TRASH,
+				buddies);
 		S32 count = items.count();
-		if(count == 0)
+		if (count == 0)
 		{
 			rv = FALSE;
 		}
-		else if(drop)
+		else if (drop)
 		{
 			uuid_vec_t ids;
 			ids.reserve(count);
-			for(S32 i = 0; i < count; ++i)
+			for (S32 i = 0; i < count; ++i)
 			{
 				ids.push_back(items.get(i)->getCreatorUUID());
 			}
@@ -1156,11 +1001,11 @@ BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
 
 BOOL LLIMFloater::isInviteAllowed() const
 {
-	return ( (IM_SESSION_CONFERENCE_START == mDialog)
-			 || (IM_SESSION_INVITE == mDialog) );
+	return ((IM_SESSION_CONFERENCE_START == mDialog)
+			|| (IM_SESSION_INVITE == mDialog));
 }
 
-class LLSessionInviteResponder : public LLHTTPClient::Responder
+class LLSessionInviteResponder: public LLHTTPClient::Responder
 {
 public:
 	LLSessionInviteResponder(const LLUUID& session_id)
@@ -1181,60 +1026,60 @@ private:
 BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 {
 	LLViewerRegion* region = gAgent.getRegion();
-	if (!region)
+	bool is_region_exist = !!region;
+
+	if (is_region_exist)
 	{
-		return FALSE;
-	}
+		S32 count = ids.size();
 
-	S32 count = ids.size();
+		if (isInviteAllowed() && (count > 0))
+		{
+			llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
 
-	if( isInviteAllowed() && (count > 0) )
-	{
-		llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
+			std::string url = region->getCapability("ChatSessionRequest");
 
-		std::string url = region->getCapability("ChatSessionRequest");
+			LLSD data;
 
-		LLSD data;
+			data["params"] = LLSD::emptyArray();
+			for (int i = 0; i < count; i++)
+			{
+				data["params"].append(ids[i]);
+			}
 
-		data["params"] = LLSD::emptyArray();
-		for (int i = 0; i < count; i++)
+			data["method"] = "invite";
+			data["session-id"] = mSessionID;
+			LLHTTPClient::post(
+					url,
+					data,
+					new LLSessionInviteResponder(mSessionID));
+		}
+		else
 		{
-			data["params"].append(ids[i]);
+			llinfos << "LLIMFloater::inviteToSession -"
+					<< " no need to invite agents for "
+					<< mDialog << llendl;
+			// successful add, because everyone that needed to get added
+			// was added.
 		}
-
-		data["method"] = "invite";
-		data["session-id"] = mSessionID;
-		LLHTTPClient::post(
-			url,
-			data,
-				new LLSessionInviteResponder(mSessionID));
-	}
-	else
-	{
-		llinfos << "LLIMFloater::inviteToSession -"
-				<< " no need to invite agents for "
-				<< mDialog << llendl;
-		// successful add, because everyone that needed to get added
-		// was added.
 	}
 
-	return TRUE;
+	return is_region_exist;
 }
 
 void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
 {
 	// We may have lost a "stop-typing" packet, don't add it twice
-	if ( im_info && !mOtherTyping )
+	if (im_info && !mOtherTyping)
 	{
 		mOtherTyping = true;
 
 		// Save and set new title
 		mSavedTitle = getTitle();
-		setTitle (mTypingStart);
+		setTitle(mTypingStart);
 
 		// Update speaker
 		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		if ( speaker_mgr )
+		if (speaker_mgr)
 		{
 			speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
 		}
@@ -1243,18 +1088,18 @@ void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
 
 void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 {
-	if ( mOtherTyping )
+	if (mOtherTyping)
 	{
 		mOtherTyping = false;
 
 		// Revert the title to saved one
 		setTitle(mSavedTitle);
 
-		if ( im_info )
+		if (im_info)
 		{
 			// Update speaker
 			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-			if ( speaker_mgr )
+			if (speaker_mgr)
 			{
 				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
 			}
@@ -1262,59 +1107,6 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 	}
 }
 
-void LLIMFloater::updateHeaderAndToolbar()
-{
-	bool is_hosted = getHost() != NULL;
-
-	if (is_hosted)
-	{
-		for (S32 i = 0; i < BUTTON_COUNT; i++)
-		{
-			if (!mButtons[i])
-			{
-				continue;
-			}
-
-			// Hide the standard header buttons in a docked IM floater.
-			mButtons[i]->setVisible(false);
-	}
-}
-
-	bool is_control_panel_visible = false;
-	if (mControlPanel)
-	{
-		// Control panel should be visible only in torn off floaters.
-		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
-		mControlPanel->getParent()->setVisible(is_control_panel_visible);
-	}
-
-	// Display collapse image (<<) if the floater is hosted
-	// or if it is torn off but has an open control panel.
-	bool is_expanded = is_hosted || is_control_panel_visible;
-	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
-
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
-	if (session)
-	{
-		// The button (>>) should be disabled for torn off P2P conversations.
-		mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType());
-	}
-	else
-	{
-		llwarns << "IM session not found." << llendl;
-	}
-
-	if (mDragHandle)
-	{
-		// toggle floater's drag handle and title visibility
-		mDragHandle->setVisible(!is_hosted);
-	}
-
-	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
-
-	mCloseBtn->setVisible(is_hosted);
-}
-
 // static
 void LLIMFloater::closeHiddenIMToasts()
 {
@@ -1351,14 +1143,6 @@ void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD&
 	return;
 }
 
-// static
-bool LLIMFloater::isChatMultiTab()
-{
-	// Restart is required in order to change chat window type.
-	static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1;
-	return is_single_window;
-}
-
 // static
 void LLIMFloater::initIMFloater()
 {
@@ -1390,28 +1174,32 @@ void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
 
 void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
 {
+	LLIMFloater::addToHost(session_id);
+}
 
-	if (isChatMultiTab())
+void LLIMFloater::addToHost(const LLUUID& session_id)
+{
+	if (LLIMConversation::isChatMultiTab())
 	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
 		if (!im_box)
-			return;
-
-		if (LLIMFloater::findInstance(session_id))
-			return;
-
-		LLIMFloater* new_tab = LLIMFloater::getInstance(session_id);
+	    {
+			im_box = LLIMFloaterContainer::getInstance();
+	    }
 
-		im_box->addFloater(new_tab, FALSE, LLTabContainer::END);
+		if (im_box && !LLIMFloater::findInstance(session_id))
+		{
+			LLIMFloater* new_tab = LLIMFloater::getInstance(session_id);
+			im_box->addFloater(new_tab, FALSE, LLTabContainer::END);
+		}
 	}
-
 }
 
 void	LLIMFloater::onClickCloseBtn()
 {
 
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				mSessionID);
+			mSessionID);
 
 	if (session == NULL)
 	{
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 8e7ab4cc21..c7793f73eb 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -28,17 +28,16 @@
 #define LL_IMFLOATER_H
 
 #include "llimview.h"
+#include "llimconversation.h"
 #include "llinstantmessage.h"
 #include "lllogchat.h"
 #include "lltooldraganddrop.h"
 #include "llvoicechannel.h"
 #include "llvoiceclient.h"
-#include "lltransientdockablefloater.h"
 
 class LLAvatarName;
 class LLButton;
 class LLLineEditor;
-class LLPanelChatControlPanel;
 class LLChatHistory;
 class LLInventoryItem;
 class LLInventoryCategory;
@@ -48,8 +47,8 @@ class LLInventoryCategory;
  * optionally "docked" to the bottom tray.
  */
 class LLIMFloater
-    : public LLTransientDockableFloater
-	, public LLVoiceClientStatusObserver
+    : public LLVoiceClientStatusObserver
+    , public LLIMConversation
 {
 	LOG_CLASS(LLIMFloater);
 public:
@@ -64,11 +63,16 @@ public:
 	// Check typing timeout timer.
 	/*virtual*/ void draw();
 
+	static void* createPanelGroupControl(void* userdata);
+	static void* createPanelAdHocControl(void* userdata);
+
+	static LLIMFloater* findInstance(const LLUUID& session_id);
+	static LLIMFloater* getInstance(const LLUUID& session_id);
+	static void addToHost(const LLUUID& session_id);
+
 	// LLFloater overrides
-	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
-
 	// Make IM conversion visible and update the message history
 	static LLIMFloater* show(const LLUUID& session_id);
 
@@ -76,10 +80,6 @@ public:
 	// Returns true iff panel became visible
 	static bool toggle(const LLUUID& session_id);
 
-	static LLIMFloater* findInstance(const LLUUID& session_id);
-
-	static LLIMFloater* getInstance(const LLUUID& session_id);
-
 	void sessionInitReplyReceived(const LLUUID& im_session_id);
 
 	// get new messages from LLIMModel
@@ -102,6 +102,7 @@ public:
 	void onChange(EStatusType status, const std::string &channelURI,
 			bool proximal);
 
+	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
 	virtual void onVoiceChannelStateChanged(
 			const LLVoiceChannel::EState& old_state,
 			const LLVoiceChannel::EState& new_state);
@@ -110,28 +111,18 @@ public:
 	void processAgentListUpdates(const LLSD& body);
 	void processSessionUpdate(const LLSD& session_update);
 
-	static void processChatHistoryStyleUpdate();
-
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
 			BOOL drop, EDragAndDropType cargo_type,
 			void *cargo_data, EAcceptance *accept,
 			std::string& tooltip_msg);
 
-	/**
-	 * Returns true if chat is displayed in multi tabbed floater
-	 *         false if chat is displayed in multiple windows
-	 */
-	static bool isChatMultiTab();
 
 	static void initIMFloater();
 
 	//used as a callback on receiving new IM message
 	static void sRemoveTypingIndicator(const LLSD& data);
-
 	static void onIMChicletCreated(const LLUUID& session_id);
 
-	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
-
 protected:
 	/* virtual */ void onClickCloseBtn();
 
@@ -156,23 +147,13 @@ private:
 	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
 	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
 	void setTyping(bool typing);
-	void onSlide();
-	static void* createPanelGroupControl(void* userdata);
-	static void* createPanelAdHocControl(void* userdata);
 
-	void onTearOffClicked();
-
-	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
-	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
-	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
-	void onIMSessionMenuItemClicked(const LLSD& userdata);
 	void onCallButtonClicked();
 
-	void boundVoiceChannel();
-	void enableDisableCallBtn();
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn();
 
-	// refresh a visual state of the Call button
-	void updateCallState(LLVoiceChannel::EState state);
+	void boundVoiceChannel();
 
 	// Add the "User is typing..." indicator.
 	void addTypingIndicator(const LLIMInfo* im_info);
@@ -180,15 +161,11 @@ private:
 	// Remove the "User is typing..." indicator.
 	void removeTypingIndicator(const LLIMInfo* im_info = NULL);
 
-	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
-	void updateHeaderAndToolbar();
-
 	static void closeHiddenIMToasts();
 
 	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
 
-	LLPanelChatControlPanel* mControlPanel;
-	LLUUID mSessionID;
+
 	LLIMModel::LLIMSession* mSession;
 	S32 mLastMessageIndex;
 
@@ -204,7 +181,6 @@ private:
 	bool mMeTyping;
 	bool mOtherTyping;
 	bool mShouldSendTypingState;
-	bool mIsP2PChat;
 	LLFrameTimer mTypingTimer;
 	LLFrameTimer mTypingTimeoutTimer;
 
@@ -213,10 +189,6 @@ private:
 
 	// connection to voice channel state change signal
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
-
-	LLButton* mCloseBtn;
-	LLButton* mExpandCollapseBtn;
-	LLButton* mTearOffBtn;
 };
 
 #endif  // LL_IMFLOATER_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index b051440589..f72ddef412 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -31,6 +31,7 @@
 
 #include "llfloaterreg.h"
 #include "lllayoutstack.h"
+#include "llnearbychatbar.h"
 
 #include "llagent.h"
 #include "llavatariconctrl.h"
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 18d39b7aa4..c3ac1d32cb 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -41,7 +41,7 @@
 #include "lltextutil.h"
 #include "lltrans.h"
 #include "lluictrlfactory.h"
-
+#include "llimconversation.h"
 #include "llagent.h"
 #include "llagentui.h"
 #include "llappviewer.h"
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 3c4b0b9aae..497690d656 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -25,7 +25,6 @@
  */
 
 #include "llviewerprecompiledheaders.h"
-#include "llnearbychat.h"
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
 #include "llrootview.h"
@@ -93,9 +92,9 @@ static const S32 RESIZE_BAR_THICKNESS = 3;
 
 static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat");
 
-LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p) 
-:	LLPanel(p),
-	mChatHistory(NULL)
+LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p)
+	: LLPanel(p),
+	  mChatHistory(NULL)
 {
 }
 
@@ -117,10 +116,7 @@ BOOL LLNearbyChat::postBuild()
 
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
-	if(!LLPanel::postBuild())
-		return false;
-	
-	return true;
+    return LLPanel::postBuild();
 }
 
 
@@ -139,8 +135,7 @@ void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args)
 		chat_args["use_plain_text_chat_history"] =
 				gSavedSettings.getBOOL("PlainTextChatHistory");
 		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
-		chat_args["show_names_for_p2p_conv"] = false
-				|| gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+		chat_args["show_names_for_p2p_conv"] = true;
 
 		mChatHistory->appendMessage(chat, chat_args);
 	}
@@ -223,7 +218,7 @@ void LLNearbyChat::getAllowedRect(LLRect& rect)
 	rect = gViewerWindow->getWorldViewRectScaled();
 }
 
-void LLNearbyChat::updateChatHistoryStyle()
+void LLNearbyChat::reloadMessages()
 {
 	mChatHistory->clear();
 
@@ -236,15 +231,6 @@ void LLNearbyChat::updateChatHistoryStyle()
 	}
 }
 
-//static 
-void LLNearbyChat::processChatHistoryStyleUpdate()
-{
-	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
-	if(nearby_chat)
-		nearby_chat->updateChatHistoryStyle();
-}
-
 void LLNearbyChat::loadHistory()
 {
 	LLSD do_not_log;
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 47f4de1c6d..62a41c17cb 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -29,13 +29,13 @@
 
 #include "llscrollbar.h"
 #include "llviewerchat.h"
-#include "llfloater.h"
+#include "llpanel.h"
 
 class LLResizeBar;
 class LLChatHistory;
 
 class LLNearbyChat
-: public LLPanel
+	: public LLPanel
 {
 public:
 	LLNearbyChat(const Params& p = LLPanel::getDefaultParams());
@@ -56,12 +56,8 @@ public:
 	
 	/*virtual*/ void	setVisible(BOOL visible);
 	
-	virtual void updateChatHistoryStyle();
-
-	static void processChatHistoryStyleUpdate();
-
 	void loadHistory();
-
+    void reloadMessages();
 	static LLNearbyChat* getInstance();
 	void removeScreenChat();
 
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index b4224e30e6..82c00253e8 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -31,7 +31,7 @@
 #include "llappviewer.h"
 #include "llfloaterreg.h"
 #include "lltrans.h"
-
+#include "llimfloatercontainer.h"
 #include "llfirstuse.h"
 #include "llnearbychatbar.h"
 #include "llagent.h"
@@ -54,7 +54,7 @@
 
 S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
 
-const S32 EXPANDED_HEIGHT = 300;
+const S32 EXPANDED_HEIGHT = 266;
 const S32 COLLAPSED_HEIGHT = 60;
 const S32 EXPANDED_MIN_HEIGHT = 150;
 
@@ -72,7 +72,7 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
 };
 
 LLNearbyChatBar::LLNearbyChatBar(const LLSD& key)
-:	LLFloater(key),
+:	LLIMConversation(key),
 	mChatBox(NULL),
 	mNearbyChat(NULL),
 	mOutputMonitor(NULL),
@@ -116,14 +116,44 @@ BOOL LLNearbyChatBar::postBuild()
 	// Register for font change notifications
 	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
 
+	// childSetAction("voice_call_btn", boost::bind(&LLNearbyChatBar::onCallButtonClicked, this));
+
 	enableResizeCtrls(true, true, false);
 
-	return TRUE;
+	addToHost();
+
+	return LLIMConversation::postBuild();;
+}
+
+void LLNearbyChatBar::onCallButtonClicked()
+{
+	LLAgent::toggleMicrophone(NULL);
+}
+
+void LLNearbyChatBar::enableDisableCallBtn()
+{
+	// bool btn_enabled = LLAgent::isActionAllowed("speak");
+
+	getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/);
+}
+
+void LLNearbyChatBar::addToHost()
+{
+	if (LLIMConversation::isChatMultiTab())
+	{
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+
+		if (im_box)
+		{
+			im_box->addFloater(this, FALSE, LLTabContainer::END);
+		}
+	}
 }
 
 // virtual
 void LLNearbyChatBar::onOpen(const LLSD& key)
 {
+	LLIMConversation::onOpen(key);
 	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 }
 
@@ -160,6 +190,12 @@ LLNearbyChatBar* LLNearbyChatBar::getInstance()
 	return LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar");
 }
 
+//static
+//LLNearbyChatBar* LLNearbyChatBar::findInstance()
+//{
+//	return LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar");
+//}
+
 void LLNearbyChatBar::showHistory()
 {
 	openFloater();
@@ -178,7 +214,8 @@ void LLNearbyChatBar::showTranslationCheckbox(BOOL show)
 void LLNearbyChatBar::draw()
 {
 	displaySpeakingIndicator();
-	LLFloater::draw();
+	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
+	LLIMConversation::draw();
 }
 
 std::string LLNearbyChatBar::getCurrentChat()
@@ -206,22 +243,24 @@ BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::strin
 	U32 in_len = in_str.length();
 	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
 	
-	for (S32 n = 0; n < cnt; n++)
-	{
-		if (in_len > sChatTypeTriggers[n].name.length())
-			continue;
-
-		std::string trigger_trunc = sChatTypeTriggers[n].name;
-		LLStringUtil::truncate(trigger_trunc, in_len);
+	bool string_was_found = false;
 
-		if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+	for (S32 n = 0; n < cnt && !string_was_found; n++)
+	{
+		if (in_len <= sChatTypeTriggers[n].name.length())
 		{
-			*out_str = sChatTypeTriggers[n].name;
-			return TRUE;
+			std::string trigger_trunc = sChatTypeTriggers[n].name;
+			LLStringUtil::truncate(trigger_trunc, in_len);
+
+			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+			{
+				*out_str = sChatTypeTriggers[n].name;
+				string_was_found = true;
+			}
 		}
 	}
 
-	return FALSE;
+	return string_was_found;
 }
 
 void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
@@ -421,6 +460,11 @@ void LLNearbyChatBar::onToggleNearbyChatPanel()
 	gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible());
 }
 
+void LLNearbyChatBar::reloadMessages()
+{
+	LLNearbyChat::getInstance()->reloadMessages();
+}
+
 void LLNearbyChatBar::setMinimized(BOOL b)
 {
 	LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat");
@@ -531,20 +575,20 @@ void LLNearbyChatBar::startChat(const char* line)
 {
 	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
 
-	if (!cb )
-		return;
+	if (cb )
+	{
+		cb->setVisible(TRUE);
+		cb->setFocus(TRUE);
+		cb->mChatBox->setFocus(TRUE);
 
-	cb->setVisible(TRUE);
-	cb->setFocus(TRUE);
-	cb->mChatBox->setFocus(TRUE);
+		if (line)
+		{
+			std::string line_string(line);
+			cb->mChatBox->setText(line_string);
+		}
 
-	if (line)
-	{
-		std::string line_string(line);
-		cb->mChatBox->setText(line_string);
+		cb->mChatBox->setCursorToEnd();
 	}
-
-	cb->mChatBox->setCursorToEnd();
 }
 
 // Exit "chat mode" and do the appropriate focus changes
@@ -553,13 +597,13 @@ void LLNearbyChatBar::stopChat()
 {
 	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
 
-	if (!cb)
-		return;
-
-	cb->mChatBox->setFocus(FALSE);
+	if (cb)
+	{
+		cb->mChatBox->setFocus(FALSE);
 
- 	// stop typing animation
- 	gAgent.stopTyping();
+		// stop typing animation
+		gAgent.stopTyping();
+	}
 }
 
 // If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 8547cf0bce..e714c04498 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -27,26 +27,31 @@
 #ifndef LL_LLNEARBYCHATBAR_H
 #define LL_LLNEARBYCHATBAR_H
 
-#include "llfloater.h"
+#include "llimconversation.h"
 #include "llcombobox.h"
 #include "llgesturemgr.h"
 #include "llchat.h"
+#include "llnearbychat.h"
 #include "llvoiceclient.h"
 #include "lloutputmonitorctrl.h"
 #include "llspeakers.h"
 
-class LLNearbyChatBar :	public LLFloater
+class LLNearbyChatBar :	public LLIMConversation
 {
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
 	LLNearbyChatBar(const LLSD& key);
 	~LLNearbyChatBar() {}
 
-	virtual BOOL postBuild();
+	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 
 	static LLNearbyChatBar* getInstance();
+//	static LLNearbyChatBar* findInstance();
 
+	void addToHost();
+
+	void reloadMessages();
 	LLLineEditor* getChatBox() { return mChatBox; }
 
 	virtual void draw();
@@ -83,6 +88,11 @@ protected:
 
 	void displaySpeakingIndicator();
 
+	void onCallButtonClicked();
+
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn();
+
 	// Which non-zero channel did we last chat on?
 	static S32 sLastSpecialChatChannel;
 
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 63992462b3..7688525e13 100644
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
@@ -3,32 +3,151 @@
  open_positioning="specified"
  specified_left="10"
  specified_bottom="10"
- height="60"
+ background_visible="true"
+ default_tab_group="1"
+ height="355"
+ help_topic="chat_bar"
  layout="topleft"
- legacy_header_height="25"
- single_instance="true"
- title="NEARBY CHAT"
- save_rect="true"
- save_visibility="true"
- can_close="true"
+ name="chat_bar"
+ can_dock="false"
  can_minimize="true"
- help_topic="chat_bar"
- min_height="60"
- min_width="150"
+ can_close="true"
+ visible="false"
+ width="394"
  can_resize="true"
- default_tab_group="1"
- name="chat_bar"
- width="300">
+ can_tear_off="false"
+ min_width="250"
+ min_height="80"
+ single_instance="true"
+ title="Nearby chat">
+    <floater.string name="call_btn_start">VoicePTT_Off</floater.string>
+    <floater.string name="call_btn_stop">VoicePTT_On</floater.string>
+    <floater.string
+     name="collapse_icon"
+     value="TabIcon_Open_Off"/>
+    <floater.string
+     name="expand_icon"
+     value="TabIcon_Close_Off"/>
+    <floater.string
+     name="tear_off_icon"
+     value="tearoffbox.tga"/>
+    <floater.string
+     name="return_icon"
+     value="Icon_Dock_Foreground"/>
+     <view
+        follows="all"
+        layout="topleft"
+        name="contents_view"
+        top="0"
+        left="0"
+        height="355"
+        width="394">
+      <panel
+         follows="left|top|right"
+         layout="topleft"
+         name="toolbar_panel"
+         top="0"
+         left="0"
+         height="35"
+         width="394">         
+             <menu_button
+                 menu_filename="menu_im_session_showmodes.xml"
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Left_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Left_Selected"
+                 image_unselected="Toolbar_Left_Off"
+                 layout="topleft"
+                 left="5"
+                 name="view_options_btn"
+                 top="5"
+                 width="31" />
+             <button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="4"
+                 name="add_btn"
+                 width="31">
+                 <commit_callback
+                    function="Chats.add" />
+             </button>   
+             <button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Right_Over"
+                 image_overlay="VoicePTT_Off"
+                 image_selected="Toolbar_Right_Selected"
+                 image_unselected="Toolbar_Right_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="4"
+                 name="voice_call_btn"
+                 width="31">
+                 <commit_callback
+                    function="Chats.add" />
+             </button>
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Icon_Close_Foreground"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left="283"
+                 name="close_btn"
+                 width="31">
+             </button>
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TabIcon_Open_Off"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="5"
+                 name="expand_collapse_btn"
+                 width="31">
+             </button>
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="tearoffbox.tga"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="5"
+                 name="tear_off_btn"
+                 width="31">
+             </button>
+     </panel>
     <panel
-        top="20"
+        top="35"
+        left="0"
         class="panel_nearby_chat"
         follow="all"
-        width="300"
+        width="390"
         height="0"
         visible="false"
         filename="panel_nearby_chat.xml"
         name="nearby_chat" />
-    <panel width="300" 
+    <panel
+    	width="390"
+    	height="10"
+    	visible="true" />
+    <panel width="394" 
            height="31" 
            left="0" 
            name="bottom_panel"
@@ -39,18 +158,15 @@
         border_style="line"
         border_thickness="1"
         follows="left|right"
-        height="23"
+        height="20"
         label="Click here to chat."
         layout="topleft"
-        left_delta="7"
-        left="0"
+        left="1"
         max_length_bytes="1023"
         name="chat_box"
-        text_pad_left="5"
-        text_pad_right="25"
         tool_tip="Press Enter to say, Ctrl+Enter to shout"
         top="2"
-        width="255" />
+        width="384" />
       <output_monitor
         auto_update="true"
         follows="right"
@@ -65,6 +181,7 @@
         width="20" />
       <button
         follows="right"
+        visible="false"
         is_toggle="true"
         width="20"
         top="2"
@@ -81,4 +198,5 @@
         tool_tip="Shows/hides nearby chat log">
       </button>
     </panel>
+  </view>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
index d683116eb8..b415ba780d 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
@@ -1,20 +1,21 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel
  follows="all"
- height="300"
+ top="0"
+ bottom_delta="10"
  help_topic="nearby_chat"
  layout="topleft"
  name="nearby_chat"
- width="320">
+ width="394">
   <layout_stack
    follows="all"
-   height="295"
+   height="278"
    layout="topleft"
    left="0"
    name="stack"
    top="5"
    orientation="vertical"
-   width="320">
+   width="394">
     <layout_panel
      auto_resize="false"
      height="26"
@@ -23,7 +24,7 @@
      name="translate_chat_checkbox_lp"
      top_delta="0"
      visible="true"
-     width="313">
+     width="387">
       <check_box
        top="10"
        control_name="TranslateChat"
@@ -33,15 +34,15 @@
        layout="topleft"
        left="5"
        name="translate_chat_checkbox"
-       width="300" />
+       width="374" />
     </layout_panel>
     <layout_panel
      auto_resize="true"
-     height="277"
+     height="256"
      left_delta="0"
      layout="topleft"
      name="chat_history_lp"
-     width="318">
+     width="394">
       <chat_history
        bg_readonly_color="ChatHistoryBgColor"
        bg_writeable_color="ChatHistoryBgColor"
@@ -49,7 +50,7 @@
        layout="topleft"
        left="5"
        left_widget_pad="0"
-       height="272"
+       height="240"
        name="chat_history"
        parse_highlights="true"
        parse_urls="true"
@@ -57,7 +58,7 @@
        text_color="ChatHistoryTextColor"
        text_readonly_color="ChatHistoryTextColor"
        top="0"
-       width="313" />
+       width="384" />
     </layout_panel>
   </layout_stack>
 </panel>
-- 
cgit v1.2.3


From fe252836ebfb8a1247b0ae3222056d0543203a44 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 30 May 2012 22:58:22 +0300
Subject: Build fix

---
 indra/newview/llimconversation.cpp | 2 ++
 indra/newview/llnearbychatbar.cpp  | 7 -------
 indra/newview/llnearbychatbar.h    | 2 --
 3 files changed, 2 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 7220ab6a82..f5d84e80c1 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -25,6 +25,8 @@
  * $/LicenseInfo$
  */
 
+#include "llviewerprecompiledheaders.h"
+
 #include "llpanelimcontrolpanel.h"
 
 #include "lldraghandle.h"
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 82c00253e8..68934be11a 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -116,8 +116,6 @@ BOOL LLNearbyChatBar::postBuild()
 	// Register for font change notifications
 	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
 
-	// childSetAction("voice_call_btn", boost::bind(&LLNearbyChatBar::onCallButtonClicked, this));
-
 	enableResizeCtrls(true, true, false);
 
 	addToHost();
@@ -125,11 +123,6 @@ BOOL LLNearbyChatBar::postBuild()
 	return LLIMConversation::postBuild();;
 }
 
-void LLNearbyChatBar::onCallButtonClicked()
-{
-	LLAgent::toggleMicrophone(NULL);
-}
-
 void LLNearbyChatBar::enableDisableCallBtn()
 {
 	// bool btn_enabled = LLAgent::isActionAllowed("speak");
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index e714c04498..b7c4c993c6 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -88,8 +88,6 @@ protected:
 
 	void displaySpeakingIndicator();
 
-	void onCallButtonClicked();
-
 	// set the enable/disable state for the Call button
 	virtual void enableDisableCallBtn();
 
-- 
cgit v1.2.3


From bba0f4f74e56d911df8fc534d83cd4a84993bc8b Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 31 May 2012 16:37:22 +0300
Subject: CHUI-119 WIP

---
 indra/newview/CMakeLists.txt                       |   4 -
 indra/newview/llagent.cpp                          |   6 +-
 indra/newview/llchatitemscontainerctrl.cpp         |   6 +-
 indra/newview/llfloatertranslationsettings.cpp     |   4 +-
 indra/newview/llgesturemgr.cpp                     |   4 +-
 indra/newview/llimconversation.cpp                 |  97 ++-
 indra/newview/llimconversation.h                   |  12 +-
 indra/newview/llimfloater.cpp                      |  67 +-
 indra/newview/llimfloater.h                        |   9 +-
 indra/newview/llimfloatercontainer.cpp             |   2 +-
 indra/newview/llimview.cpp                         |   5 +-
 indra/newview/llnearbychat.cpp                     | 840 ++++++++++++++++++---
 indra/newview/llnearbychat.h                       | 107 ++-
 indra/newview/llnearbychatbar.cpp                  | 709 -----------------
 indra/newview/llnearbychatbar.h                    | 105 ---
 indra/newview/llnearbychatbarlistener.cpp          |   4 +-
 indra/newview/llnearbychatbarlistener.h            |   6 +-
 indra/newview/llnearbychathandler.cpp              |   9 +-
 indra/newview/llnotificationtiphandler.cpp         |   5 +-
 indra/newview/llpanelimcontrolpanel.cpp            |  81 --
 indra/newview/llviewerfloaterreg.cpp               |   4 +-
 indra/newview/llviewergesture.cpp                  |   4 +-
 indra/newview/llviewerkeyboard.cpp                 |  10 +-
 indra/newview/llviewerwindow.cpp                   |   8 +-
 .../skins/default/xui/en/floater_chat_bar.xml      | 202 -----
 .../skins/default/xui/en/floater_im_session.xml    | 119 ++-
 .../default/xui/en/panel_adhoc_control_panel.xml   |  95 ---
 .../default/xui/en/panel_group_control_panel.xml   |  60 --
 .../skins/default/xui/en/panel_nearby_chat.xml     |  19 +-
 29 files changed, 1037 insertions(+), 1566 deletions(-)
 delete mode 100644 indra/newview/llnearbychatbar.cpp
 delete mode 100644 indra/newview/llnearbychatbar.h
 delete mode 100644 indra/newview/skins/default/xui/en/floater_chat_bar.xml
 delete mode 100644 indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
 delete mode 100644 indra/newview/skins/default/xui/en/panel_group_control_panel.xml

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 86d30c239f..509f9581d6 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -332,7 +332,6 @@ set(viewer_SOURCE_FILES
     llnamelistctrl.cpp
     llnavigationbar.cpp
     llnearbychat.cpp
-    llnearbychatbar.cpp
     llnearbychathandler.cpp
     llnearbychatbarlistener.cpp
     llnetmap.cpp
@@ -364,7 +363,6 @@ set(viewer_SOURCE_FILES
     llpanelgroupnotices.cpp
     llpanelgrouproles.cpp
     llpanelhome.cpp
-    llpanelimcontrolpanel.cpp
     llpanelland.cpp
     llpanellandaudio.cpp
     llpanellandmarkinfo.cpp
@@ -890,7 +888,6 @@ set(viewer_HEADER_FILES
     llnamelistctrl.h
     llnavigationbar.h
     llnearbychat.h
-    llnearbychatbar.h
     llnearbychathandler.h
     llnearbychatbarlistener.h
     llnetmap.h
@@ -916,7 +913,6 @@ set(viewer_HEADER_FILES
     llpanelgroupnotices.h
     llpanelgrouproles.h
     llpanelhome.h
-    llpanelimcontrolpanel.h
     llpanelland.h
     llpanellandaudio.h
     llpanellandmarkinfo.h
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3870a3be2e..0db03289d8 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -54,7 +54,7 @@
 #include "llmorphview.h"
 #include "llmoveview.h"
 #include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 #include "llnotificationsutil.h"
 #include "llpaneltopinfobar.h"
 #include "llparcel.h"
@@ -1778,7 +1778,7 @@ void LLAgent::startTyping()
 	{
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
 	}
-	LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+	LLNearbyChat::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
 }
 
 //-----------------------------------------------------------------------------
@@ -1790,7 +1790,7 @@ void LLAgent::stopTyping()
 	{
 		clearRenderState(AGENT_STATE_TYPING);
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
-		LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+		LLNearbyChat::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
 	}
 }
 
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 7477fbd656..477bdb3967 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -35,7 +35,7 @@
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
 #include "lltrans.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 
 #include "llviewercontrol.h"
 #include "llagentdata.h"
@@ -316,12 +316,12 @@ BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
 			return TRUE;
 		else
 		{
-			LLNearbyChatBar::getInstance()->showHistory();
+			LLNearbyChat::getInstance()->showHistory();
 			return FALSE;
 		}
 	}
 
-	LLNearbyChatBar::getInstance()->showHistory();
+	LLNearbyChat::getInstance()->showHistory();
 	return LLPanel::handleMouseUp(x,y,mask);
 }
 
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index 1a17183efd..bb01ce5a7e 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -29,7 +29,7 @@
 #include "llfloatertranslationsettings.h"
 
 // Viewer includes
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 #include "lltranslate.h"
 #include "llviewercontrol.h" // for gSavedSettings
 
@@ -293,6 +293,6 @@ void LLFloaterTranslationSettings::onBtnOK()
 	gSavedSettings.setString("TranslationService", getSelectedService());
 	gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
 	gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
-	LLNearbyChatBar::getInstance()->showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+	LLNearbyChat::getInstance()->showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 	closeFloater(false);
 }
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 66ca76bfb0..26b63bdacb 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -51,7 +51,7 @@
 #include "llviewermessage.h"
 #include "llvoavatarself.h"
 #include "llviewerstats.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 #include "llappearancemgr.h"
 #include "llgesturelistener.h"
 
@@ -997,7 +997,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
 
 			const BOOL animate = FALSE;
 
-			LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+			LLNearbyChat::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
 
 			gesture->mCurrentStep++;
 			break;
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index f5d84e80c1..893d8dc83f 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -27,25 +27,27 @@
 
 #include "llviewerprecompiledheaders.h"
 
-#include "llpanelimcontrolpanel.h"
+#include "llimconversation.h"
 
 #include "lldraghandle.h"
 #include "llfloaterreg.h"
-#include "llimconversation.h"
 #include "llimfloater.h"
 #include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
 #include "lllayoutstack.h"
 #include "llnearbychat.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
+
+const F32 REFRESH_INTERVAL = 0.2;
 
 LLIMConversation::LLIMConversation(const LLUUID& session_id)
   : LLTransientDockableFloater(NULL, true, session_id)
-  ,  mControlPanel(NULL)
+  ,	LLEventTimer(REFRESH_INTERVAL)
   ,  mIsP2PChat(false)
   ,  mExpandCollapseBtn(NULL)
   ,  mTearOffBtn(NULL)
   ,  mCloseBtn(NULL)
   ,  mSessionID(session_id)
+  , mParticipantList(NULL)
 {
 	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
 			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2));
@@ -63,6 +65,15 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)
 			boost::bind(&LLIMConversation::onIMShowModesMenuItemEnable,  this, _2));
 }
 
+LLIMConversation::~LLIMConversation()
+{
+	if (mParticipantList)
+	{
+		delete mParticipantList;
+		mParticipantList = NULL;
+	}
+}
+
 BOOL LLIMConversation::postBuild()
 {
 	mCloseBtn = getChild<LLButton>("close_btn");
@@ -71,19 +82,12 @@ BOOL LLIMConversation::postBuild()
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this));
 
-	if (mControlPanel)
-	{
-	    mControlPanel->setSessionId(mSessionID);
-	    mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
-
-		mExpandCollapseBtn->setImageOverlay(
-				getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon"));
-	}
-	else
-	{
-		mExpandCollapseBtn->setEnabled(false);
-		getChild<LLLayoutPanel>("im_control_panel_holder")->setVisible(false);
-	}
+	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
+	mParticipantListPanel->setVisible(
+			mIsNearbyChat? false : gSavedSettings.getBOOL("IMShowControlPanel"));
+	mExpandCollapseBtn->setImageOverlay(
+				getString(mParticipantListPanel->getVisible() ? "collapse_icon" : "expand_icon"));
+	mExpandCollapseBtn->setEnabled(!mIsP2PChat);
 
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
@@ -93,6 +97,8 @@ BOOL LLIMConversation::postBuild()
 		setOpenPositioning(LLFloaterEnums::OPEN_POSITIONING_NONE);
 	}
 
+	buildParticipantList();
+
 	if (isChatMultiTab())
 	{
 		return LLFloater::postBuild();
@@ -104,6 +110,47 @@ BOOL LLIMConversation::postBuild()
 
 }
 
+BOOL LLIMConversation::tick()
+{
+	// Need to resort the participant list if it's in sort by recent speaker order.
+	if (mParticipantList)
+	{
+		mParticipantList->update();
+	}
+
+	return false;
+}
+
+void LLIMConversation::buildParticipantList()
+{	if (mIsNearbyChat)
+	{
+	}
+	else
+	{
+		// for group and Ad-hoc chat we need to include agent into list
+		if(!mIsP2PChat && !mParticipantList && mSessionID.notNull())
+		{
+			LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);
+		}
+	}
+}
+
+void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
+{
+	// TODO: Check this code when when sort order menu will be added. (EM)
+	if (true || !mParticipantList)
+		return;
+
+	std::string chosen_item = userdata.asString();
+
+	if (chosen_item == "sort_name")
+	{
+		mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
+	}
+
+}
+
 void LLIMConversation::onIMSessionMenuItemClicked(const LLSD& userdata)
 {
 	std::string item = userdata.asString();
@@ -162,11 +209,11 @@ void LLIMConversation::updateHeaderAndToolbar()
 	}
 
 	bool is_control_panel_visible = false;
-	if (mControlPanel)
+	if (!mIsP2PChat)
 	{
 		// Control panel should be visible only in torn off floaters.
 		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
-		mControlPanel->getParent()->setVisible(is_control_panel_visible);
+		mParticipantListPanel->setVisible(is_control_panel_visible);
 	}
 
 	// Display collapse image (<<) if the floater is hosted
@@ -215,10 +262,10 @@ void LLIMConversation::processChatHistoryStyleUpdate()
 		}
 	}
 
-	LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
-	if (nearby_chat_bar)
+	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
+	if (nearby_chat)
 	{
-		nearby_chat_bar->reloadMessages();
+		nearby_chat->reloadMessages();
 	}
 }
 
@@ -240,12 +287,12 @@ void LLIMConversation::onSlide(LLIMConversation* self)
 	}
 	else ///< floater is torn off
 	{
-		if (self->mControlPanel)
+		if (!self->mIsP2PChat)
 		{
-			bool expand = !self->mControlPanel->getParent()->getVisible();
+			bool expand = !self->mParticipantListPanel->getVisible();
 
 			// Expand/collapse the IM control panel
-			self->mControlPanel->getParent()->setVisible(expand);
+			self->mParticipantListPanel->setVisible(expand);
 
 			gSavedSettings.setBOOL("IMShowControlPanel", expand);
 
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 501977e061..d31ae0808a 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -28,19 +28,24 @@
 #ifndef LL_IMCONVERSATION_H
 #define LL_IMCONVERSATION_H
 
+#include "lllayoutstack.h"
+#include "llparticipantlist.h"
 #include "lltransientdockablefloater.h"
 #include "llviewercontrol.h"
+#include "lleventtimer.h"
 
 class LLPanelChatControlPanel;
 
 class LLIMConversation
 	: public LLTransientDockableFloater
+	, public LLEventTimer
 {
 
 public:
 	LOG_CLASS(LLIMConversation);
 
 	LLIMConversation(const LLUUID& session_id);
+	~LLIMConversation();
 
 	// reload all message with new settings of visual modes
 	static void processChatHistoryStyleUpdate();
@@ -75,13 +80,16 @@ protected:
 	// set the enable/disable state for the Call button
 	virtual void enableDisableCallBtn() = 0;
 
-//	/* virtual */ void updateTitleButtons();
+	void buildParticipantList();
+	void onSortMenuItemClicked(const LLSD& userdata);
 
+	/*virtual*/ BOOL tick();
 
-	LLPanelChatControlPanel* mControlPanel;
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
 
+	LLLayoutPanel* mParticipantListPanel;
+	LLParticipantList* mParticipantList;
 	LLUUID mSessionID;
 
 	LLButton* mExpandCollapseBtn;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 5339bcb936..c99da9e9c1 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -44,7 +44,6 @@
 //#include "lllayoutstack.h"
 #include "lllineeditor.h"
 #include "lllogchat.h"
-#include "llpanelimcontrolpanel.h"
 #include "llscreenchannel.h"
 #include "llsyswellwindow.h"
 #include "lltrans.h"
@@ -82,29 +81,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	{
 		mIsP2PChat = mSession->isP2PSessionType();
 		mSessionInitialized = mSession->mSessionInitialized;
-		
 		mDialog = mSession->mType;
-		switch (mDialog)
-		{
-		case IM_SESSION_CONFERENCE_START:
-			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
-			break;
-		case IM_SESSION_GROUP_START:
-			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
-			break;
-		case IM_SESSION_INVITE:
-			if (gAgent.isInGroup(mSessionID))
-			{
-				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
-			}
-			else
-			{
-				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
-			}
-			break;
-		default:
-			break;
-		}
 	}
 	setOverlapsScreenChannel(true);
 
@@ -113,24 +90,6 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	setDocked(true);
 }
 
-// static
-void* LLIMFloater::createPanelGroupControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*) userdata;
-	self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID);
-	self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
-	return self->mControlPanel;
-}
-
-// static
-void* LLIMFloater::createPanelAdHocControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*) userdata;
-	self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID);
-	self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml");
-	return self->mControlPanel;
-}
-
 void LLIMFloater::onFocusLost()
 {
 	LLIMModel::getInstance()->resetActiveSessionID();
@@ -409,8 +368,10 @@ void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
 }
 
 // virtual
-void LLIMFloater::draw()
+BOOL LLIMFloater::tick()
 {
+	BOOL parents_retcode = LLIMConversation::tick();
+
 	if ( mMeTyping )
 	{
 		// Time out if user hasn't typed for a while.
@@ -420,7 +381,7 @@ void LLIMFloater::draw()
 		}
 	}
 
-	LLTransientDockableFloater::draw();
+	return parents_retcode;
 }
 
 //static
@@ -643,16 +604,14 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	if (mSessionID != im_session_id)
 	{
 		mSessionID = im_session_id;
-
 		setKey(im_session_id);
-		if (mControlPanel)
-		{
-		mControlPanel->setSessionId(im_session_id);
-	}
+
 		boundVoiceChannel();
 
 		mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 		mIsP2PChat = mSession && mSession->isP2PSessionType();
+
+		buildParticipantList();
 	}
 	
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
@@ -841,10 +800,14 @@ void LLIMFloater::setTyping(bool typing)
 		}
 	}
 
-	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-	if (speaker_mgr)
-		speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
-
+	if (!mIsNearbyChat)
+	{
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if (speaker_mgr)
+		{
+			speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
+		}
+	}
 }
 
 void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index c7793f73eb..24f28c8aee 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -61,15 +61,15 @@ public:
 	/*virtual*/ void setVisible(BOOL visible);
 	/*virtual*/ BOOL getVisible();
 	// Check typing timeout timer.
-	/*virtual*/ void draw();
-
-	static void* createPanelGroupControl(void* userdata);
-	static void* createPanelAdHocControl(void* userdata);
+	/*virtual*/ BOOL tick();
 
 	static LLIMFloater* findInstance(const LLUUID& session_id);
 	static LLIMFloater* getInstance(const LLUUID& session_id);
 	static void addToHost(const LLUUID& session_id);
 
+	static void* createPanelGroupControl(void* userdata);
+	static void* createPanelAdHocControl(void* userdata);
+
 	// LLFloater overrides
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
@@ -147,7 +147,6 @@ private:
 	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
 	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
 	void setTyping(bool typing);
-
 	void onCallButtonClicked();
 
 	// set the enable/disable state for the Call button
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index f72ddef412..3b6240de44 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -31,7 +31,7 @@
 
 #include "llfloaterreg.h"
 #include "lllayoutstack.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 
 #include "llagent.h"
 #include "llavatariconctrl.h"
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c3ac1d32cb..46b1cb5f18 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -907,7 +907,7 @@ const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
 	LLIMSession* session = findIMSession(session_id);
 	if (!session)
 	{
-		llwarns << "session " << session_id << "does not exist " << llendl;
+		llwarns << "session " << session_id << " does not exist " << llendl;
 		return LLUUID::null;
 	}
 
@@ -2483,8 +2483,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 		LLChat chat(message);
 		chat.mSourceType = CHAT_SOURCE_SYSTEM;
 		
-		LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-		LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
+		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
 
 		if(nearby_chat)
 		{
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 497690d656..2d7095957e 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -1,8 +1,8 @@
 /** 
  * @file LLNearbyChat.cpp
- * @brief Nearby chat history scrolling panel implementation
+ * @brief LLNearbyChat class implementation
  *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
  * 
@@ -25,34 +25,50 @@
  */
 
 #include "llviewerprecompiledheaders.h"
-#include "llviewercontrol.h"
-#include "llviewerwindow.h"
-#include "llrootview.h"
-//#include "llchatitemscontainerctrl.h"
+
+#include "message.h"
+
 #include "lliconctrl.h"
+#include "llappviewer.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+#include "llimfloatercontainer.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfocusmgr.h"
 #include "lllogchat.h"
 #include "llresizebar.h"
 #include "llresizehandle.h"
+#include "lldraghandle.h"
 #include "llmenugl.h"
-#include "llviewermenu.h"//for gMenuHolder
-
+#include "llviewermenu.h" // for gMenuHolder
 #include "llnearbychathandler.h"
 #include "llchannelmanager.h"
-
-#include "llagent.h" 			// gAgent
 #include "llchathistory.h"
 #include "llstylemap.h"
-
 #include "llavatarnamecache.h"
-
-#include "lldraghandle.h"
-
-#include "llnearbychatbar.h"
 #include "llfloaterreg.h"
 #include "lltrans.h"
 
+#include "llfirstuse.h"
+#include "llnearbychat.h"
+#include "llagent.h" // gAgent
+#include "llgesturemgr.h"
+#include "llmultigesture.h"
+#include "llkeyboard.h"
+#include "llanimationstates.h"
+#include "llviewerstats.h"
+#include "llcommandhandler.h"
+#include "llviewercontrol.h"
+#include "llnavigationbar.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llrootview.h"
+#include "llviewerchat.h"
+#include "lltranslate.h"
+
+S32 LLNearbyChat::sLastSpecialChatChannel = 0;
+
+
 // --- 2 functions in the global namespace :( ---
 bool isWordsName(const std::string& name)
 {
@@ -88,90 +104,83 @@ std::string appendTime()
 	return timeStr;
 }
 
-static const S32 RESIZE_BAR_THICKNESS = 3;
 
-static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat");
+const S32 EXPANDED_HEIGHT = 266;
+const S32 COLLAPSED_HEIGHT = 60;
+const S32 EXPANDED_MIN_HEIGHT = 150;
 
-LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p)
-	: LLPanel(p),
-	  mChatHistory(NULL)
-{
-}
+// legacy callback glue
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
 
-BOOL LLNearbyChat::postBuild()
-{
-	//menu
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+struct LLChatTypeTrigger {
+	std::string name;
+	EChatType type;
+};
 
-	enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
-	registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
+static LLChatTypeTrigger sChatTypeTriggers[] = {
+	{ "/whisper"	, CHAT_TYPE_WHISPER},
+	{ "/shout"	, CHAT_TYPE_SHOUT}
+};
 
-	
-	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(menu)
-		mPopupMenuHandle = menu->getHandle();
 
-	gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
+LLNearbyChat::LLNearbyChat(const LLSD& key)
+:	LLIMConversation(key),
+	mChatBox(NULL),
+	mChatHistory(NULL),
+	mOutputMonitor(NULL),
+	mSpeakerMgr(NULL),
+	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
+{
+	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
+}
 
-	mChatHistory = getChild<LLChatHistory>("chat_history");
+//virtual
+BOOL LLNearbyChat::postBuild()
+{
+	mChatBox = getChild<LLLineEditor>("chat_editor");
 
-    return LLPanel::postBuild();
-}
+	mChatBox->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this));
+	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
+	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
+	mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this));
+	mChatBox->setIgnoreArrowKeys( FALSE ); 
+	mChatBox->setCommitOnFocusLost( FALSE );
+	mChatBox->setRevertOnEsc( FALSE );
+	mChatBox->setIgnoreTab(TRUE);
+	mChatBox->setPassDelete(TRUE);
+	mChatBox->setReplaceNewlinesWithSpaces(FALSE);
+	mChatBox->setEnableLineHistory(TRUE);
+	mChatBox->setFont(LLViewerChat::getChatFont());
 
+	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
+	mOutputMonitor->setVisible(FALSE);
 
-void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args)
-{
-	LLChat& tmp_chat = const_cast<LLChat&>(chat);
+	// Register for font change notifications
+	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChat::onChatFontChange, this, _1));
 
-	if(tmp_chat.mTimeStr.empty())
-		tmp_chat.mTimeStr = appendTime();
+	enableResizeCtrls(true, true, false);
 
-	if (!chat.mMuted)
-	{
-		tmp_chat.mFromName = chat.mFromName;
-		LLSD chat_args;
-		if (args) chat_args = args;
-		chat_args["use_plain_text_chat_history"] =
-				gSavedSettings.getBOOL("PlainTextChatHistory");
-		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
-		chat_args["show_names_for_p2p_conv"] = true;
+	addToHost();
 
-		mChatHistory->appendMessage(chat, chat_args);
-	}
-}
+	//for menu
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
 
-void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
-{
-	appendMessage(chat, args);
+	enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
+	registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
 
-	if(archive)
+	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	if(menu)
 	{
-		mMessageArchive.push_back(chat);
-		if(mMessageArchive.size()>200)
-			mMessageArchive.erase(mMessageArchive.begin());
+		mPopupMenuHandle = menu->getHandle();
 	}
 
-	// logging
-	if (!args["do_not_log"].asBoolean()
-			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
-	{
-		std::string from_name = chat.mFromName;
-
-		if (chat.mSourceType == CHAT_SOURCE_AGENT)
-		{
-			// if the chat is coming from an agent, log the complete name
-			LLAvatarName av_name;
-			LLAvatarNameCache::get(chat.mFromID, &av_name);
+	// obsolete, but may be needed for backward compatibility?
+	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
 
-			if (!av_name.mIsDisplayNameDefault)
-			{
-				from_name = av_name.getCompleteName();
-			}
-		}
+	mChatHistory = getChild<LLChatHistory>("chat_history");
 
-		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
-	}
+	return LLIMConversation::postBuild();;
 }
 
 void LLNearbyChat::onNearbySpeakers()
@@ -189,33 +198,40 @@ bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
 {
 	std::string str = userdata.asString();
 	if(str == "nearby_people")
-		onNearbySpeakers();	
+		onNearbySpeakers();
 	return false;
 }
 
-void LLNearbyChat::removeScreenChat()
+void LLNearbyChat::getAllowedRect(LLRect& rect)
 {
-	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
-	if(chat_channel)
-	{
-		chat_channel->removeToastsFromChannel();
-	}
+	rect = gViewerWindow->getWorldViewRectScaled();
 }
-
-void	LLNearbyChat::setVisible(BOOL visible)
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLNearbyChat::onFocusReceived()
 {
-	if(visible)
-	{
-		removeScreenChat();
-	}
-
-	LLPanel::setVisible(visible);
+	setBackgroundOpaque(true);
+	LLIMConversation::onFocusReceived();
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLNearbyChat::onFocusLost()
+{
+	setBackgroundOpaque(false);
+	LLIMConversation::onFocusLost();
+}
 
-void LLNearbyChat::getAllowedRect(LLRect& rect)
+BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
 {
-	rect = gViewerWindow->getWorldViewRectScaled();
+	//fix for EXT-6625
+	//highlight NearbyChat history whenever mouseclick happen in NearbyChat
+	//setting focus to eidtor will force onFocusLost() call that in its turn will change
+	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
+
+	if(mChatHistory)
+		mChatHistory->setFocus(TRUE);
+	return LLPanel::handleMouseDown(x, y, mask);
 }
 
 void LLNearbyChat::reloadMessages()
@@ -265,9 +281,9 @@ void LLNearbyChat::loadHistory()
 
 		chat.mSourceType = CHAT_SOURCE_AGENT;
 		if (from_id.isNull() && SYSTEM_FROM == from)
-		{	
+		{
 			chat.mSourceType = CHAT_SOURCE_SYSTEM;
-			
+
 		}
 		else if (from_id.isNull())
 		{
@@ -280,43 +296,117 @@ void LLNearbyChat::loadHistory()
 	}
 }
 
-//static
-LLNearbyChat* LLNearbyChat::getInstance()
+void LLNearbyChat::removeScreenChat()
 {
-	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-	return chat_bar->findChild<LLNearbyChat>("nearby_chat");
+	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	if(chat_channel)
+	{
+		chat_channel->removeToastsFromChannel();
+	}
 }
 
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLNearbyChat::onFocusReceived()
+void	LLNearbyChat::setVisible(BOOL visible)
 {
-	setBackgroundOpaque(true);
-	LLPanel::onFocusReceived();
+	if(visible)
+	{
+		removeScreenChat();
+	}
+
+	LLIMConversation::setVisible(visible);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLNearbyChat::onFocusLost()
+void LLNearbyChat::onCallButtonClicked()
 {
-	setBackgroundOpaque(false);
-	LLPanel::onFocusLost();
+	LLAgent::toggleMicrophone(NULL);
 }
 
-BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
+void LLNearbyChat::enableDisableCallBtn()
 {
-	//fix for EXT-6625
-	//highlight NearbyChat history whenever mouseclick happen in NearbyChat
-	//setting focus to eidtor will force onFocusLost() call that in its turn will change 
-	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
+	// bool btn_enabled = LLAgent::isActionAllowed("speak");
+
+	getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/);
+}
+
+void LLNearbyChat::addToHost()
+{
+	if (LLIMConversation::isChatMultiTab())
+	{
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+
+		if (im_box)
+		{
+			im_box->addFloater(this, FALSE, LLTabContainer::END);
+		}
+	}
+}
+
+// virtual
+void LLNearbyChat::onOpen(const LLSD& key)
+{
+	LLIMConversation::onOpen(key);
+	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+}
+
+bool LLNearbyChat::applyRectControl()
+{
+	bool rect_controlled = LLFloater::applyRectControl();
+
+/*	if (!mNearbyChat->getVisible())
+	{
+		reshape(getRect().getWidth(), getMinHeight());
+		enableResizeCtrls(true, true, false);
+	}
+	else
+	{*/
+		enableResizeCtrls(true);
+		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
+//	}
 	
-	if(mChatHistory)
-		mChatHistory->setFocus(TRUE);
-	return LLPanel::handleMouseDown(x, y, mask);
+	return rect_controlled;
+}
+
+void LLNearbyChat::onChatFontChange(LLFontGL* fontp)
+{
+	// Update things with the new font whohoo
+	if (mChatBox)
+	{
+		mChatBox->setFont(fontp);
+	}
+}
+
+//static
+LLNearbyChat* LLNearbyChat::getInstance()
+{
+	return LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar");
+}
+
+//static
+//LLNearbyChat* LLNearbyChat::findInstance()
+//{
+//	return LLFloaterReg::findTypedInstance<LLNearbyChat>("chat_bar");
+//}
+
+void LLNearbyChat::showHistory()
+{
+	openFloater();
+	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
+	reshape(getRect().getWidth(), mExpandedHeight);
+	enableResizeCtrls(true);
+	storeRectControl();
 }
 
-void LLNearbyChat::draw()
+void LLNearbyChat::showTranslationCheckbox(BOOL show)
 {
+	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(show);
+}
+
+BOOL LLNearbyChat::tick()
+{
+	BOOL parents_retcode = LLIMConversation::tick();
+
+	displaySpeakingIndicator();
+	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
+
 	// *HACK: Update transparency type depending on whether our children have focus.
 	// This is needed because this floater is chrome and thus cannot accept focus, so
 	// the transparency type setting code from LLFloater::setFocus() isn't reached.
@@ -325,5 +415,511 @@ void LLNearbyChat::draw()
 		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
 	}
 
-	LLPanel::draw();
+	return parents_retcode;
 }
+
+std::string LLNearbyChat::getCurrentChat()
+{
+	return mChatBox ? mChatBox->getText() : LLStringUtil::null;
+}
+
+// virtual
+BOOL LLNearbyChat::handleKeyHere( KEY key, MASK mask )
+{
+	BOOL handled = FALSE;
+
+	if( KEY_RETURN == key && mask == MASK_CONTROL)
+	{
+		// shout
+		sendChat(CHAT_TYPE_SHOUT);
+		handled = TRUE;
+	}
+
+	return handled;
+}
+
+BOOL LLNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
+{
+	U32 in_len = in_str.length();
+	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+	
+	bool string_was_found = false;
+
+	for (S32 n = 0; n < cnt && !string_was_found; n++)
+	{
+		if (in_len <= sChatTypeTriggers[n].name.length())
+		{
+			std::string trigger_trunc = sChatTypeTriggers[n].name;
+			LLStringUtil::truncate(trigger_trunc, in_len);
+
+			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+			{
+				*out_str = sChatTypeTriggers[n].name;
+				string_was_found = true;
+			}
+		}
+	}
+
+	return string_was_found;
+}
+
+void LLNearbyChat::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
+{
+	LLFirstUse::otherAvatarChatFirst(false);
+
+	LLNearbyChat* self = (LLNearbyChat *)userdata;
+
+	LLWString raw_text = self->mChatBox->getWText();
+
+	// Can't trim the end, because that will cause autocompletion
+	// to eat trailing spaces that might be part of a gesture.
+	LLWStringUtil::trimHead(raw_text);
+
+	S32 length = raw_text.length();
+
+	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences
+	{
+		gAgent.startTyping();
+	}
+	else
+	{
+		gAgent.stopTyping();
+	}
+
+	/* Doesn't work -- can't tell the difference between a backspace
+	   that killed the selection vs. backspace at the end of line.
+	if (length > 1 
+		&& text[0] == '/'
+		&& key == KEY_BACKSPACE)
+	{
+		// the selection will already be deleted, but we need to trim
+		// off the character before
+		std::string new_text = raw_text.substr(0, length-1);
+		self->mInputEditor->setText( new_text );
+		self->mInputEditor->setCursorToEnd();
+		length = length - 1;
+	}
+	*/
+
+	KEY key = gKeyboard->currentKey();
+
+	// Ignore "special" keys, like backspace, arrows, etc.
+	if (length > 1 
+		&& raw_text[0] == '/'
+		&& key < KEY_SPECIAL)
+	{
+		// we're starting a gesture, attempt to autocomplete
+
+		std::string utf8_trigger = wstring_to_utf8str(raw_text);
+		std::string utf8_out_str(utf8_trigger);
+
+		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
+		{
+			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+			self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+			S32 outlength = self->mChatBox->getLength(); // in characters
+
+			// Select to end of line, starting from the character
+			// after the last one the user typed.
+			self->mChatBox->setSelection(length, outlength);
+		}
+		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
+		{
+			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+			self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
+			self->mChatBox->setCursorToEnd();
+		}
+
+		//llinfos << "GESTUREDEBUG " << trigger 
+		//	<< " len " << length
+		//	<< " outlen " << out_str.getLength()
+		//	<< llendl;
+	}
+}
+
+// static
+void LLNearbyChat::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
+{
+	// stop typing animation
+	gAgent.stopTyping();
+}
+
+void LLNearbyChat::onChatBoxFocusReceived()
+{
+	mChatBox->setEnabled(!gDisconnected);
+}
+
+EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str)
+{
+	U32 length = str.length();
+	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+	
+	for (S32 n = 0; n < cnt; n++)
+	{
+		if (length >= sChatTypeTriggers[n].name.length())
+		{
+			std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
+
+			if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
+			{
+				U32 trigger_length = sChatTypeTriggers[n].name.length();
+
+				// It's to remove space after trigger name
+				if (length > trigger_length && str[trigger_length] == ' ')
+					trigger_length++;
+
+				str = str.substr(trigger_length, length);
+
+				if (CHAT_TYPE_NORMAL == type)
+					return sChatTypeTriggers[n].type;
+				else
+					break;
+			}
+		}
+	}
+
+	return type;
+}
+
+void LLNearbyChat::sendChat( EChatType type )
+{
+	if (mChatBox)
+	{
+		LLWString text = mChatBox->getConvertedText();
+		if (!text.empty())
+		{
+			// store sent line in history, duplicates will get filtered
+			mChatBox->updateHistory();
+			// Check if this is destined for another channel
+			S32 channel = 0;
+			stripChannelNumber(text, &channel);
+			
+			std::string utf8text = wstring_to_utf8str(text);
+			// Try to trigger a gesture, if not chat to a script.
+			std::string utf8_revised_text;
+			if (0 == channel)
+			{
+				// discard returned "found" boolean
+				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
+			}
+			else
+			{
+				utf8_revised_text = utf8text;
+			}
+
+			utf8_revised_text = utf8str_trim(utf8_revised_text);
+
+			type = processChatTypeTriggers(type, utf8_revised_text);
+
+			if (!utf8_revised_text.empty())
+			{
+				// Chat with animation
+				sendChatFromViewer(utf8_revised_text, type, TRUE);
+			}
+		}
+
+		mChatBox->setText(LLStringExplicit(""));
+	}
+
+	gAgent.stopTyping();
+
+	// If the user wants to stop chatting on hitting return, lose focus
+	// and go out of chat mode.
+	if (gSavedSettings.getBOOL("CloseChatOnReturn"))
+	{
+		stopChat();
+	}
+}
+
+
+void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args)
+{
+	LLChat& tmp_chat = const_cast<LLChat&>(chat);
+
+	if(tmp_chat.mTimeStr.empty())
+		tmp_chat.mTimeStr = appendTime();
+
+	if (!chat.mMuted)
+	{
+		tmp_chat.mFromName = chat.mFromName;
+		LLSD chat_args;
+		if (args) chat_args = args;
+		chat_args["use_plain_text_chat_history"] =
+				gSavedSettings.getBOOL("PlainTextChatHistory");
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] = true;
+
+		mChatHistory->appendMessage(chat, chat_args);
+	}
+}
+
+void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+{
+	appendMessage(chat, args);
+
+	if(archive)
+	{
+		mMessageArchive.push_back(chat);
+		if(mMessageArchive.size()>200)
+			mMessageArchive.erase(mMessageArchive.begin());
+	}
+
+	// logging
+	if (!args["do_not_log"].asBoolean()
+			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
+	{
+		std::string from_name = chat.mFromName;
+
+		if (chat.mSourceType == CHAT_SOURCE_AGENT)
+		{
+			// if the chat is coming from an agent, log the complete name
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(chat.mFromID, &av_name);
+
+			if (!av_name.mIsDisplayNameDefault)
+			{
+				from_name = av_name.getCompleteName();
+			}
+		}
+
+		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
+	}
+}
+
+
+void LLNearbyChat::onChatBoxCommit()
+{
+	if (mChatBox->getText().length() > 0)
+	{
+		sendChat(CHAT_TYPE_NORMAL);
+	}
+
+	gAgent.stopTyping();
+}
+
+void LLNearbyChat::displaySpeakingIndicator()
+{
+	LLSpeakerMgr::speaker_list_t speaker_list;
+	LLUUID id;
+
+	id.setNull();
+	mSpeakerMgr->update(TRUE);
+	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
+
+	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
+	{
+		LLPointer<LLSpeaker> s = *i;
+		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
+		{
+			id = s->mID;
+			break;
+		}
+	}
+
+	if (!id.isNull())
+	{
+		mOutputMonitor->setVisible(TRUE);
+		mOutputMonitor->setSpeakerId(id);
+	}
+	else
+	{
+		mOutputMonitor->setVisible(FALSE);
+	}
+}
+
+void LLNearbyChat::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
+{
+	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
+}
+
+void LLNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
+{
+	// Look for "/20 foo" channel chats.
+	S32 channel = 0;
+	LLWString out_text = stripChannelNumber(wtext, &channel);
+	std::string utf8_out_text = wstring_to_utf8str(out_text);
+	std::string utf8_text = wstring_to_utf8str(wtext);
+
+	utf8_text = utf8str_trim(utf8_text);
+	if (!utf8_text.empty())
+	{
+		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
+	}
+
+	// Don't animate for chats people can't hear (chat to scripts)
+	if (animate && (channel == 0))
+	{
+		if (type == CHAT_TYPE_WHISPER)
+		{
+			lldebugs << "You whisper " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
+		}
+		else if (type == CHAT_TYPE_NORMAL)
+		{
+			lldebugs << "You say " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
+		}
+		else if (type == CHAT_TYPE_SHOUT)
+		{
+			lldebugs << "You shout " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
+		}
+		else
+		{
+			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
+			return;
+		}
+	}
+	else
+	{
+		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
+		{
+			lldebugs << "Channel chat: " << utf8_text << llendl;
+		}
+	}
+
+	send_chat_from_viewer(utf8_out_text, type, channel);
+}
+
+// static 
+void LLNearbyChat::startChat(const char* line)
+{
+	LLNearbyChat* cb = LLNearbyChat::getInstance();
+
+	if (cb )
+	{
+		cb->setVisible(TRUE);
+		cb->setFocus(TRUE);
+		cb->mChatBox->setFocus(TRUE);
+
+		if (line)
+		{
+			std::string line_string(line);
+			cb->mChatBox->setText(line_string);
+		}
+
+		cb->mChatBox->setCursorToEnd();
+	}
+}
+
+// Exit "chat mode" and do the appropriate focus changes
+// static
+void LLNearbyChat::stopChat()
+{
+	LLNearbyChat* cb = LLNearbyChat::getInstance();
+
+	if (cb)
+	{
+		cb->mChatBox->setFocus(FALSE);
+
+		// stop typing animation
+		gAgent.stopTyping();
+	}
+}
+
+// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
+// Otherwise returns input and channel 0.
+LLWString LLNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel)
+{
+	if (mesg[0] == '/'
+		&& mesg[1] == '/')
+	{
+		// This is a "repeat channel send"
+		*channel = sLastSpecialChatChannel;
+		return mesg.substr(2, mesg.length() - 2);
+	}
+	else if (mesg[0] == '/'
+			 && mesg[1]
+			 && LLStringOps::isDigit(mesg[1]))
+	{
+		// This a special "/20" speak on a channel
+		S32 pos = 0;
+
+		// Copy the channel number into a string
+		LLWString channel_string;
+		llwchar c;
+		do
+		{
+			c = mesg[pos+1];
+			channel_string.push_back(c);
+			pos++;
+		}
+		while(c && pos < 64 && LLStringOps::isDigit(c));
+		
+		// Move the pointer forward to the first non-whitespace char
+		// Check isspace before looping, so we can handle "/33foo"
+		// as well as "/33 foo"
+		while(c && iswspace(c))
+		{
+			c = mesg[pos+1];
+			pos++;
+		}
+		
+		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
+		*channel = sLastSpecialChatChannel;
+		return mesg.substr(pos, mesg.length() - pos);
+	}
+	else
+	{
+		// This is normal chat.
+		*channel = 0;
+		return mesg;
+	}
+}
+
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
+{
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_ChatFromViewer);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_ChatData);
+	msg->addStringFast(_PREHASH_Message, utf8_out_text);
+	msg->addU8Fast(_PREHASH_Type, type);
+	msg->addS32("Channel", channel);
+
+	gAgent.sendReliableMessage();
+
+	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+}
+
+class LLChatCommandHandler : public LLCommandHandler
+{
+public:
+	// not allowed from outside the app
+	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
+
+    // Your code here
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLMediaCtrl* web)
+	{
+		bool retval = false;
+		// Need at least 2 tokens to have a valid message.
+		if (tokens.size() < 2)
+		{
+			retval = false;
+		}
+		else
+		{
+		S32 channel = tokens[0].asInteger();
+			// VWR-19499 Restrict function to chat channels greater than 0.
+			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
+			{
+				retval = true;
+		// Send unescaped message, see EXT-6353.
+		std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
+		send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
+			}
+			else
+			{
+				retval = false;
+				// Tell us this is an unsupported SLurl.
+			}
+		}
+		return retval;
+	}
+};
+
+// Creating the object registers with the dispatcher.
+LLChatCommandHandler gChatHandler;
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 62a41c17cb..b38111defa 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -1,8 +1,8 @@
- /** 
+/** 
  * @file llnearbychat.h
- * @brief nearby chat history scrolling panel implementation
+ * @brief LLNearbyChat class definition
  *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
  * 
@@ -24,9 +24,16 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLNEARBYCHAT_H_
-#define LL_LLNEARBYCHAT_H_
+#ifndef LL_LLNEARBYCHAT_H
+#define LL_LLNEARBYCHAT_H
 
+#include "llimconversation.h"
+#include "llcombobox.h"
+#include "llgesturemgr.h"
+#include "llchat.h"
+#include "llvoiceclient.h"
+#include "lloutputmonitorctrl.h"
+#include "llspeakers.h"
 #include "llscrollbar.h"
 #include "llviewerchat.h"
 #include "llpanel.h"
@@ -35,32 +42,88 @@ class LLResizeBar;
 class LLChatHistory;
 
 class LLNearbyChat
-	: public LLPanel
+	:	public LLIMConversation
 {
 public:
-	LLNearbyChat(const Params& p = LLPanel::getDefaultParams());
+	// constructor for inline chat-bars (e.g. hosted in chat history window)
+	LLNearbyChat(const LLSD& key);
+	~LLNearbyChat() {}
 
-	BOOL	postBuild			();
-
-	/** @param archive true - to save a message to the chat history log */
-	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());	
-	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);
-	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
-
-	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
-	virtual void	draw();
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
 
 	// focus overrides
 	/*virtual*/ void	onFocusLost();
 	/*virtual*/ void	onFocusReceived();
-	
+
 	/*virtual*/ void	setVisible(BOOL visible);
-	
+
 	void loadHistory();
     void reloadMessages();
-	static LLNearbyChat* getInstance();
 	void removeScreenChat();
 
+	static LLNearbyChat* getInstance();
+
+	void addToHost();
+
+	/** @param archive true - to save a message to the chat history log */
+	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());
+	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);
+	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
+
+	LLLineEditor* getChatBox() { return mChatBox; }
+
+	//virtual void draw();
+
+	std::string getCurrentChat();
+
+	virtual BOOL handleKeyHere( KEY key, MASK mask );
+	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
+
+	static void startChat(const char* line);
+	static void stopChat();
+
+	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
+	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
+
+	void showHistory();
+	void showTranslationCheckbox(BOOL show);
+
+protected:
+	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
+	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
+	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
+	void onChatBoxFocusReceived();
+
+	void sendChat( EChatType type );
+	void onChatBoxCommit();
+	void onChatFontChange(LLFontGL* fontp);
+
+	/* virtual */ bool applyRectControl();
+
+	void onToggleNearbyChatPanel();
+
+	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
+	EChatType processChatTypeTriggers(EChatType type, std::string &str);
+
+	void displaySpeakingIndicator();
+
+	void onCallButtonClicked();
+
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn();
+
+	// Which non-zero channel did we last chat on?
+	static S32 sLastSpecialChatChannel;
+
+	LLLineEditor*			mChatBox;
+	LLOutputMonitorCtrl*	mOutputMonitor;
+	LLLocalSpeakerMgr*		mSpeakerMgr;
+
+	S32 mExpandedHeight;
+
+	/*virtual*/ BOOL tick();
+
 private:
 
 	void	getAllowedRect		(LLRect& rect);
@@ -68,14 +131,10 @@ private:
 	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	void	onNearbySpeakers	();
 
-
-private:
 	LLHandle<LLView>	mPopupMenuHandle;
+	std::vector<LLChat> mMessageArchive;
 	LLChatHistory*		mChatHistory;
 
-	std::vector<LLChat> mMessageArchive;
 };
 
 #endif
-
-
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
deleted file mode 100644
index 68934be11a..0000000000
--- a/indra/newview/llnearbychatbar.cpp
+++ /dev/null
@@ -1,709 +0,0 @@
-/** 
- * @file llnearbychatbar.cpp
- * @brief LLNearbyChatBar class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "message.h"
-
-#include "llappviewer.h"
-#include "llfloaterreg.h"
-#include "lltrans.h"
-#include "llimfloatercontainer.h"
-#include "llfirstuse.h"
-#include "llnearbychatbar.h"
-#include "llagent.h"
-#include "llgesturemgr.h"
-#include "llmultigesture.h"
-#include "llkeyboard.h"
-#include "llanimationstates.h"
-#include "llviewerstats.h"
-#include "llcommandhandler.h"
-#include "llviewercontrol.h"
-#include "llnavigationbar.h"
-#include "llwindow.h"
-#include "llviewerwindow.h"
-#include "llrootview.h"
-#include "llviewerchat.h"
-#include "llnearbychat.h"
-#include "lltranslate.h"
-
-#include "llresizehandle.h"
-
-S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
-
-const S32 EXPANDED_HEIGHT = 266;
-const S32 COLLAPSED_HEIGHT = 60;
-const S32 EXPANDED_MIN_HEIGHT = 150;
-
-// legacy callback glue
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
-
-struct LLChatTypeTrigger {
-	std::string name;
-	EChatType type;
-};
-
-static LLChatTypeTrigger sChatTypeTriggers[] = {
-	{ "/whisper"	, CHAT_TYPE_WHISPER},
-	{ "/shout"	, CHAT_TYPE_SHOUT}
-};
-
-LLNearbyChatBar::LLNearbyChatBar(const LLSD& key)
-:	LLIMConversation(key),
-	mChatBox(NULL),
-	mNearbyChat(NULL),
-	mOutputMonitor(NULL),
-	mSpeakerMgr(NULL),
-	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
-{
-	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
-}
-
-//virtual
-BOOL LLNearbyChatBar::postBuild()
-{
-	mChatBox = getChild<LLLineEditor>("chat_box");
-
-	mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
-	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
-	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
-	mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChatBar::onChatBoxFocusReceived, this));
-
-	mChatBox->setIgnoreArrowKeys( FALSE ); 
-	mChatBox->setCommitOnFocusLost( FALSE );
-	mChatBox->setRevertOnEsc( FALSE );
-	mChatBox->setIgnoreTab(TRUE);
-	mChatBox->setPassDelete(TRUE);
-	mChatBox->setReplaceNewlinesWithSpaces(FALSE);
-	mChatBox->setEnableLineHistory(TRUE);
-	mChatBox->setFont(LLViewerChat::getChatFont());
-
-	mNearbyChat = getChildView("nearby_chat");
-
-	LLUICtrl* show_btn = getChild<LLUICtrl>("show_nearby_chat");
-	show_btn->setCommitCallback(boost::bind(&LLNearbyChatBar::onToggleNearbyChatPanel, this));
-
-	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
-	mOutputMonitor->setVisible(FALSE);
-
-	gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE);
-
-	mNearbyChat->setVisible(gSavedSettings.getBOOL("nearbychat_history_visibility"));
-
-	// Register for font change notifications
-	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
-
-	enableResizeCtrls(true, true, false);
-
-	addToHost();
-
-	return LLIMConversation::postBuild();;
-}
-
-void LLNearbyChatBar::enableDisableCallBtn()
-{
-	// bool btn_enabled = LLAgent::isActionAllowed("speak");
-
-	getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/);
-}
-
-void LLNearbyChatBar::addToHost()
-{
-	if (LLIMConversation::isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-
-		if (im_box)
-		{
-			im_box->addFloater(this, FALSE, LLTabContainer::END);
-		}
-	}
-}
-
-// virtual
-void LLNearbyChatBar::onOpen(const LLSD& key)
-{
-	LLIMConversation::onOpen(key);
-	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
-}
-
-bool LLNearbyChatBar::applyRectControl()
-{
-	bool rect_controlled = LLFloater::applyRectControl();
-
-	if (!mNearbyChat->getVisible())
-	{
-		reshape(getRect().getWidth(), getMinHeight());
-		enableResizeCtrls(true, true, false);
-	}
-	else
-	{
-		enableResizeCtrls(true);
-		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-	}
-	
-	return rect_controlled;
-}
-
-void LLNearbyChatBar::onChatFontChange(LLFontGL* fontp)
-{
-	// Update things with the new font whohoo
-	if (mChatBox)
-	{
-		mChatBox->setFont(fontp);
-	}
-}
-
-//static
-LLNearbyChatBar* LLNearbyChatBar::getInstance()
-{
-	return LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar");
-}
-
-//static
-//LLNearbyChatBar* LLNearbyChatBar::findInstance()
-//{
-//	return LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar");
-//}
-
-void LLNearbyChatBar::showHistory()
-{
-	openFloater();
-
-	if (!getChildView("nearby_chat")->getVisible())
-	{
-		onToggleNearbyChatPanel();
-	}
-}
-
-void LLNearbyChatBar::showTranslationCheckbox(BOOL show)
-{
-	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(show);
-}
-
-void LLNearbyChatBar::draw()
-{
-	displaySpeakingIndicator();
-	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
-	LLIMConversation::draw();
-}
-
-std::string LLNearbyChatBar::getCurrentChat()
-{
-	return mChatBox ? mChatBox->getText() : LLStringUtil::null;
-}
-
-// virtual
-BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask )
-{
-	BOOL handled = FALSE;
-
-	if( KEY_RETURN == key && mask == MASK_CONTROL)
-	{
-		// shout
-		sendChat(CHAT_TYPE_SHOUT);
-		handled = TRUE;
-	}
-
-	return handled;
-}
-
-BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
-{
-	U32 in_len = in_str.length();
-	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
-	
-	bool string_was_found = false;
-
-	for (S32 n = 0; n < cnt && !string_was_found; n++)
-	{
-		if (in_len <= sChatTypeTriggers[n].name.length())
-		{
-			std::string trigger_trunc = sChatTypeTriggers[n].name;
-			LLStringUtil::truncate(trigger_trunc, in_len);
-
-			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
-			{
-				*out_str = sChatTypeTriggers[n].name;
-				string_was_found = true;
-			}
-		}
-	}
-
-	return string_was_found;
-}
-
-void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
-{
-	LLFirstUse::otherAvatarChatFirst(false);
-
-	LLNearbyChatBar* self = (LLNearbyChatBar *)userdata;
-
-	LLWString raw_text = self->mChatBox->getWText();
-
-	// Can't trim the end, because that will cause autocompletion
-	// to eat trailing spaces that might be part of a gesture.
-	LLWStringUtil::trimHead(raw_text);
-
-	S32 length = raw_text.length();
-
-	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences
-	{
-		gAgent.startTyping();
-	}
-	else
-	{
-		gAgent.stopTyping();
-	}
-
-	/* Doesn't work -- can't tell the difference between a backspace
-	   that killed the selection vs. backspace at the end of line.
-	if (length > 1 
-		&& text[0] == '/'
-		&& key == KEY_BACKSPACE)
-	{
-		// the selection will already be deleted, but we need to trim
-		// off the character before
-		std::string new_text = raw_text.substr(0, length-1);
-		self->mInputEditor->setText( new_text );
-		self->mInputEditor->setCursorToEnd();
-		length = length - 1;
-	}
-	*/
-
-	KEY key = gKeyboard->currentKey();
-
-	// Ignore "special" keys, like backspace, arrows, etc.
-	if (length > 1 
-		&& raw_text[0] == '/'
-		&& key < KEY_SPECIAL)
-	{
-		// we're starting a gesture, attempt to autocomplete
-
-		std::string utf8_trigger = wstring_to_utf8str(raw_text);
-		std::string utf8_out_str(utf8_trigger);
-
-		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
-		{
-			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
-			S32 outlength = self->mChatBox->getLength(); // in characters
-
-			// Select to end of line, starting from the character
-			// after the last one the user typed.
-			self->mChatBox->setSelection(length, outlength);
-		}
-		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
-		{
-			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
-			self->mChatBox->setCursorToEnd();
-		}
-
-		//llinfos << "GESTUREDEBUG " << trigger 
-		//	<< " len " << length
-		//	<< " outlen " << out_str.getLength()
-		//	<< llendl;
-	}
-}
-
-// static
-void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
-{
-	// stop typing animation
-	gAgent.stopTyping();
-}
-
-void LLNearbyChatBar::onChatBoxFocusReceived()
-{
-	mChatBox->setEnabled(!gDisconnected);
-}
-
-EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str)
-{
-	U32 length = str.length();
-	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
-	
-	for (S32 n = 0; n < cnt; n++)
-	{
-		if (length >= sChatTypeTriggers[n].name.length())
-		{
-			std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
-
-			if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
-			{
-				U32 trigger_length = sChatTypeTriggers[n].name.length();
-
-				// It's to remove space after trigger name
-				if (length > trigger_length && str[trigger_length] == ' ')
-					trigger_length++;
-
-				str = str.substr(trigger_length, length);
-
-				if (CHAT_TYPE_NORMAL == type)
-					return sChatTypeTriggers[n].type;
-				else
-					break;
-			}
-		}
-	}
-
-	return type;
-}
-
-void LLNearbyChatBar::sendChat( EChatType type )
-{
-	if (mChatBox)
-	{
-		LLWString text = mChatBox->getConvertedText();
-		if (!text.empty())
-		{
-			// store sent line in history, duplicates will get filtered
-			mChatBox->updateHistory();
-			// Check if this is destined for another channel
-			S32 channel = 0;
-			stripChannelNumber(text, &channel);
-			
-			std::string utf8text = wstring_to_utf8str(text);
-			// Try to trigger a gesture, if not chat to a script.
-			std::string utf8_revised_text;
-			if (0 == channel)
-			{
-				// discard returned "found" boolean
-				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
-			}
-			else
-			{
-				utf8_revised_text = utf8text;
-			}
-
-			utf8_revised_text = utf8str_trim(utf8_revised_text);
-
-			type = processChatTypeTriggers(type, utf8_revised_text);
-
-			if (!utf8_revised_text.empty())
-			{
-				// Chat with animation
-				sendChatFromViewer(utf8_revised_text, type, TRUE);
-			}
-		}
-
-		mChatBox->setText(LLStringExplicit(""));
-	}
-
-	gAgent.stopTyping();
-
-	// If the user wants to stop chatting on hitting return, lose focus
-	// and go out of chat mode.
-	if (gSavedSettings.getBOOL("CloseChatOnReturn"))
-	{
-		stopChat();
-	}
-}
-
-
-void LLNearbyChatBar::onToggleNearbyChatPanel()
-{
-	LLView* nearby_chat = getChildView("nearby_chat");
-
-	if (nearby_chat->getVisible())
-	{
-		if (!isMinimized())
-		{
-			mExpandedHeight = getRect().getHeight();
-		}
-		setResizeLimits(getMinWidth(), COLLAPSED_HEIGHT);
-		nearby_chat->setVisible(FALSE);
-		reshape(getRect().getWidth(), COLLAPSED_HEIGHT);
-		enableResizeCtrls(true, true, false);
-		storeRectControl();
-	}
-	else
-	{
-		nearby_chat->setVisible(TRUE);
-		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-		reshape(getRect().getWidth(), mExpandedHeight);
-		enableResizeCtrls(true);
-		storeRectControl();
-	}
-
-	gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible());
-}
-
-void LLNearbyChatBar::reloadMessages()
-{
-	LLNearbyChat::getInstance()->reloadMessages();
-}
-
-void LLNearbyChatBar::setMinimized(BOOL b)
-{
-	LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat");
-	// when unminimizing with nearby chat visible, go ahead and kill off screen chats
-	if (!b && nearby_chat->getVisible())
-	{
-		nearby_chat->removeScreenChat();
-	}
-		LLFloater::setMinimized(b);
-}
-
-void LLNearbyChatBar::onChatBoxCommit()
-{
-	if (mChatBox->getText().length() > 0)
-	{
-		sendChat(CHAT_TYPE_NORMAL);
-	}
-
-	gAgent.stopTyping();
-}
-
-void LLNearbyChatBar::displaySpeakingIndicator()
-{
-	LLSpeakerMgr::speaker_list_t speaker_list;
-	LLUUID id;
-
-	id.setNull();
-	mSpeakerMgr->update(TRUE);
-	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
-
-	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
-	{
-		LLPointer<LLSpeaker> s = *i;
-		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
-		{
-			id = s->mID;
-			break;
-		}
-	}
-
-	if (!id.isNull())
-	{
-		mOutputMonitor->setVisible(TRUE);
-		mOutputMonitor->setSpeakerId(id);
-	}
-	else
-	{
-		mOutputMonitor->setVisible(FALSE);
-	}
-}
-
-void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
-{
-	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
-}
-
-void LLNearbyChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
-{
-	// Look for "/20 foo" channel chats.
-	S32 channel = 0;
-	LLWString out_text = stripChannelNumber(wtext, &channel);
-	std::string utf8_out_text = wstring_to_utf8str(out_text);
-	std::string utf8_text = wstring_to_utf8str(wtext);
-
-	utf8_text = utf8str_trim(utf8_text);
-	if (!utf8_text.empty())
-	{
-		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
-	}
-
-	// Don't animate for chats people can't hear (chat to scripts)
-	if (animate && (channel == 0))
-	{
-		if (type == CHAT_TYPE_WHISPER)
-		{
-			lldebugs << "You whisper " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
-		}
-		else if (type == CHAT_TYPE_NORMAL)
-		{
-			lldebugs << "You say " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
-		}
-		else if (type == CHAT_TYPE_SHOUT)
-		{
-			lldebugs << "You shout " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
-		}
-		else
-		{
-			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
-			return;
-		}
-	}
-	else
-	{
-		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
-		{
-			lldebugs << "Channel chat: " << utf8_text << llendl;
-		}
-	}
-
-	send_chat_from_viewer(utf8_out_text, type, channel);
-}
-
-// static 
-void LLNearbyChatBar::startChat(const char* line)
-{
-	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
-
-	if (cb )
-	{
-		cb->setVisible(TRUE);
-		cb->setFocus(TRUE);
-		cb->mChatBox->setFocus(TRUE);
-
-		if (line)
-		{
-			std::string line_string(line);
-			cb->mChatBox->setText(line_string);
-		}
-
-		cb->mChatBox->setCursorToEnd();
-	}
-}
-
-// Exit "chat mode" and do the appropriate focus changes
-// static
-void LLNearbyChatBar::stopChat()
-{
-	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
-
-	if (cb)
-	{
-		cb->mChatBox->setFocus(FALSE);
-
-		// stop typing animation
-		gAgent.stopTyping();
-	}
-}
-
-// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
-// Otherwise returns input and channel 0.
-LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
-{
-	if (mesg[0] == '/'
-		&& mesg[1] == '/')
-	{
-		// This is a "repeat channel send"
-		*channel = sLastSpecialChatChannel;
-		return mesg.substr(2, mesg.length() - 2);
-	}
-	else if (mesg[0] == '/'
-			 && mesg[1]
-			 && LLStringOps::isDigit(mesg[1]))
-	{
-		// This a special "/20" speak on a channel
-		S32 pos = 0;
-
-		// Copy the channel number into a string
-		LLWString channel_string;
-		llwchar c;
-		do
-		{
-			c = mesg[pos+1];
-			channel_string.push_back(c);
-			pos++;
-		}
-		while(c && pos < 64 && LLStringOps::isDigit(c));
-		
-		// Move the pointer forward to the first non-whitespace char
-		// Check isspace before looping, so we can handle "/33foo"
-		// as well as "/33 foo"
-		while(c && iswspace(c))
-		{
-			c = mesg[pos+1];
-			pos++;
-		}
-		
-		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
-		*channel = sLastSpecialChatChannel;
-		return mesg.substr(pos, mesg.length() - pos);
-	}
-	else
-	{
-		// This is normal chat.
-		*channel = 0;
-		return mesg;
-	}
-}
-
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
-{
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ChatFromViewer);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_ChatData);
-	msg->addStringFast(_PREHASH_Message, utf8_out_text);
-	msg->addU8Fast(_PREHASH_Type, type);
-	msg->addS32("Channel", channel);
-
-	gAgent.sendReliableMessage();
-
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
-}
-
-class LLChatCommandHandler : public LLCommandHandler
-{
-public:
-	// not allowed from outside the app
-	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
-    // Your code here
-	bool handle(const LLSD& tokens, const LLSD& query_map,
-				LLMediaCtrl* web)
-	{
-		bool retval = false;
-		// Need at least 2 tokens to have a valid message.
-		if (tokens.size() < 2)
-		{
-			retval = false;
-		}
-		else
-		{
-		S32 channel = tokens[0].asInteger();
-			// VWR-19499 Restrict function to chat channels greater than 0.
-			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
-			{
-				retval = true;
-		// Send unescaped message, see EXT-6353.
-		std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
-		send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
-			}
-			else
-			{
-				retval = false;
-				// Tell us this is an unsupported SLurl.
-			}
-		}
-		return retval;
-	}
-};
-
-// Creating the object registers with the dispatcher.
-LLChatCommandHandler gChatHandler;
-
-
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
deleted file mode 100644
index b7c4c993c6..0000000000
--- a/indra/newview/llnearbychatbar.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/** 
- * @file llnearbychatbar.h
- * @brief LLNearbyChatBar class definition
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLNEARBYCHATBAR_H
-#define LL_LLNEARBYCHATBAR_H
-
-#include "llimconversation.h"
-#include "llcombobox.h"
-#include "llgesturemgr.h"
-#include "llchat.h"
-#include "llnearbychat.h"
-#include "llvoiceclient.h"
-#include "lloutputmonitorctrl.h"
-#include "llspeakers.h"
-
-class LLNearbyChatBar :	public LLIMConversation
-{
-public:
-	// constructor for inline chat-bars (e.g. hosted in chat history window)
-	LLNearbyChatBar(const LLSD& key);
-	~LLNearbyChatBar() {}
-
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onOpen(const LLSD& key);
-
-	static LLNearbyChatBar* getInstance();
-//	static LLNearbyChatBar* findInstance();
-
-	void addToHost();
-
-	void reloadMessages();
-	LLLineEditor* getChatBox() { return mChatBox; }
-
-	virtual void draw();
-
-	std::string getCurrentChat();
-	virtual BOOL handleKeyHere( KEY key, MASK mask );
-
-	static void startChat(const char* line);
-	static void stopChat();
-
-	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
-	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
-
-	void showHistory();
-	void showTranslationCheckbox(BOOL show);
-	/*virtual*/void setMinimized(BOOL b);
-
-protected:
-	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
-	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
-	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
-	void onChatBoxFocusReceived();
-
-	void sendChat( EChatType type );
-	void onChatBoxCommit();
-	void onChatFontChange(LLFontGL* fontp);
-
-	/* virtual */ bool applyRectControl();
-
-	void onToggleNearbyChatPanel();
-
-	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
-	EChatType processChatTypeTriggers(EChatType type, std::string &str);
-
-	void displaySpeakingIndicator();
-
-	// set the enable/disable state for the Call button
-	virtual void enableDisableCallBtn();
-
-	// Which non-zero channel did we last chat on?
-	static S32 sLastSpecialChatChannel;
-
-	LLLineEditor*			mChatBox;
-	LLView*					mNearbyChat;
-	LLOutputMonitorCtrl*	mOutputMonitor;
-	LLLocalSpeakerMgr*		mSpeakerMgr;
-
-	S32 mExpandedHeight;
-};
-
-#endif
diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llnearbychatbarlistener.cpp
index a63e1fb76e..61815d1864 100644
--- a/indra/newview/llnearbychatbarlistener.cpp
+++ b/indra/newview/llnearbychatbarlistener.cpp
@@ -29,14 +29,14 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llnearbychatbarlistener.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 
 #include "llagent.h"
 #include "llchat.h"
 
 
 
-LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar)
+LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChat & chatbar)
   : LLEventAPI("LLChatBar",
                "LLChatBar listener to (e.g.) sendChat, etc."),
 	mChatbar(chatbar)
diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llnearbychatbarlistener.h
index 9af9bc1f7b..0537275424 100644
--- a/indra/newview/llnearbychatbarlistener.h
+++ b/indra/newview/llnearbychatbarlistener.h
@@ -33,17 +33,17 @@
 #include "lleventapi.h"
 
 class LLSD;
-class LLNearbyChatBar;
+class LLNearbyChat;
 
 class LLNearbyChatBarListener : public LLEventAPI
 {
 public:
-	LLNearbyChatBarListener(LLNearbyChatBar & chatbar);
+	LLNearbyChatBarListener(LLNearbyChat & chatbar);
 
 private:
     void sendChat(LLSD const & chat_data) const;
 
-	LLNearbyChatBar & mChatbar;
+	LLNearbyChat & mChatbar;
 };
 
 #endif // LL_LLNEARBYCHATBARLISTENER_H
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index f26cc85019..e91a3fc334 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -40,7 +40,7 @@
 
 #include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
 #include "llviewerwindow.h"//for screen channel position
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 #include "llrootview.h"
 #include "lllayoutstack.h"
 
@@ -487,9 +487,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	if(chat_msg.mText.empty())
 		return;//don't process empty messages
 
-	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-
-	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
+	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
 
 	// Build notification data 
 	LLSD chat;
@@ -558,8 +556,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	sChatWatcher->post(chat);
 
 
-	if( !chat_bar->isMinimized()
-		&& nearby_chat->isInVisibleChain() 
+	if( nearby_chat->isInVisibleChain()
 		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") )
 		|| mChannel.isDead()
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index a1d5db2e27..507c6686fd 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -29,7 +29,7 @@
 
 #include "llfloaterreg.h"
 #include "llnearbychat.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 #include "llnotificationhandler.h"
 #include "llnotifications.h"
 #include "lltoastnotifypanel.h"
@@ -86,8 +86,7 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 
 		// don't show toast if Nearby Chat is opened
 		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-		LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
-		if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible())
+		if (!nearby_chat->isMinimized() && nearby_chat->getVisible())
 		{
 			return false;
 		}
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index bc4097cd93..389baa86cd 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -41,85 +41,4 @@
 #include "llspeakers.h"
 #include "lltrans.h"
 
-LLPanelChatControlPanel::~LLPanelChatControlPanel()
-{
-}
 
-BOOL LLPanelChatControlPanel::postBuild()
-{
-	return TRUE;
-}
-
-void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
-{
-	//Method is called twice for AdHoc and Group chat. Second time when server init reply received
-	mSessionId = session_id;
-}
-
-
-LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):
-mParticipantList(NULL)
-{
-}
-
-BOOL LLPanelGroupControlPanel::postBuild()
-{
-
-	return LLPanelChatControlPanel::postBuild();
-}
-
-LLPanelGroupControlPanel::~LLPanelGroupControlPanel()
-{
-	delete mParticipantList;
-	mParticipantList = NULL;
-}
-
-// virtual
-void LLPanelGroupControlPanel::draw()
-{
-	// Need to resort the participant list if it's in sort by recent speaker order.
-	if (mParticipantList)
-		mParticipantList->update();
-	LLPanelChatControlPanel::draw();
-}
-
-
-void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata)
-{
-	// TODO: Check this code when when sort order menu will be added. (EM)
-	if (false && !mParticipantList)
-		return;
-
-	std::string chosen_item = userdata.asString();
-
-	if (chosen_item == "sort_name")
-	{
-		mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
-	}
-
-}
-
-void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
-{
-	LLPanelChatControlPanel::setSessionId(session_id);
-
-	mGroupID = session_id;
-
-	// for group and Ad-hoc chat we need to include agent into list
-	if(!mParticipantList)
-	{
-		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
-		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);
-	}
-}
-
-
-LLPanelAdHocControlPanel::LLPanelAdHocControlPanel(const LLUUID& session_id):LLPanelGroupControlPanel(session_id)
-{
-}
-
-BOOL LLPanelAdHocControlPanel::postBuild()
-{
-	//We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat
-	return LLPanelChatControlPanel::postBuild();
-}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 5ced32a9ab..df1962f5fe 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -134,7 +134,6 @@
 #include "llscriptfloater.h"
 #include "llfloatermodelpreview.h"
 #include "llcommandhandler.h"
-#include "llnearbychatbar.h"
 
 // *NOTE: Please add files in alphabetical order to keep merges easy.
 
@@ -187,8 +186,6 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
 
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
-	LLFloaterReg::add("chat_bar", "floater_chat_bar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChatBar>);
-
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
 
 	LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
@@ -211,6 +208,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);	
 	LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
 
+	LLFloaterReg::add("chat_bar", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
 	LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
 	LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>);
 	LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>);
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index a32a78cbf9..c7d37e102e 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -40,7 +40,7 @@
 #include "llviewermessage.h" // send_guid_sound_trigger
 #include "llviewernetwork.h"
 #include "llagent.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 
 // Globals
 LLViewerGestureList gGestureList;
@@ -130,7 +130,7 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
 	{
 		// Don't play nodding animation, since that might not blend
 		// with the gesture animation.
-		LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+		LLNearbyChat::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
 	}
 }
 
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 1aa9fd8a45..385d3cd29a 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -31,7 +31,7 @@
 #include "llmath.h"
 #include "llagent.h"
 #include "llagentcamera.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 #include "llviewercontrol.h"
 #include "llfocusmgr.h"
 #include "llmorphview.h"
@@ -534,7 +534,7 @@ void stop_moving( EKeystate s )
 void start_chat( EKeystate s )
 {
 	// start chat
-	LLNearbyChatBar::startChat(NULL);
+	LLNearbyChat::startChat(NULL);
 }
 
 void start_gesture( EKeystate s )
@@ -543,15 +543,15 @@ void start_gesture( EKeystate s )
 	if (KEYSTATE_UP == s &&
 		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
 	{
- 		if (LLNearbyChatBar::getInstance()->getCurrentChat().empty())
+ 		if (LLNearbyChat::getInstance()->getCurrentChat().empty())
  		{
  			// No existing chat in chat editor, insert '/'
- 			LLNearbyChatBar::startChat("/");
+ 			LLNearbyChat::startChat("/");
  		}
  		else
  		{
  			// Don't overwrite existing text in chat editor
- 			LLNearbyChatBar::startChat(NULL);
+ 			LLNearbyChat::startChat(NULL);
  		}
 	}
 }
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 32f693b009..5b8cf52298 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -185,7 +185,7 @@
 #include "llviewerjoystick.h"
 #include "llviewernetwork.h"
 #include "llpostprocess.h"
-#include "llnearbychatbar.h"
+#include "llnearbychat.h"
 #include "llagentui.h"
 #include "llwearablelist.h"
 
@@ -2482,7 +2482,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	// Traverses up the hierarchy
 	if( keyboard_focus )
 	{
-		LLNearbyChatBar* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar");
+		LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("chat_bar");
 
 		if (nearby_chat)
 		{
@@ -2549,11 +2549,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
-		LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar")->getChatBox();
+		LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar")->getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
-			LLNearbyChatBar::getInstance()->startChat(NULL);
+			LLNearbyChat::getInstance()->startChat(NULL);
 			return TRUE;
 		}
 	}
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
deleted file mode 100644
index 7688525e13..0000000000
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ /dev/null
@@ -1,202 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- open_positioning="specified"
- specified_left="10"
- specified_bottom="10"
- background_visible="true"
- default_tab_group="1"
- height="355"
- help_topic="chat_bar"
- layout="topleft"
- name="chat_bar"
- can_dock="false"
- can_minimize="true"
- can_close="true"
- visible="false"
- width="394"
- can_resize="true"
- can_tear_off="false"
- min_width="250"
- min_height="80"
- single_instance="true"
- title="Nearby chat">
-    <floater.string name="call_btn_start">VoicePTT_Off</floater.string>
-    <floater.string name="call_btn_stop">VoicePTT_On</floater.string>
-    <floater.string
-     name="collapse_icon"
-     value="TabIcon_Open_Off"/>
-    <floater.string
-     name="expand_icon"
-     value="TabIcon_Close_Off"/>
-    <floater.string
-     name="tear_off_icon"
-     value="tearoffbox.tga"/>
-    <floater.string
-     name="return_icon"
-     value="Icon_Dock_Foreground"/>
-     <view
-        follows="all"
-        layout="topleft"
-        name="contents_view"
-        top="0"
-        left="0"
-        height="355"
-        width="394">
-      <panel
-         follows="left|top|right"
-         layout="topleft"
-         name="toolbar_panel"
-         top="0"
-         left="0"
-         height="35"
-         width="394">         
-             <menu_button
-                 menu_filename="menu_im_session_showmodes.xml"
-                 follows="top|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Left_Over"
-                 image_overlay="OptionsMenu_Off"
-                 image_selected="Toolbar_Left_Selected"
-                 image_unselected="Toolbar_Left_Off"
-                 layout="topleft"
-                 left="5"
-                 name="view_options_btn"
-                 top="5"
-                 width="31" />
-             <button
-                 follows="top|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="AddItem_Off"
-                 image_selected="Toolbar_Middle_Selected"
-                 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left_pad="4"
-                 name="add_btn"
-                 width="31">
-                 <commit_callback
-                    function="Chats.add" />
-             </button>   
-             <button
-                 follows="top|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Right_Over"
-                 image_overlay="VoicePTT_Off"
-                 image_selected="Toolbar_Right_Selected"
-                 image_unselected="Toolbar_Right_Off"
-                 layout="topleft"
-                 top="5"
-                 left_pad="4"
-                 name="voice_call_btn"
-                 width="31">
-                 <commit_callback
-                    function="Chats.add" />
-             </button>
-             <button
-                 follows="right|top"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Icon_Close_Foreground"
-                 image_selected="Toolbar_Middle_Selected"
-                 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left="283"
-                 name="close_btn"
-                 width="31">
-             </button>
-             <button
-                 follows="right|top"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="TabIcon_Open_Off"
-                 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left_pad="5"
-                 name="expand_collapse_btn"
-                 width="31">
-             </button>
-             <button
-                 follows="right|top"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="tearoffbox.tga"
-                 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 top="5"
-                 left_pad="5"
-                 name="tear_off_btn"
-                 width="31">
-             </button>
-     </panel>
-    <panel
-        top="35"
-        left="0"
-        class="panel_nearby_chat"
-        follow="all"
-        width="390"
-        height="0"
-        visible="false"
-        filename="panel_nearby_chat.xml"
-        name="nearby_chat" />
-    <panel
-    	width="390"
-    	height="10"
-    	visible="true" />
-    <panel width="394" 
-           height="31" 
-           left="0" 
-           name="bottom_panel"
-           bottom="-1" 
-           follows="left|right|bottom" 
-           tab_group="1">
-      <line_editor
-        border_style="line"
-        border_thickness="1"
-        follows="left|right"
-        height="20"
-        label="Click here to chat."
-        layout="topleft"
-        left="1"
-        max_length_bytes="1023"
-        name="chat_box"
-        tool_tip="Press Enter to say, Ctrl+Enter to shout"
-        top="2"
-        width="384" />
-      <output_monitor
-        auto_update="true"
-        follows="right"
-        draw_border="false"
-        height="16"
-        layout="topleft"
-        left_pad="-24"
-        mouse_opaque="true"
-        name="chat_zone_indicator"
-        top="6"
-        visible="true"
-        width="20" />
-      <button
-        follows="right"
-        visible="false"
-        is_toggle="true"
-        width="20"
-        top="2"
-        layout="topleft"
-        left_pad="12"
-        image_disabled="ComboButton_UpOff"
-        image_unselected="ComboButton_UpOff"
-        image_selected="ComboButton_On"
-        image_pressed="ComboButton_UpSelected"
-        image_pressed_selected="ComboButton_Selected"
-        height="23"
-        chrome="true"
-        name="show_nearby_chat"
-        tool_tip="Shows/hides nearby chat log">
-      </button>
-    </panel>
-  </view>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index a332bb5b12..c5cacab9f4 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -138,18 +138,24 @@
   top_pad="0"
   left="0">
     <layout_panel
-      name="im_control_panel_holder"
+      name="speakers_list_panel"
       min_width="115"
       width="150" 
       height="310" 
       auto_resize="false">
-      <panel
-        name="panel_im_control_panel"
-        layout="topleft"
-        height="310"
-        width="150" 
-        follows="all"/>
-      </layout_panel>
+            <avatar_list
+             color="DkGray2"
+             follows="all"
+             height="100"
+             ignore_online_status="true"
+             layout="topleft"
+             name="speakers_list"
+             opaque="false"
+             show_info_btn="true"
+             show_profile_btn="false"
+             show_speaking_indicator="false"
+             width="145" />
+    </layout_panel>
     <layout_panel
        default_tab_group="3"
        left="0"
@@ -158,27 +164,82 @@
        height="200"
 	    width="254"
        user_resize="true">
-        <chat_history
-	     font="SansSerifSmall"
-         follows="all"
-         height="170"
-         name="chat_history"
-         parse_highlights="true"
-         parse_urls="true"
-         left="1"
-         width="249">
-        </chat_history>
-        <line_editor
-         bottom="0"
-         follows="left|right|bottom"
-	     font="SansSerifSmall"
-         height="20"
-         label="To"
-         layout="bottomleft"
-         name="chat_editor"
-         tab_group="3"
-         width="249">
-        </line_editor>
+         <layout_stack
+          animate="true" 
+          default_tab_group="2"
+          follows="all"
+          height="200"
+          width="254"
+          layout="topleft"
+          orientation="vertical"
+          name="chat_area"
+          tab_group="1"
+          left_pad="0"
+          top="0">
+            <layout_panel
+             auto_resize="false"
+             height="26"
+             layout="topleft"
+             left_delta="0"
+             name="translate_chat_checkbox_lp"
+             top_delta="0"
+             visible="true"
+             width="230">
+                <check_box
+                 top="10"
+                 control_name="TranslateChat"
+                 enabled="true"
+                 height="16"
+                 label="Translate chat"
+                 layout="topleft"
+                 left="5"
+                 name="translate_chat_checkbox"
+                 width="230" />
+            </layout_panel>
+            <layout_panel
+             auto_resize="false"
+             height="170"
+             layout="topleft"
+             left_delta="0"
+             name="translate_chat_checkbox_lp"
+             top_delta="0"
+             visible="true"
+             width="230">      
+           		<chat_history
+    	     		font="SansSerifSmall"
+             		follows="all"
+             		height="170"
+            	 	name="chat_history"
+             		parse_highlights="true"
+             		parse_urls="true"
+             		left="1"
+             		width="229">
+            	</chat_history>
+            	<line_editor
+             		bottom="0"
+             		follows="left|right|bottom"
+	         		font="SansSerifSmall"
+             		height="20"
+             		label="To"
+             		layout="bottomleft"
+             		name="chat_editor"
+             		tab_group="3"
+             		width="230">
+            	</line_editor>
+            	<output_monitor
+                 auto_update="true"
+                 follows="right"
+                 draw_border="false"
+                 height="16"
+                 layout="topleft"
+                 left_pad="-24"
+                 mouse_opaque="true"
+                 name="chat_zone_indicator"
+                 top="6"
+                 visible="true"
+                 width="20" />           	
+            </layout_panel>
+        </layout_stack>
     </layout_panel>
   </layout_stack>
     </view>
diff --git a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
deleted file mode 100644
index d68fa6ca6c..0000000000
--- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="215"
- name="panel_im_control_panel"
- width="150">
-    <layout_stack
-     mouse_opaque="false"
-     border_size="0"
-     clip="false"
-     follows="all"
-     height="215"
-     layout="topleft"
-     left="3"
-     name="vertical_stack"
-     orientation="vertical"
-     top="0"
-     width="147">
-        <layout_panel
-         auto_resize="true"
-         follows="top|left"
-         height="130"
-         layout="topleft"
-         left="0"
-         min_height="0"
-         mouse_opaque="false"
-         width="147"
-         top="0"
-         name="speakers_list_panel">
-            <avatar_list
-             color="DkGray2"
-             follows="all"
-             height="130"
-             ignore_online_status="true"
-             layout="topleft"
-             name="speakers_list"
-             opaque="false"
-             show_info_btn="true"
-             show_profile_btn="false"
-             show_speaking_indicator="false"
-             width="147" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="130"
-         name="call_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="20"
-             label="Call"
-             name="call_btn"
-             width="130"
-             top="0" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="130"
-         name="end_call_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="20"
-             label="Leave Call"
-             name="end_call_btn"
-             top="0"/>
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="130"
-         name="voice_ctrls_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="20"
-             label="Voice Controls"
-             name="voice_ctrls_btn"
-             top="0"
-             use_ellipses="true" />
-        </layout_panel>
-    </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
deleted file mode 100644
index a5295ebe01..0000000000
--- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="238"
- name="panel_im_control_panel"
- width="150">
-    <layout_stack
-     mouse_opaque="false"
-     border_size="0"
-     clip="false"
-     follows="all"
-     height="238"
-     layout="topleft"
-     left="5"
-     name="vertical_stack"
-     orientation="vertical"
-     top="0"
-     width="145">
-        <layout_panel
-         auto_resize="true"
-         follows="top|left"
-         height="100"
-         layout="topleft"
-         min_height="0"
-         mouse_opaque="false"
-         width="145"
-         top="0"
-         name="speakers_list_panel">
-            <avatar_list
-             color="DkGray2"
-             follows="all"
-             height="100"
-             ignore_online_status="true"
-             layout="topleft"
-             name="speakers_list"
-             opaque="false"
-             show_info_btn="true"
-             show_profile_btn="false"
-             show_speaking_indicator="false"
-             width="145" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         width="130"
-         name="voice_ctrls_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="23"
-             label="Open Voice Controls"
-             name="voice_ctrls_btn"
-             use_ellipses="true" />
-        </layout_panel>
-    </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
index b415ba780d..4de56b424e 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
@@ -6,16 +6,17 @@
  help_topic="nearby_chat"
  layout="topleft"
  name="nearby_chat"
- width="394">
+ width="242"
+ height="169">
   <layout_stack
    follows="all"
-   height="278"
+   height="164"
    layout="topleft"
    left="0"
    name="stack"
    top="5"
    orientation="vertical"
-   width="394">
+   width="242">
     <layout_panel
      auto_resize="false"
      height="26"
@@ -24,7 +25,7 @@
      name="translate_chat_checkbox_lp"
      top_delta="0"
      visible="true"
-     width="387">
+     width="230">
       <check_box
        top="10"
        control_name="TranslateChat"
@@ -34,15 +35,15 @@
        layout="topleft"
        left="5"
        name="translate_chat_checkbox"
-       width="374" />
+       width="230" />
     </layout_panel>
     <layout_panel
      auto_resize="true"
-     height="256"
+     height="138"
      left_delta="0"
      layout="topleft"
      name="chat_history_lp"
-     width="394">
+     width="242">
       <chat_history
        bg_readonly_color="ChatHistoryBgColor"
        bg_writeable_color="ChatHistoryBgColor"
@@ -50,7 +51,7 @@
        layout="topleft"
        left="5"
        left_widget_pad="0"
-       height="240"
+       height="138"
        name="chat_history"
        parse_highlights="true"
        parse_urls="true"
@@ -58,7 +59,7 @@
        text_color="ChatHistoryTextColor"
        text_readonly_color="ChatHistoryTextColor"
        top="0"
-       width="384" />
+       width="237" />
     </layout_panel>
   </layout_stack>
 </panel>
-- 
cgit v1.2.3


From b7b612500132acf05e82f1482460ffa9312fcc4a Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 1 Jun 2012 14:57:51 +0300
Subject: CHUI-119 FIXED Bug fixed. Clean up a code

---
 indra/newview/llnearbychat.cpp                     |  7 +-
 indra/newview/llstartup.cpp                        |  9 ---
 .../skins/default/xui/en/floater_im_session.xml    | 88 +++++++++++++---------
 3 files changed, 58 insertions(+), 46 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 2d7095957e..4ac72858d3 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -68,7 +68,6 @@
 
 S32 LLNearbyChat::sLastSpecialChatChannel = 0;
 
-
 // --- 2 functions in the global namespace :( ---
 bool isWordsName(const std::string& name)
 {
@@ -179,8 +178,12 @@ BOOL LLNearbyChat::postBuild()
 	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
 
 	mChatHistory = getChild<LLChatHistory>("chat_history");
+	if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
+	{
+		loadHistory();
+	}
 
-	return LLIMConversation::postBuild();;
+	return LLIMConversation::postBuild();
 }
 
 void LLNearbyChat::onNearbySpeakers()
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0ac8c1fe39..2f13ba5ab1 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1376,15 +1376,6 @@ bool idle_startup()
 		LLVoiceClient::getInstance()->updateSettings();
 		display_startup();
 
-		//gCacheName is required for nearby chat history loading
-		//so I just moved nearby history loading a few states further
-		if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
-		{
-			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-			if (nearby_chat) nearby_chat->loadHistory();
-		}
-		display_startup();
-
 		// *Note: this is where gWorldMap used to be initialized.
 
 		// register null callbacks for audio until the audio system is initialized
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index c5cacab9f4..beeb4eea9b 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -70,8 +70,6 @@
                  left_pad="4"
                  name="add_btn"
                  width="31">
-                 <commit_callback
-                    function="Chats.add" />
              </button>   
              <button
                  follows="top|left"
@@ -85,8 +83,6 @@
                  left_pad="4"
                  name="voice_call_btn"
                  width="31">
-                 <commit_callback
-                    function="Chats.add" />
              </button>
              <button
                  follows="right|top"
@@ -136,9 +132,12 @@
   name="im_panels"
   tab_group="1"
   top_pad="0"
-  left="0">
+  left="0"
+  auto_resize="true"
+  user_resize="true">
     <layout_panel
       name="speakers_list_panel"
+      follows="all"
       min_width="115"
       width="150" 
       height="310" 
@@ -146,7 +145,7 @@
             <avatar_list
              color="DkGray2"
              follows="all"
-             height="100"
+             height="310"
              ignore_online_status="true"
              layout="topleft"
              name="speakers_list"
@@ -154,28 +153,44 @@
              show_info_btn="true"
              show_profile_btn="false"
              show_speaking_indicator="false"
-             width="145" />
+             width="150" />
     </layout_panel>
     <layout_panel
        default_tab_group="3"
        left="0"
        tab_group="2"
+       follows="all"
        top="0"
-       height="200"
-	    width="254"
-       user_resize="true">
+       height="310"
+	   width="244"
+       layout="topleft"
+       user_resize="true"
+       auto_resize="true"
+       visible="true"
+       name="left_part_holder">
+        <panel
+         name="trnsAndChat_panel"
+         follows="all"
+         layout="topleft"
+         visible="true"
+         height="275"
+         width="244">
          <layout_stack
           animate="true" 
           default_tab_group="2"
           follows="all"
-          height="200"
-          width="254"
+          height="275"
+          width="244"
           layout="topleft"
+          visible="true"
           orientation="vertical"
-          name="chat_area"
+          name="translate_and_chat_stack"
           tab_group="1"
+          auto_resize="true"
+          user_resize="true"
           left_pad="0"
-          top="0">
+          top="0"
+          left="0">
             <layout_panel
              auto_resize="false"
              height="26"
@@ -197,49 +212,52 @@
                  width="230" />
             </layout_panel>
             <layout_panel
-             auto_resize="false"
-             height="170"
+             height="248"
+             width="234"
              layout="topleft"
+             follows="all"
              left_delta="0"
-             name="translate_chat_checkbox_lp"
              top_delta="0"
+             bottom="0"
              visible="true"
-             width="230">      
+             user_resize="true"
+             auto_resize="true"
+             name="chat_holder">      
            		<chat_history
     	     		font="SansSerifSmall"
              		follows="all"
-             		height="170"
+             		visible="true"
+             		height="240"
             	 	name="chat_history"
              		parse_highlights="true"
              		parse_urls="true"
              		left="1"
              		width="229">
-            	</chat_history>
+            	</chat_history>           
+            </layout_panel>
+           </layout_stack>
+           </panel>
+            <panel width="228" 
+             height="31" 
+             left="4"
+             right="4" 
+             name="bottom_panel"
+             bottom="-1" 
+             follows="left|right|bottom" 
+             tab_group="1">    
             	<line_editor
              		bottom="0"
              		follows="left|right|bottom"
 	         		font="SansSerifSmall"
+	         		visible="true"
              		height="20"
              		label="To"
              		layout="bottomleft"
              		name="chat_editor"
              		tab_group="3"
-             		width="230">
+             		width="240">
             	</line_editor>
-            	<output_monitor
-                 auto_update="true"
-                 follows="right"
-                 draw_border="false"
-                 height="16"
-                 layout="topleft"
-                 left_pad="-24"
-                 mouse_opaque="true"
-                 name="chat_zone_indicator"
-                 top="6"
-                 visible="true"
-                 width="20" />           	
-            </layout_panel>
-        </layout_stack>
+              </panel>
     </layout_panel>
   </layout_stack>
     </view>
-- 
cgit v1.2.3


From 30a6da68bcee5b871fd0a18dab703fe20271d83c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 1 Jun 2012 16:36:58 +0300
Subject: Build fix

---
 indra/newview/llimconversation.cpp | 4 ++--
 indra/newview/llnearbychat.cpp     | 4 ----
 indra/newview/llnearbychat.h       | 2 --
 3 files changed, 2 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 893d8dc83f..d8c7c63e9e 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -37,7 +37,7 @@
 #include "llnearbychat.h"
 #include "llnearbychat.h"
 
-const F32 REFRESH_INTERVAL = 0.2;
+const F32 REFRESH_INTERVAL = 0.2f;
 
 LLIMConversation::LLIMConversation(const LLUUID& session_id)
   : LLTransientDockableFloater(NULL, true, session_id)
@@ -127,7 +127,7 @@ void LLIMConversation::buildParticipantList()
 	}
 	else
 	{
-		// for group and Ad-hoc chat we need to include agent into list
+		// for group and ad-hoc chat we need to include agent into list
 		if(!mIsP2PChat && !mParticipantList && mSessionID.notNull())
 		{
 			LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 4ac72858d3..8b54c6ce53 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -318,10 +318,6 @@ void	LLNearbyChat::setVisible(BOOL visible)
 	LLIMConversation::setVisible(visible);
 }
 
-void LLNearbyChat::onCallButtonClicked()
-{
-	LLAgent::toggleMicrophone(NULL);
-}
 
 void LLNearbyChat::enableDisableCallBtn()
 {
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index b38111defa..bc0e54de15 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -108,8 +108,6 @@ protected:
 
 	void displaySpeakingIndicator();
 
-	void onCallButtonClicked();
-
 	// set the enable/disable state for the Call button
 	virtual void enableDisableCallBtn();
 
-- 
cgit v1.2.3


From 164e1073952060cf88a163945d6745934db62620 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 5 Jun 2012 18:20:01 +0300
Subject: CHUI-103 Added square brackets to a messages from Second Life in the
 plain text mode; changed the default colors of user's messages

---
 indra/newview/llchathistory.cpp        | 8 ++++++++
 indra/newview/skins/default/colors.xml | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index c514261b60..cfc70a1b0e 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -693,6 +693,7 @@ void LLChatHistory::clear()
 void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params)
 {
 	bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean();
+	bool square_brackets = false; // square brackets necessary for a system messages
 
 	llassert(mEditor);
 	if (!mEditor)
@@ -781,6 +782,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	// show timestamps and names in the compact mode
 	if (use_plain_text_chat_history)
 	{
+		square_brackets = chat.mFromName == SYSTEM_FROM;
+
 		LLStyle::Params timestamp_style(style_params);
 
 		// timestams showing
@@ -942,6 +945,11 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			message = chat.mFromName + message;
 		}
 		
+		if (square_brackets)
+		{
+			message = "[" + message + "]";
+		}
+
 		mEditor->appendText(message, prependNewLineState, style_params);
 		prependNewLineState = false;
 	}
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index b616e2327b..5205988d5d 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -766,7 +766,7 @@
      reference="LtGray" />
     <color
      name="UserChatColor"
-     reference="White" />
+     reference="Yellow" />
     <color
      name="llOwnerSayChatColor"
      reference="LtYellow" />
-- 
cgit v1.2.3


From d11f542ffefdc5db845028d5a260b5b0ad12dea6 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 7 Jun 2012 00:59:05 +0300
Subject: CHUI-120 WIP Added starting ad hoc conference in the same floater as
 P2P chat, after adding more participants. - Added a parameter to
 LLAvatarActions::startConference() and LLIMMgr::addSession() to pass the uuid
 of a P2P IM floater which should be used to start a new conference in it. -
 In LLChicletBar::sessionRemoved() we don't close the IM floater if it is
 going to be re-used for a new conference.

---
 indra/newview/llavataractions.cpp                  |   4 +-
 indra/newview/llavataractions.h                    |   4 +-
 indra/newview/llchicletbar.cpp                     |   8 +-
 indra/newview/llimfloater.cpp                      | 158 +++++++++++----------
 indra/newview/llimfloater.h                        |  10 +-
 indra/newview/llimview.cpp                         |  15 +-
 indra/newview/llimview.h                           |   4 +-
 indra/newview/llnearbychat.cpp                     |   1 +
 indra/newview/llpanelpeoplemenus.cpp               |   2 +-
 indra/newview/llstartup.cpp                        |   1 -
 .../skins/default/xui/en/floater_im_session.xml    |   6 +-
 11 files changed, 117 insertions(+), 96 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index aa626a9a30..53b87faf66 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -285,7 +285,7 @@ bool LLAvatarActions::canCall()
 }
 
 // static
-void LLAvatarActions::startConference(const uuid_vec_t& ids)
+void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& floater_id)
 {
 	// *HACK: Copy into dynamic array
 	LLDynamicArray<LLUUID> id_array;
@@ -294,7 +294,7 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids)
 		id_array.push_back(*it);
 	}
 	const std::string title = LLTrans::getString("conference-title");
-	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array);
+	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array, false, floater_id);
 	if (session_id != LLUUID::null)
 	{
 		LLIMFloater::show(session_id);
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index e5dad74fc8..0a69ad86a3 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -86,9 +86,9 @@ public:
 	static void startAdhocCall(const uuid_vec_t& ids);
 
 	/**
-	 * Start conference chat with the given avatars.
+	 * Start conference chat with the given avatars in a specific IM floater.
 	 */
-	static void startConference(const uuid_vec_t& ids);
+	static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
 
 	/**
 	 * Show avatar profile.
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index f1bc51fbe7..8701b602ce 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -125,10 +125,12 @@ void LLChicletBar::sessionRemoved(const LLUUID& session_id)
 	if(getChicletPanel())
 	{
 		// IM floater should be closed when session removed and associated chiclet closed
-		LLIMFloater* iMfloater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-		if (iMfloater != NULL)
+		LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+		if (im_floater != NULL && !im_floater->getStartConferenceInSameFloater())
 		{
-			iMfloater->closeFloater();
+			// Close the IM floater only if we are not planning to close the P2P chat
+			// and start a new conference in the same floater.
+			im_floater->closeFloater();
 		}
 
 		getChicletPanel()->removeChiclet(session_id);
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index c99da9e9c1..f04fecca26 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -71,18 +71,12 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mTypingTimer(),
 	mTypingTimeoutTimer(),
 	mPositioned(false),
-	mSessionInitialized(false)
+	mSessionInitialized(false),
+	mStartConferenceInSameFloater(false)
 {
 	mIsNearbyChat = false;
+	initIMSession(session_id);
 
-	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
-
-	if (mSession)
-	{
-		mIsP2PChat = mSession->isP2PSessionType();
-		mSessionInitialized = mSession->mSessionInitialized;
-		mDialog = mSession->mType;
-	}
 	setOverlapsScreenChannel(true);
 
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
@@ -112,6 +106,29 @@ void LLIMFloater::onFocusReceived()
 // virtual
 void LLIMFloater::onClose(bool app_quitting)
 {
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
+				mSessionID);
+
+	if (session == NULL)
+	{
+		llwarns << "Empty session." << llendl;
+		return;
+	}
+
+	bool is_call_with_chat = session->isGroupSessionType()
+			|| session->isAdHocSessionType() || session->isP2PSessionType();
+
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+	if (is_call_with_chat && voice_channel != NULL
+			&& voice_channel->isActive())
+	{
+		LLSD payload;
+		payload["session_id"] = mSessionID;
+		LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+		return;
+	}
+
 	setTyping(false);
 
 	// The source of much argument and design thrashing
@@ -211,8 +228,24 @@ LLIMFloater::~LLIMFloater()
 	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
 }
 
-//virtual
-BOOL LLIMFloater::postBuild()
+void LLIMFloater::initIMSession(const LLUUID& session_id)
+{
+	// Change the floater key to bind it to a new session.
+	setKey(session_id);
+
+	mSessionID = session_id;
+	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+	if (mSession)
+	{
+		mIsP2PChat = mSession->isP2PSessionType();
+		mSessionInitialized = mSession->mSessionInitialized;
+
+		mDialog = mSession->mType;
+	}
+}
+
+void LLIMFloater::initIMFloater()
 {
 	const LLUUID& other_party_id =
 			LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
@@ -223,6 +256,34 @@ BOOL LLIMFloater::postBuild()
 
 	boundVoiceChannel();
 
+	// Show control panel in torn off floaters only.
+	mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel"));
+
+	// Disable input editor if session cannot accept text
+	if ( mSession && !mSession->mTextIMPossible )
+	{
+		mInputEditor->setEnabled(FALSE);
+		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
+	}
+
+	if (mIsP2PChat)
+	{
+		// look up display name for window title
+		LLAvatarNameCache::get(mSession->mOtherParticipantID,
+							   boost::bind(&LLIMFloater::onAvatarNameCache,
+										   this, _1, _2));
+	}
+	else
+	{
+		std::string session_name(LLIMModel::instance().getName(mSessionID));
+		updateSessionName(session_name, session_name);
+	}
+}
+
+//virtual
+BOOL LLIMFloater::postBuild()
+{
+	LLIMConversation::postBuild();
 
 	mInputEditor = getChild<LLLineEditor>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
@@ -248,26 +309,6 @@ BOOL LLIMFloater::postBuild()
 
 	mTypingStart = LLTrans::getString("IM_typing_start_string");
 
-	// Disable input editor if session cannot accept text
-	if ( mSession && !mSession->mTextIMPossible )
-	{
-		mInputEditor->setEnabled(FALSE);
-		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
-	}
-
-	if (mIsP2PChat)
-	{
-		// look up display name for window title
-		LLAvatarNameCache::get(mSession->mOtherParticipantID,
-							   boost::bind(&LLIMFloater::onAvatarNameCache,
-										   this, _1, _2));
-	}
-	else
-	{
-		std::string session_name(LLIMModel::instance().getName(mSessionID));
-		updateSessionName(session_name, session_name);
-	}
-	
 	childSetAction("voice_call_btn", boost::bind(&LLIMFloater::onCallButtonClicked, this));
 
 	LLVoiceClient::getInstance()->addObserver(this);
@@ -275,7 +316,9 @@ BOOL LLIMFloater::postBuild()
 	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
 	//see LLFloaterIMPanel for how it is done (IB)
 
-	return LLIMConversation::postBuild();
+	initIMFloater();
+
+	return TRUE;
 }
 
 void LLIMFloater::boundVoiceChannel()
@@ -603,17 +646,15 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	//will be different only for an ad-hoc im session
 	if (mSessionID != im_session_id)
 	{
-		mSessionID = im_session_id;
-		setKey(im_session_id);
+		initIMSession(im_session_id);
 
 		boundVoiceChannel();
 
-		mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
-		mIsP2PChat = mSession && mSession->isP2PSessionType();
-
 		buildParticipantList();
 	}
-	
+
+	initIMFloater();
+
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
 
 	//need to send delayed messaged collected while waiting for session initialization
@@ -965,7 +1006,8 @@ BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
 BOOL LLIMFloater::isInviteAllowed() const
 {
 	return ((IM_SESSION_CONFERENCE_START == mDialog)
-			|| (IM_SESSION_INVITE == mDialog));
+			 || (IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
+			 || mIsP2PChat);
 }
 
 class LLSessionInviteResponder: public LLHTTPClient::Responder
@@ -1107,14 +1149,6 @@ void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD&
 }
 
 // static
-void LLIMFloater::initIMFloater()
-{
-	// This is called on viewer start up
-	// init chat window type before user changed it in preferences
-	isChatMultiTab();
-}
-
-//static
 void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
 {
 	LLUUID session_id = data["session_id"];
@@ -1139,7 +1173,6 @@ void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
 {
 	LLIMFloater::addToHost(session_id);
 }
-
 void LLIMFloater::addToHost(const LLUUID& session_id)
 {
 	if (LLIMConversation::isChatMultiTab())
@@ -1157,32 +1190,3 @@ void LLIMFloater::addToHost(const LLUUID& session_id)
 		}
 	}
 }
-
-void	LLIMFloater::onClickCloseBtn()
-{
-
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-			mSessionID);
-
-	if (session == NULL)
-	{
-		llwarns << "Empty session." << llendl;
-		return;
-	}
-
-	bool is_call_with_chat = session->isGroupSessionType()
-			|| session->isAdHocSessionType() || session->isP2PSessionType();
-
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-	if (is_call_with_chat && voice_channel != NULL
-			&& voice_channel->isActive())
-	{
-		LLSD payload;
-		payload["session_id"] = mSessionID;
-		LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
-		return;
-	}
-
-	LLFloater::onClickCloseBtn();
-}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 24f28c8aee..b97d4ab90c 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -56,6 +56,9 @@ public:
 
 	virtual ~LLIMFloater();
 
+	void initIMSession(const LLUUID& session_id);
+	void initIMFloater();
+
 	// LLView overrides
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void setVisible(BOOL visible);
@@ -117,14 +120,11 @@ public:
 			std::string& tooltip_msg);
 
 
-	static void initIMFloater();
-
 	//used as a callback on receiving new IM message
 	static void sRemoveTypingIndicator(const LLSD& data);
 	static void onIMChicletCreated(const LLUUID& session_id);
 
-protected:
-	/* virtual */ void onClickCloseBtn();
+	bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
 
 private:
 	// process focus events to set a currently active session
@@ -186,6 +186,8 @@ private:
 	bool mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
 
+	bool mStartConferenceInSameFloater;
+
 	// connection to voice channel state change signal
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
 };
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 46b1cb5f18..0d2b1f06b5 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2591,7 +2591,8 @@ LLUUID LLIMMgr::addSession(
 	const std::string& name,
 	EInstantMessage dialog,
 	const LLUUID& other_participant_id,
-	const LLDynamicArray<LLUUID>& ids, bool voice)
+	const LLDynamicArray<LLUUID>& ids, bool voice,
+	const LLUUID& floater_id)
 {
 	if (0 == ids.getLength())
 	{
@@ -2606,6 +2607,18 @@ LLUUID LLIMMgr::addSession(
 
 	LLUUID session_id = computeSessionID(dialog,other_participant_id);
 
+	if (floater_id.notNull())
+	{
+		LLIMFloater* im_floater = LLIMFloater::findInstance(floater_id);
+		if (im_floater && im_floater->getStartConferenceInSameFloater())
+		{
+			// The IM floater should be initialized with a new session_id
+			// so that it is found by that id when creating a chiclet in LLIMFloater::onIMChicletCreated,
+			// and a new floater is not created.
+			im_floater->initIMSession(session_id);
+		}
+	}
+
 	bool new_session = !LLIMModel::getInstance()->findIMSession(session_id);
 
 	//works only for outgoing ad-hoc sessions
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 9d19af4b62..58a2ac5162 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -347,10 +347,12 @@ public:
 
 	// Adds a session using a specific group of starting agents
 	// the dialog type is assumed correct. Returns the uuid of the session.
+	// A session can be added to a floater specified by floater_id.
 	LLUUID addSession(const std::string& name,
 					  EInstantMessage dialog,
 					  const LLUUID& other_participant_id,
-					  const LLDynamicArray<LLUUID>& ids, bool voice = false);
+					  const LLDynamicArray<LLUUID>& ids, bool voice = false,
+					  const LLUUID& floater_id = LLUUID::null);
 
 	/**
 	 * Creates a P2P session with the requisite handle for responding to voice calls.
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 8b54c6ce53..e35dbf21d4 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -130,6 +130,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key)
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
 {
+	mIsNearbyChat = true;
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
 }
 
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index c84790d839..ac2109dda4 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -81,7 +81,7 @@ LLContextMenu* NearbyMenu::createMenu()
 		// Set up for multi-selected People
 
 		// registrar.add("Avatar.AddFriend",	boost::bind(&LLAvatarActions::requestFriendshipDialog,	mUUIDs)); // *TODO: unimplemented
-		registrar.add("Avatar.IM",			boost::bind(&LLAvatarActions::startConference,			mUUIDs));
+		registrar.add("Avatar.IM",			boost::bind(&LLAvatarActions::startConference,			mUUIDs, LLUUID::null));
 		registrar.add("Avatar.Call",		boost::bind(&LLAvatarActions::startAdhocCall,			mUUIDs));
 		registrar.add("Avatar.OfferTeleport",	boost::bind(&NearbyMenu::offerTeleport,					this));
 		registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog,		mUUIDs));
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 2f13ba5ab1..320a602916 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2153,7 +2153,6 @@ bool idle_startup()
 
 		LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
 
-		LLIMFloater::initIMFloater();
 		display_startup();
 
 		return TRUE;
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index beeb4eea9b..fc5b6b10af 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -69,8 +69,7 @@
                  top="5"
                  left_pad="4"
                  name="add_btn"
-                 width="31">
-             </button>   
+                 width="31"/>
              <button
                  follows="top|left"
                  height="25"
@@ -82,8 +81,7 @@
                  top="5"
                  left_pad="4"
                  name="voice_call_btn"
-                 width="31">
-             </button>
+                 width="31"/>
              <button
                  follows="right|top"
                  height="25"
-- 
cgit v1.2.3


From 85e553638e51994824683497bd9ccc964c7cc1fc Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 6 Jun 2012 19:37:59 -0700
Subject: CHUI-137 : Implement temporary conversations list (not working yet)

---
 indra/newview/llfolderviewitem.cpp     |  2 +-
 indra/newview/llimfloatercontainer.cpp | 79 +++++++++++++++++++++++++++++++++
 indra/newview/llimfloatercontainer.h   | 81 ++++++++++++++++++++++++++++++++++
 3 files changed, 161 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 43d3675d17..126de95551 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -287,7 +287,7 @@ void LLFolderViewItem::refreshFromListener()
 			setCreationDate(creation_date);
 			dirtyFilter();
 		}
-		if (mRoot->useLabelSuffix())
+		if (mRoot && mRoot->useLabelSuffix())
 		{
 			mLabelStyle = mListener->getLabelStyle();
 			mLabelSuffix = mListener->getLabelSuffix();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 3b6240de44..134d345148 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -71,6 +71,8 @@ BOOL LLIMFloaterContainer::postBuild()
 	mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
 	mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel");
 	mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel");
+	
+	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
@@ -112,6 +114,22 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
+	// CHUI-137
+	llinfos << "Merov debug : addFloater, title = " << floaterp->getTitle() << llendl;
+	// Create a conversation item
+	LLConversationItem item(floaterp->getTitle());
+	// Add it to the list
+	mConversationsItems.push_back(item);
+	// Create a widget from it
+	LLFolderViewItem* widget = createConversationItemWidget(&item);
+	// Add it to the list of widgets
+	mConversationsWidgets.push_back(widget);
+	// Add it to the UI
+	widget->setVisible(TRUE);
+	mConversationsListPanel->addChild(widget);
+	// Reposition it...
+	// CHUI-137 : end
+	
 	LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
 
 	// we don't show the header when the floater is hosted,
@@ -150,6 +168,8 @@ void LLIMFloaterContainer::removeFloater(LLFloater* floaterp)
 {
 	LLMultiFloater::removeFloater(floaterp);
 
+	llinfos << "Merov debug : removeFloater, title = " << floaterp->getTitle() << llendl;
+
 	LLRect contents_rect = floaterp->getRect();
 
 	// reduce the floater contents height by header height
@@ -313,4 +333,63 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
 }
 
+// CHUI-137 : Temp implementation of conversations list
+LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
+{
+	LLFolderViewItem::Params params;
+	
+	params.name = item->getDisplayName();
+	//params.icon = bridge->getIcon();
+	//params.icon_open = bridge->getOpenIcon();
+		
+	//params.creation_date = bridge->getCreationDate();
+	//params.root = mFolderRoot;
+	params.listener = item;
+	params.rect = LLRect (0, 0, 0, 0);
+	params.tool_tip = params.name;
+	
+	return LLUICtrlFactory::create<LLFolderViewItem>(params);
+}
+
+// Conversation items
+LLConversationItem::LLConversationItem(std::string name) :
+	mName(name),
+	mUUID(LLUUID::null)
+{
+	if (name == "")
+		mName = "Nearby Chat";
+}
+
+// Virtual action callbacks
+void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
+{
+	llinfos << "Merov debug : performAction, title = " << mName << ", action = " << action << llendl;
+}
+
+void LLConversationItem::openItem( void )
+{
+	llinfos << "Merov debug : openItem, title = " << mName << llendl;
+}
+
+void LLConversationItem::closeItem( void )
+{
+	llinfos << "Merov debug : closeItem, title = " << mName << llendl;
+}
+
+void LLConversationItem::previewItem( void )
+{
+	llinfos << "Merov debug : previewItem, title = " << mName << llendl;
+}
+
+void LLConversationItem::selectItem(void)
+{
+	llinfos << "Merov debug : selectItem, title = " << mName << llendl;
+}
+
+void LLConversationItem::showProperties(void)
+{
+	llinfos << "Merov debug : showProperties, title = " << mName << llendl;
+}
+
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 92938ff405..5cfdb41ad3 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -35,11 +35,85 @@
 #include "llavatarpropertiesprocessor.h"
 #include "llgroupmgr.h"
 
+#include "llfolderviewitem.h"
+#include "llfoldervieweventlistener.h"
+
 class LLButton;
 class LLLayoutPanel;
 class LLLayoutStack;
 class LLTabContainer;
 
+// CHUI-137 : Temporary implementation of conversations list
+class LLConversationItem;
+
+typedef std::list<LLConversationItem> conversations_items_list_t;
+typedef std::list<LLFolderViewItem*> conversations_widgets_list_t;
+
+// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each that we tuck 
+// into the mConversationsListPanel. 
+class LLConversationItem : public LLFolderViewEventListener
+{
+public:
+	LLConversationItem(std::string name);
+	virtual ~LLConversationItem() {}
+
+	// Stub those things we won't really be using in this conversation context
+	virtual const std::string& getName() const { return mName; }
+	virtual const std::string& getDisplayName() const { return mName; }
+	virtual const LLUUID& getUUID() const { return mUUID; }
+	virtual time_t getCreationDate() const { return 0; }
+	virtual PermissionMask getPermissionMask() const { return PERM_ALL; }
+	virtual LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
+	virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
+	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
+	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
+	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
+	virtual BOOL isItemRenameable() const { return FALSE; }
+	virtual BOOL renameItem(const std::string& new_name) { return FALSE; }
+	virtual BOOL isItemMovable( void ) const { return FALSE; }
+	virtual BOOL isItemRemovable( void ) const { return FALSE; }
+	virtual BOOL isItemInTrash( void) const { return FALSE; }
+	virtual BOOL removeItem() { return FALSE; }
+	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) { }
+	virtual void move( LLFolderViewEventListener* parent_listener ) { }
+	virtual BOOL isItemCopyable() const { return FALSE; }
+	virtual BOOL copyToClipboard() const { return FALSE; }
+	virtual void cutToClipboard() { }
+	virtual BOOL isClipboardPasteable() const { return FALSE; }
+	virtual void pasteFromClipboard() { }
+	virtual void pasteLinkFromClipboard() { }
+	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
+	virtual BOOL isUpToDate() const { return TRUE; }
+	virtual BOOL hasChildren() const { return FALSE; }
+	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
+	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+
+	// The action callbacks (or so we think...)
+	virtual void performAction(LLInventoryModel* model, std::string action);
+	virtual void openItem( void );
+	virtual void closeItem( void );
+	virtual void previewItem( void );
+	virtual void selectItem(void);
+	virtual void showProperties(void);
+	
+	// This method should be called when a drag begins. returns TRUE
+	// if the drag can begin, otherwise FALSE.
+	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const { return FALSE; }
+	
+	// This method will be called to determine if a drop can be
+	// performed, and will set drop to TRUE if a drop is
+	// requested. Returns TRUE if a drop is possible/happened,
+	// otherwise FALSE.
+	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+							EDragAndDropType cargo_type,
+							void* cargo_data,
+							std::string& tooltip_msg) { return FALSE; }
+private:
+	std::string mName;
+	LLUUID mUUID;
+};
+	// CHUI-137 : End
+
 class LLIMFloaterContainer : public LLMultiFloater
 {
 public:
@@ -64,6 +138,8 @@ public:
 	virtual void setMinimized(BOOL b);
 
 	void collapseMessagesPane(bool collapse);
+	
+	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
@@ -84,6 +160,11 @@ private:
 	LLLayoutPanel* mMessagesPane;
 	LLLayoutPanel* mConversationsPane;
 	LLLayoutStack* mConversationsStack;
+	
+	// CHUI-137 : Data
+	LLPanel* mConversationsListPanel;	// The widget we add list item to (title of each conversation)
+	conversations_items_list_t mConversationsItems;
+	conversations_widgets_list_t mConversationsWidgets;
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H
-- 
cgit v1.2.3


From 8353a1ab4d9dab891535b766329c5d92323fe3b6 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 8 Jun 2012 01:08:56 +0300
Subject: CHUI-120 WIP Added avatar picker that allows to add other users to an
 existing chat if they don't participate in it already.

---
 indra/newview/llimfloater.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++
 indra/newview/llimfloater.h   |  4 +++
 2 files changed, 73 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index f04fecca26..f49375798d 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -33,12 +33,14 @@
 
 #include "llagent.h"
 #include "llappviewer.h"
+#include "llavataractions.h"
 #include "llavatarnamecache.h"
 #include "llbutton.h"
 #include "llchannelmanager.h"
 #include "llchiclet.h"
 #include "llchicletbar.h"
 #include "llfloaterreg.h"
+#include "llfloateravatarpicker.h"
 #include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
 #include "llinventoryfunctions.h"
 //#include "lllayoutstack.h"
@@ -309,6 +311,7 @@ BOOL LLIMFloater::postBuild()
 
 	mTypingStart = LLTrans::getString("IM_typing_start_string");
 
+	childSetAction("add_btn", boost::bind(&LLIMFloater::onAddButtonClicked, this));
 	childSetAction("voice_call_btn", boost::bind(&LLIMFloater::onCallButtonClicked, this));
 
 	LLVoiceClient::getInstance()->addObserver(this);
@@ -321,6 +324,72 @@ BOOL LLIMFloater::postBuild()
 	return TRUE;
 }
 
+void LLIMFloater::onAddButtonClicked()
+{
+       LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::onAvatarPicked, this, _1, _2), TRUE, TRUE);
+       if (!picker)
+       {
+               return;
+       }
+
+       // Need to disable 'ok' button when selected users are already in conversation.
+       picker->setOkBtnEnableCb(boost::bind(&LLIMFloater::canAddSelectedToChat, this, _1));
+       LLFloater* root_floater = gFloaterView->getParentFloater(this);
+       if (root_floater)
+       {
+               root_floater->addDependentFloater(picker);
+       }
+}
+
+void LLIMFloater::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
+{
+       if (mIsP2PChat)
+       {
+               mStartConferenceInSameFloater = true;
+               onClose(false);
+
+               uuid_vec_t temp_ids;
+               temp_ids.push_back(mOtherParticipantUUID);
+               temp_ids.insert(temp_ids.end(), ids.begin(), ids.end());
+
+               LLAvatarActions::startConference(temp_ids, mSessionID);
+       }
+       else
+       {
+               inviteToSession(ids);
+       }
+}
+
+bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
+{
+       if (!mSession
+               || mDialog == IM_SESSION_GROUP_START
+               || mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID))
+       {
+               return false;
+       }
+
+       for (uuid_vec_t::const_iterator id = uuids.begin();
+                       id != uuids.end(); ++id)
+       {
+               if (*id == mOtherParticipantUUID)
+               {
+                       return false;
+               }
+
+               for (uuid_vec_t::const_iterator target_id = mSession->mInitialTargetIDs.begin();
+                               target_id != mSession->mInitialTargetIDs.end(); ++target_id)
+               {
+                       if (*id == *target_id)
+                       {
+                               return false;
+                       }
+               }
+       }
+
+       return true;
+}
+
 void LLIMFloater::boundVoiceChannel()
 {
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index b97d4ab90c..b5822db8dd 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -147,6 +147,10 @@ private:
 	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
 	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
 	void setTyping(bool typing);
+	void onAddButtonClicked();
+	void onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
+	bool canAddSelectedToChat(const uuid_vec_t& uuids);
+
 	void onCallButtonClicked();
 
 	// set the enable/disable state for the Call button
-- 
cgit v1.2.3


From 9b92235291382deac15b860efa281f625d2173dd Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 8 Jun 2012 01:08:58 +0300
Subject: CHUI-120 WIP Added conversations participants drag and drop from
 avatar lists to IM floaters. - Added new drag and drop type DAD_PERSON and
 source SOURCE_PEOPLE to avoid highliting the toolbars when using
 SOURCE_VIEWER. - Disabled calling card drop support as it is considered
 obsolete.

---
 indra/llcommon/llassettype.cpp        |  1 +
 indra/llcommon/llassettype.h          |  3 ++
 indra/llcommon/stdenums.h             |  3 +-
 indra/llinventory/llinventorytype.cpp |  3 +-
 indra/llinventory/llinventorytype.h   |  3 +-
 indra/newview/llavatarlistitem.cpp    | 58 +++++++++++++++++++++
 indra/newview/llavatarlistitem.h      |  3 ++
 indra/newview/llimconversation.cpp    | 12 ++---
 indra/newview/llimfloater.cpp         | 97 +++++++++++------------------------
 indra/newview/llimfloater.h           | 12 ++---
 indra/newview/lltoolbarview.cpp       |  2 +-
 indra/newview/lltooldraganddrop.cpp   |  2 +-
 indra/newview/lltooldraganddrop.h     |  3 +-
 indra/newview/llviewerassettype.cpp   |  2 +
 14 files changed, 120 insertions(+), 84 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 5e566d6c7c..5ae2df3994 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -95,6 +95,7 @@ LLAssetDictionary::LLAssetDictionary()
 	addEntry(LLAssetType::AT_LINK_FOLDER, 		new AssetEntry("FOLDER_LINK",		"link_f", 	"sym folder link",	false,		false,		true));
 	addEntry(LLAssetType::AT_MESH,              new AssetEntry("MESH",              "mesh",     "mesh",             false,      false,      false));
 	addEntry(LLAssetType::AT_WIDGET,            new AssetEntry("WIDGET",            "widget",   "widget",           false,      false,      false));
+	addEntry(LLAssetType::AT_PERSON,            new AssetEntry("PERSON",            "person",   "person",           false,      false,      false));
 	addEntry(LLAssetType::AT_NONE, 				new AssetEntry("NONE",				"-1",		NULL,		  		FALSE,		FALSE,		FALSE));
 
 };
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index d538accbf7..69b01731e5 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -112,6 +112,9 @@ public:
 		AT_WIDGET = 40,
 			// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
 		
+		AT_PERSON = 45,
+			// A user uuid  which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
+
 		AT_MESH = 49,
 			// Mesh data in our proprietary SLM format
 		
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 40b3364b36..efcbe76795 100644
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -51,7 +51,8 @@ enum EDragAndDropType
 	DAD_LINK			= 14,
 	DAD_MESH            = 15,
 	DAD_WIDGET          = 16,
-	DAD_COUNT           = 17,   // number of types in this enum
+	DAD_PERSON          = 17,
+	DAD_COUNT           = 18,   // number of types in this enum
 };
 
 // Reasons for drags to be denied.
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 8282d79b67..8807b36117 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
 	addEntry(LLInventoryType::IT_GESTURE,             new InventoryEntry("gesture",   "gesture",       1, LLAssetType::AT_GESTURE)); 
 	addEntry(LLInventoryType::IT_MESH,                new InventoryEntry("mesh",      "mesh",          1, LLAssetType::AT_MESH));
 	addEntry(LLInventoryType::IT_WIDGET,              new InventoryEntry("widget",    "widget",        1, LLAssetType::AT_WIDGET));
+	addEntry(LLInventoryType::IT_PERSON,              new InventoryEntry("person",    "person",        1, LLAssetType::AT_PERSON));
 }
 
 
@@ -140,7 +141,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
 	LLInventoryType::IT_NONE,			// 42	AT_NONE
 	LLInventoryType::IT_NONE,			// 43	AT_NONE
 	LLInventoryType::IT_NONE,			// 44	AT_NONE
-	LLInventoryType::IT_NONE,			// 45	AT_NONE
+	LLInventoryType::IT_PERSON,			// 45	AT_PERSON
 	LLInventoryType::IT_NONE,			// 46	AT_NONE
 	LLInventoryType::IT_NONE,			// 47	AT_NONE
 	LLInventoryType::IT_NONE,			// 48	AT_NONE
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 4d1e0db040..645ebab234 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -63,7 +63,8 @@ public:
 		IT_GESTURE = 20,
 		IT_MESH = 22,
 		IT_WIDGET = 23,
-		IT_COUNT = 24,
+		IT_PERSON = 24,
+		IT_COUNT = 25,
 
 		IT_NONE = -1
 	};
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 30eecfe323..e670d3ea04 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -31,6 +31,7 @@
 #include "llavatarlistitem.h"
 
 #include "llbutton.h"
+#include "llclipboard.h"
 #include "llfloaterreg.h"
 #include "lltextutil.h"
 
@@ -38,6 +39,7 @@
 #include "llavatarnamecache.h"
 #include "llavatariconctrl.h"
 #include "lloutputmonitorctrl.h"
+#include "lltooldraganddrop.h"
 
 bool LLAvatarListItem::sStaticInitialized = false;
 S32 LLAvatarListItem::sLeftPadding = 0;
@@ -334,6 +336,62 @@ BOOL LLAvatarListItem::handleDoubleClick(S32 x, S32 y, MASK mask)
 	return LLPanel::handleDoubleClick(x, y, mask);
 }
 
+BOOL LLAvatarListItem::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	if (LLUICtrl::handleMouseDown(x, y, mask))
+	{
+		return TRUE;
+	}
+
+	gFocusMgr.setMouseCapture(this);
+
+	S32 screen_x;
+	S32 screen_y;
+	localPointToScreen(x, y, &screen_x, &screen_y);
+	LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y);
+
+	return TRUE;
+}
+
+BOOL LLAvatarListItem::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+	if (LLUICtrl::childrenHandleMouseUp(x, y, mask))
+	{
+		return TRUE;
+	}
+
+	if(hasMouseCapture())
+	{
+		gFocusMgr.setMouseCapture(NULL);
+	}
+	return TRUE;
+}
+
+BOOL LLAvatarListItem::handleHover(S32 x, S32 y, MASK mask)
+{
+	bool handled = hasMouseCapture();
+	if(handled)
+	{
+		S32 screen_x;
+		S32 screen_y;
+		localPointToScreen(x, y, &screen_x, &screen_y);
+
+		if(LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y))
+		{
+			// First, create the global drag and drop object
+			std::vector<EDragAndDropType> types;
+			uuid_vec_t cargo_ids;
+			types.push_back(DAD_PERSON);
+			cargo_ids.push_back(mAvatarId);
+			gClipboard.setSourceObject(mAvatarId, LLAssetType::AT_PERSON);
+			LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE;
+			LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src);
+		}
+	}
+
+	return handled;
+}
+
 void LLAvatarListItem::setValue( const LLSD& value )
 {
 	if (!value.isMap()) return;;
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index c95ac39696..28a50870d4 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -112,6 +112,9 @@ public:
 	void onProfileBtnClick();
 
 	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 
 protected:
 	/**
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index d8c7c63e9e..ec2a9196d4 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -83,8 +83,10 @@ BOOL LLIMConversation::postBuild()
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this));
 
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
-	mParticipantListPanel->setVisible(
-			mIsNearbyChat? false : gSavedSettings.getBOOL("IMShowControlPanel"));
+
+	// Show the participants list in torn off floaters only.
+	mParticipantListPanel->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")
+									  && !mIsNearbyChat); // *TODO: temporarily disabled for Nearby chat
 	mExpandCollapseBtn->setImageOverlay(
 				getString(mParticipantListPanel->getVisible() ? "collapse_icon" : "expand_icon"));
 	mExpandCollapseBtn->setEnabled(!mIsP2PChat);
@@ -209,12 +211,10 @@ void LLIMConversation::updateHeaderAndToolbar()
 	}
 
 	bool is_control_panel_visible = false;
-	if (!mIsP2PChat)
-	{
 		// Control panel should be visible only in torn off floaters.
 		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
-		mParticipantListPanel->setVisible(is_control_panel_visible);
-	}
+		mParticipantListPanel->setVisible(!mIsP2PChat && is_control_panel_visible
+				&& !mIsNearbyChat); // *TODO: temporarily disabled for Nearby chat
 
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index f49375798d..6a510c4df1 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -986,90 +986,55 @@ void LLIMFloater::processSessionUpdate(const LLSD& session_update)
 	}
 }
 
-BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
-		BOOL drop, EDragAndDropType cargo_type,
-		void *cargo_data, EAcceptance *accept,
-		std::string& tooltip_msg)
+// virtual
+BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+									std::string& tooltip_msg)
 {
-	if (mDialog == IM_NOTHING_SPECIAL)
-	{
-		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
-				cargo_type, cargo_data, accept);
-	}
-
-	// handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites
-	else if (isInviteAllowed())
+	if (cargo_type == DAD_PERSON)
 	{
-		*accept = ACCEPT_NO;
-
-		if (cargo_type == DAD_CALLINGCARD)
+		if (dropPerson(static_cast<LLInventoryObject*>(cargo_data), drop))
 		{
-			if (dropCallingCard((LLInventoryItem*) cargo_data, drop))
-			{
-				*accept = ACCEPT_YES_MULTI;
-			}
+			*accept = ACCEPT_YES_MULTI;
 		}
-		else if (cargo_type == DAD_CATEGORY)
+		else
 		{
-			if (dropCategory((LLInventoryCategory*) cargo_data, drop))
-			{
-				*accept = ACCEPT_YES_MULTI;
-			}
+			*accept = ACCEPT_NO;
 		}
 	}
 	return TRUE;
 }
 
-BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
+bool LLIMFloater::dropPerson(LLInventoryObject* item, bool drop)
 {
-	BOOL rv = isInviteAllowed();
-	if (rv && item && item->getCreatorUUID().notNull())
+	bool res = item && item->getUUID().notNull();
+	if(res)
 	{
-		if (drop)
-		{
-			uuid_vec_t ids;
-			ids.push_back(item->getCreatorUUID());
-			inviteToSession(ids);
-		}
-	}
-	else
-	{
-		// set to false if creator uuid is null.
-		rv = FALSE;
-	}
-	return rv;
-}
+		uuid_vec_t ids;
+		ids.push_back(item->getUUID());
 
-BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
-{
-	BOOL rv = isInviteAllowed();
-	if (rv && category)
-	{
-		LLInventoryModel::cat_array_t cats;
-		LLInventoryModel::item_array_t items;
-		LLUniqueBuddyCollector buddies;
-		gInventory.collectDescendentsIf(category->getUUID(),
-				cats,
-				items,
-				LLInventoryModel::EXCLUDE_TRASH,
-				buddies);
-		S32 count = items.count();
-		if (count == 0)
-		{
-			rv = FALSE;
-		}
-		else if (drop)
+		res = canAddSelectedToChat(ids);
+		if(res && drop)
 		{
-			uuid_vec_t ids;
-			ids.reserve(count);
-			for (S32 i = 0; i < count; ++i)
+			if (mIsP2PChat)
 			{
-				ids.push_back(items.get(i)->getCreatorUUID());
+				mStartConferenceInSameFloater = true;
+				onClose(false);
+
+				ids.push_back(mOtherParticipantUUID);
+
+				LLAvatarActions::startConference(ids, mSessionID);
+			}
+			else
+			{
+				inviteToSession(ids);
 			}
-			inviteToSession(ids);
 		}
 	}
-	return rv;
+
+	return res;
 }
 
 BOOL LLIMFloater::isInviteAllowed() const
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index b5822db8dd..b02f779637 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -114,10 +114,11 @@ public:
 	void processAgentListUpdates(const LLSD& body);
 	void processSessionUpdate(const LLSD& session_update);
 
-	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
-			BOOL drop, EDragAndDropType cargo_type,
-			void *cargo_data, EAcceptance *accept,
-			std::string& tooltip_msg);
+	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+									   EDragAndDropType cargo_type,
+									   void* cargo_data,
+									   EAcceptance* accept,
+									   std::string& tooltip_msg);
 
 
 	//used as a callback on receiving new IM message
@@ -137,8 +138,7 @@ private:
 	// For display name lookups for IM window titles
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
 
-	BOOL dropCallingCard(LLInventoryItem* item, BOOL drop);
-	BOOL dropCategory(LLInventoryCategory* category, BOOL drop);
+	bool dropPerson(LLInventoryObject* item, bool drop);
 
 	BOOL isInviteAllowed() const;
 	BOOL inviteToSession(const uuid_vec_t& agent_ids);
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index eccb2cf2f1..e71cf66a96 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -603,7 +603,7 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
 BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar)
 {
 	BOOL handled = FALSE;
-	LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
+	LLInventoryObject* inv_item = static_cast<LLInventoryObject*>(cargo_data);
 	
 	LLAssetType::EType type = inv_item->getType();
 	if (type == LLAssetType::AT_WIDGET)
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index c7ab934f9e..ee79a53f43 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -2526,7 +2526,7 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
 			item = (LLViewerInventoryItem*)preview->getDragItem();
 		}
 	}
-	else if(mSource == SOURCE_VIEWER)
+	else if(mSource == SOURCE_VIEWER || mSource == SOURCE_PEOPLE)
 	{
 		item = (LLViewerInventoryItem*)gClipboard.getSourceObject();
 	}
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 245c2a23e6..44980ffdb3 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -67,7 +67,8 @@ public:
 		SOURCE_WORLD,
 		SOURCE_NOTECARD,
 		SOURCE_LIBRARY,
-		SOURCE_VIEWER
+		SOURCE_VIEWER,
+		SOURCE_PEOPLE
 	};
 
 	void beginDrag(EDragAndDropType type,
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index a4b1c2155f..08ba5a5f25 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -83,6 +83,8 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
 	
 	addEntry(LLViewerAssetType::AT_WIDGET, 				new ViewerAssetEntry(DAD_WIDGET));
 	
+	addEntry(LLViewerAssetType::AT_PERSON, 				new ViewerAssetEntry(DAD_PERSON));
+
 	addEntry(LLViewerAssetType::AT_NONE, 				new ViewerAssetEntry(DAD_NONE));
 };
 
-- 
cgit v1.2.3


From f7f85dd0dda563a9fb49ed65b193a9ea98da9ba2 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 8 Jun 2012 01:09:00 +0300
Subject: CHUI-122 FIX Add button enabled only for P2P and ad hoc IM sessions.

---
 indra/newview/llimfloater.cpp                             | 7 ++++++-
 indra/newview/skins/default/xui/en/floater_im_session.xml | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 6a510c4df1..dcd19b5856 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -311,7 +311,12 @@ BOOL LLIMFloater::postBuild()
 
 	mTypingStart = LLTrans::getString("IM_typing_start_string");
 
-	childSetAction("add_btn", boost::bind(&LLIMFloater::onAddButtonClicked, this));
+	LLButton* add_btn = getChild<LLButton>("add_btn");
+
+	// Allow to add chat participants depending on the session type
+	add_btn->setEnabled(isInviteAllowed());
+	add_btn->setClickedCallback(boost::bind(&LLIMFloater::onAddButtonClicked, this));
+
 	childSetAction("voice_call_btn", boost::bind(&LLIMFloater::onCallButtonClicked, this));
 
 	LLVoiceClient::getInstance()->addObserver(this);
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index fc5b6b10af..21fc2d25d4 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -59,6 +59,7 @@
                  top="5"
                  width="31" />
              <button
+                 enabled="false"
                  follows="top|left"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-- 
cgit v1.2.3


From 33adfe09474c58075d58feff1fc34e24503d3e80 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 8 Jun 2012 19:51:56 +0300
Subject: CHUI-103 FIXED Added a square brackets to system messages; changed a
 default color for user messages

---
 indra/newview/llchathistory.cpp | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index cfc70a1b0e..dcd6d25888 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -737,7 +737,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	LLViewerChat::getChatColor(chat,txt_color);
 	LLFontGL* fontp = LLViewerChat::getChatFont();	
 	std::string font_name = LLFontGL::nameFromFont(fontp);
-	std::string font_size = LLFontGL::sizeFromFont(fontp);	
+	std::string font_size = LLFontGL::sizeFromFont(fontp);
+
 	LLStyle::Params style_params;
 	style_params.color(txt_color);
 	style_params.readonly_color(txt_color);
@@ -773,8 +774,9 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	// We graying out chat history by graying out messages that contains full date in a time string
 	if (message_from_log)
 	{
-		style_params.color(LLColor4::grey);
-		style_params.readonly_color(LLColor4::grey);
+		txt_color = LLColor4::grey;
+		style_params.color(txt_color);
+		style_params.readonly_color(txt_color);
 	}
 
 	bool prependNewLineState = mEditor->getText().size() != 0;
@@ -786,7 +788,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 
 		LLStyle::Params timestamp_style(style_params);
 
-		// timestams showing
+		// out of the timestamp
 		if (args["show_time"].asBoolean())
 		{
 		if (!message_from_log)
@@ -799,6 +801,13 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			prependNewLineState = false;
 		}
 
+        // out the opening square bracket (if need)
+		if (square_brackets)
+		{
+			mEditor->appendText("[", prependNewLineState, style_params);
+			prependNewLineState = false;
+		}
+
 		// names showing
 		if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0)
 		{
@@ -947,7 +956,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		
 		if (square_brackets)
 		{
-			message = "[" + message + "]";
+			message += "]";
 		}
 
 		mEditor->appendText(message, prependNewLineState, style_params);
-- 
cgit v1.2.3


From 3f7ecef1968b9087ba7c885a2dd6213120dfa547 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 8 Jun 2012 11:31:50 -0700
Subject: CHUI-137 : Fix crasher in item drawing

---
 indra/newview/llfolderviewitem.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 126de95551..73715c78df 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -864,8 +864,8 @@ void LLFolderViewItem::draw()
 	const S32 FOCUS_LEFT = 1;
 	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
-	const BOOL in_inventory = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID());
-	const BOOL in_library = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID());
+	const BOOL in_inventory = getListener() && getListener()->getUUID().notNull() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID());
+	const BOOL in_library = getListener() && getListener()->getUUID().notNull() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID());
 
 	//--------------------------------------------------------------------------------//
 	// Draw open folder arrow
-- 
cgit v1.2.3


From 18077965146922efb6541734bc3f7307efb4f586 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 8 Jun 2012 12:15:36 -0700
Subject: Fix post merge build issue: take clipboard changes into account

---
 indra/newview/llavatarlistitem.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index e670d3ea04..7ba63bc4a2 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -383,7 +383,6 @@ BOOL LLAvatarListItem::handleHover(S32 x, S32 y, MASK mask)
 			uuid_vec_t cargo_ids;
 			types.push_back(DAD_PERSON);
 			cargo_ids.push_back(mAvatarId);
-			gClipboard.setSourceObject(mAvatarId, LLAssetType::AT_PERSON);
 			LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE;
 			LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src);
 		}
-- 
cgit v1.2.3


From 1aba6c119ef05a4cfd91325c8455dc8c60098746 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 8 Jun 2012 17:26:13 -0700
Subject: CHUI-137 : Implement conversation list, temporary solution: add but
 doesn't take out items from the list

---
 indra/newview/llfolderviewitem.cpp     | 32 +++++++++++++++++++++-----------
 indra/newview/llimfloatercontainer.cpp | 15 +++++++++------
 indra/newview/llimfloatercontainer.h   |  4 ++--
 3 files changed, 32 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 73715c78df..0800e0baa2 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -377,7 +377,10 @@ void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
 											BOOL openitem,
 											BOOL take_keyboard_focus)
 {
-	getRoot()->setSelection(selection, openitem, take_keyboard_focus);
+	if (getRoot())
+	{
+		getRoot()->setSelection(selection, openitem, take_keyboard_focus);
+	}
 }
 
 // helper function to change the selection from the root.
@@ -754,7 +757,10 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 	}
 	else
 	{
-		getRoot()->setShowSelectionContext(FALSE);
+		if (getRoot())
+		{
+			getRoot()->setShowSelectionContext(FALSE);
+		}
 		gViewerWindow->setCursor(UI_CURSOR_ARROW);
 		// let parent handle this then...
 		return FALSE;
@@ -797,7 +803,10 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
 
 	if( hasMouseCapture() )
 	{
-		getRoot()->setShowSelectionContext(FALSE);
+		if (getRoot())
+		{
+			getRoot()->setShowSelectionContext(FALSE);
+		}
 		gFocusMgr.setMouseCapture( NULL );
 	}
 	return TRUE;
@@ -864,8 +873,9 @@ void LLFolderViewItem::draw()
 	const S32 FOCUS_LEFT = 1;
 	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
-	const BOOL in_inventory = getListener() && getListener()->getUUID().notNull() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID());
-	const BOOL in_library = getListener() && getListener()->getUUID().notNull() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID());
+	const LLUUID uuid = (getListener() ? getListener()->getUUID() : LLUUID::null);
+	const BOOL in_inventory = (uuid.notNull() ? gInventory.isObjectDescendentOf(uuid, gInventory.getRootFolderID()) : FALSE);
+	const BOOL in_library   = (uuid.notNull() ? gInventory.isObjectDescendentOf(uuid, gInventory.getLibraryRootFolderID()) : FALSE);
 
 	//--------------------------------------------------------------------------------//
 	// Draw open folder arrow
@@ -885,8 +895,8 @@ void LLFolderViewItem::draw()
 	//--------------------------------------------------------------------------------//
 	// Draw highlight for selected items
 	//
-	const BOOL show_context = getRoot()->getShowSelectionContext();
-	const BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); // If we have keyboard focus, draw selection filled
+	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+	const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
 	const S32 focus_top = getRect().getHeight();
 	const S32 focus_bottom = getRect().getHeight() - mItemHeight;
 	const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
@@ -897,8 +907,8 @@ void LLFolderViewItem::draw()
 		if (!mIsCurSelection)
 		{
 			// do time-based fade of extra objects
-			F32 fade_time = getRoot()->getSelectionFadeElapsedTime();
-			if (getRoot()->getShowSingleSelection())
+			F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
+			if (getRoot() && getRoot()->getShowSingleSelection())
 			{
 				// fading out
 				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
@@ -1009,7 +1019,7 @@ void LLFolderViewItem::draw()
 	//--------------------------------------------------------------------------------//
 	// Highlight filtered text
 	//
-	if (getRoot()->getDebugFilters())
+	if (getRoot() && getRoot()->getDebugFilters())
 	{
 		if (!getFiltered() && !possibly_has_children)
 		{
@@ -1070,7 +1080,7 @@ void LLFolderViewItem::draw()
 	if (mStringMatchOffset != std::string::npos)
 	{
 		// don't draw backgrounds for zero-length strings
-		S32 filter_string_length = getRoot()->getFilterSubString().size();
+		S32 filter_string_length = (getRoot() ? getRoot()->getFilterSubString().size() : 0);
 		if (filter_string_length > 0)
 		{
 			std::string combined_string = mLabel + mLabelSuffix;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 134d345148..cd19105860 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -115,19 +115,22 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
 	// CHUI-137
-	llinfos << "Merov debug : addFloater, title = " << floaterp->getTitle() << llendl;
 	// Create a conversation item
-	LLConversationItem item(floaterp->getTitle());
-	// Add it to the list
+	LLConversationItem* item = new LLConversationItem(floaterp->getTitle());
 	mConversationsItems.push_back(item);
 	// Create a widget from it
-	LLFolderViewItem* widget = createConversationItemWidget(&item);
-	// Add it to the list of widgets
+	LLFolderViewItem* widget = createConversationItemWidget(item);
 	mConversationsWidgets.push_back(widget);
 	// Add it to the UI
 	widget->setVisible(TRUE);
 	mConversationsListPanel->addChild(widget);
-	// Reposition it...
+	LLRect panel_rect = mConversationsListPanel->getRect();
+	S32 item_height = 16;
+	S32 index = mConversationsWidgets.size() - 1;
+	widget->setRect(LLRect(0,
+						   panel_rect.getHeight() - item_height*index,
+						   panel_rect.getWidth(),
+						   panel_rect.getHeight() - item_height*(index+1)));
 	// CHUI-137 : end
 	
 	LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 5cfdb41ad3..d04ac873fa 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -46,7 +46,7 @@ class LLTabContainer;
 // CHUI-137 : Temporary implementation of conversations list
 class LLConversationItem;
 
-typedef std::list<LLConversationItem> conversations_items_list_t;
+typedef std::list<LLConversationItem*> conversations_items_list_t;
 typedef std::list<LLFolderViewItem*> conversations_widgets_list_t;
 
 // Conversation items: we hold a list of those and create an LLFolderViewItem widget for each that we tuck 
@@ -110,7 +110,7 @@ public:
 							std::string& tooltip_msg) { return FALSE; }
 private:
 	std::string mName;
-	LLUUID mUUID;
+	const LLUUID mUUID;
 };
 	// CHUI-137 : End
 
-- 
cgit v1.2.3


From e286330365576e67fa9b59166f6019e89f09f3cf Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 8 Jun 2012 17:58:15 -0700
Subject: CHUI-137 : Fix build error after merge

---
 indra/newview/llimfloatercontainer.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index d04ac873fa..84b1c864cc 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -78,7 +78,7 @@ public:
 	virtual void move( LLFolderViewEventListener* parent_listener ) { }
 	virtual BOOL isItemCopyable() const { return FALSE; }
 	virtual BOOL copyToClipboard() const { return FALSE; }
-	virtual void cutToClipboard() { }
+	virtual BOOL cutToClipboard() const { return FALSE; }
 	virtual BOOL isClipboardPasteable() const { return FALSE; }
 	virtual void pasteFromClipboard() { }
 	virtual void pasteLinkFromClipboard() { }
-- 
cgit v1.2.3


From ec726c3a3ecbefd34008cd735f455c7947b67246 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 11 Jun 2012 17:04:58 +0300
Subject: CHUI-119 WIP Fixed some bugs

---
 indra/newview/llstartup.cpp                               | 6 +++++-
 indra/newview/skins/default/xui/en/floater_im_session.xml | 7 +++----
 2 files changed, 8 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 320a602916..65fd6d7019 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -63,7 +63,7 @@
 #include "llmemorystream.h"
 #include "llmessageconfig.h"
 #include "llmoveview.h"
-#include "llnearbychat.h"
+#include "llimfloatercontainer.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llteleporthistory.h"
@@ -1376,6 +1376,10 @@ bool idle_startup()
 		LLVoiceClient::getInstance()->updateSettings();
 		display_startup();
 
+		// create a container's instance for start a controlling conversation windows
+		// by the voice's events
+		LLIMFloaterContainer::getInstance();
+
 		// *Note: this is where gWorldMap used to be initialized.
 
 		// register null callbacks for audio until the audio system is initialized
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 21fc2d25d4..e5e005e36f 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -236,10 +236,9 @@
             </layout_panel>
            </layout_stack>
            </panel>
-            <panel width="228" 
+            <panel width="225" 
              height="31" 
-             left="4"
-             right="4" 
+             left="4" 
              name="bottom_panel"
              bottom="-1" 
              follows="left|right|bottom" 
@@ -254,7 +253,7 @@
              		layout="bottomleft"
              		name="chat_editor"
              		tab_group="3"
-             		width="240">
+             		width="220">
             	</line_editor>
               </panel>
     </layout_panel>
-- 
cgit v1.2.3


From db67c21f901800d27c9dd2ea2ce6134dc3bd33f1 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 11 Jun 2012 17:25:17 -0700
Subject: CHUI-137 : Implemented switch conversation in the conversation list

---
 indra/newview/llfolderviewitem.cpp     |  4 ++++
 indra/newview/llimfloatercontainer.cpp | 20 +++++++++++++-------
 indra/newview/llimfloatercontainer.h   |  5 ++++-
 3 files changed, 21 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index d7d5195c14..8ae779326c 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -387,6 +387,10 @@ void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
 	{
 		getRoot()->setSelection(selection, openitem, take_keyboard_focus);
 	}
+    else if (mListener)
+    {
+        mListener->selectItem();
+    }
 }
 
 // helper function to change the selection from the root.
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index cd19105860..9c6cee6cb5 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -85,6 +85,7 @@ BOOL LLIMFloaterContainer::postBuild()
 
 void LLIMFloaterContainer::onOpen(const LLSD& key)
 {
+	llinfos << "Merov debug : onOpen, key = " << key.asUUID() << llendl;
 	LLMultiFloater::onOpen(key);
 /*
 	if (key.isDefined())
@@ -114,9 +115,11 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
+	LLUUID session_id = floaterp->getKey();
+
 	// CHUI-137
 	// Create a conversation item
-	LLConversationItem* item = new LLConversationItem(floaterp->getTitle());
+	LLConversationItem* item = new LLConversationItem(floaterp->getTitle(),session_id, floaterp, this);
 	mConversationsItems.push_back(item);
 	// Create a widget from it
 	LLFolderViewItem* widget = createConversationItemWidget(item);
@@ -139,8 +142,6 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 	// so reshape floater contents to occupy the header space
 	floater_contents->setShape(floaterp->getRect());
 
-	LLUUID session_id = floaterp->getKey();
-
 	LLIconCtrl* icon = 0;
 
 	if(gAgent.isInGroup(session_id, TRUE))
@@ -164,6 +165,8 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
 	}
 	mTabContainer->setTabImage(floaterp, icon);
+    
+	llinfos << "Merov debug : addFloater, title = " << floaterp->getTitle() << ", uuid = " << session_id << llendl;
 }
 
 // virtual
@@ -171,7 +174,7 @@ void LLIMFloaterContainer::removeFloater(LLFloater* floaterp)
 {
 	LLMultiFloater::removeFloater(floaterp);
 
-	llinfos << "Merov debug : removeFloater, title = " << floaterp->getTitle() << llendl;
+	llinfos << "Merov debug : removeFloater, title = " << floaterp->getTitle() << ", uuid = " << floaterp->getKey() << llendl;
 
 	LLRect contents_rect = floaterp->getRect();
 
@@ -355,9 +358,11 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
 }
 
 // Conversation items
-LLConversationItem::LLConversationItem(std::string name) :
+LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp) :
 	mName(name),
-	mUUID(LLUUID::null)
+	mUUID(uuid),
+    mFloater(floaterp),
+    mContainer(containerp)
 {
 	if (name == "")
 		mName = "Nearby Chat";
@@ -386,7 +391,8 @@ void LLConversationItem::previewItem( void )
 
 void LLConversationItem::selectItem(void)
 {
-	llinfos << "Merov debug : selectItem, title = " << mName << llendl;
+	llinfos << "Merov debug : selectItem, title = " << mName << ", uuid = " << mUUID << llendl;
+    mContainer->selectFloater(mFloater);
 }
 
 void LLConversationItem::showProperties(void)
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 84b1c864cc..afb65671ae 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -45,6 +45,7 @@ class LLTabContainer;
 
 // CHUI-137 : Temporary implementation of conversations list
 class LLConversationItem;
+class LLIMFloaterContainer;
 
 typedef std::list<LLConversationItem*> conversations_items_list_t;
 typedef std::list<LLFolderViewItem*> conversations_widgets_list_t;
@@ -54,7 +55,7 @@ typedef std::list<LLFolderViewItem*> conversations_widgets_list_t;
 class LLConversationItem : public LLFolderViewEventListener
 {
 public:
-	LLConversationItem(std::string name);
+	LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
 	virtual ~LLConversationItem() {}
 
 	// Stub those things we won't really be using in this conversation context
@@ -111,6 +112,8 @@ public:
 private:
 	std::string mName;
 	const LLUUID mUUID;
+    LLFloater* mFloater;
+    LLIMFloaterContainer* mContainer;
 };
 	// CHUI-137 : End
 
-- 
cgit v1.2.3


From 0e2f5c2ebad0a19e9c5e151a4ac3ae7321f2f296 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 11 Jun 2012 22:12:43 -0700
Subject: CHUI-137 : Implemented tear off and close of conversation in the list

---
 indra/newview/llimfloatercontainer.cpp | 56 ++++++++++++++++++++++------------
 indra/newview/llimfloatercontainer.h   |  8 ++---
 2 files changed, 41 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 9c6cee6cb5..9084c07cc7 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -85,7 +85,6 @@ BOOL LLIMFloaterContainer::postBuild()
 
 void LLIMFloaterContainer::onOpen(const LLSD& key)
 {
-	llinfos << "Merov debug : onOpen, key = " << key.asUUID() << llendl;
 	LLMultiFloater::onOpen(key);
 /*
 	if (key.isDefined())
@@ -120,10 +119,10 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 	// CHUI-137
 	// Create a conversation item
 	LLConversationItem* item = new LLConversationItem(floaterp->getTitle(),session_id, floaterp, this);
-	mConversationsItems.push_back(item);
+	mConversationsItems[session_id] = item;
 	// Create a widget from it
 	LLFolderViewItem* widget = createConversationItemWidget(item);
-	mConversationsWidgets.push_back(widget);
+	mConversationsWidgets[session_id] = widget;
 	// Add it to the UI
 	widget->setVisible(TRUE);
 	mConversationsListPanel->addChild(widget);
@@ -165,8 +164,6 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
 	}
 	mTabContainer->setTabImage(floaterp, icon);
-    
-	llinfos << "Merov debug : addFloater, title = " << floaterp->getTitle() << ", uuid = " << session_id << llendl;
 }
 
 // virtual
@@ -174,8 +171,34 @@ void LLIMFloaterContainer::removeFloater(LLFloater* floaterp)
 {
 	LLMultiFloater::removeFloater(floaterp);
 
-	llinfos << "Merov debug : removeFloater, title = " << floaterp->getTitle() << ", uuid = " << floaterp->getKey() << llendl;
-
+    // CHUI-137 : Clean up the conversations list
+ 	LLUUID session_id = floaterp->getKey();
+    // Delete the widget and the associated conversation item
+    // Note : since the mConversationsItems is a listener to the widget, deleting the widget also
+    // delete its listener
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(session_id);
+	if (widget_it != mConversationsWidgets.end())
+    {
+        LLFolderViewItem* widget = widget_it->second;
+        delete widget;
+    }
+    // Suppress the conversation items and widgets from their respective maps
+	mConversationsItems.erase(session_id);
+	mConversationsWidgets.erase(session_id);
+    // Reposition the leftover conversation items
+	LLRect panel_rect = mConversationsListPanel->getRect();
+	S32 item_height = 16;
+    int index = 0;
+    for (widget_it = mConversationsWidgets.begin(); widget_it != mConversationsWidgets.end(); ++widget_it, ++index)
+    {
+        LLFolderViewItem* widget = widget_it->second;
+        widget->setRect(LLRect(0,
+                               panel_rect.getHeight() - item_height*index,
+                               panel_rect.getWidth(),
+                               panel_rect.getHeight() - item_height*(index+1)));
+    }
+    // CHUI-137
+   
 	LLRect contents_rect = floaterp->getRect();
 
 	// reduce the floater contents height by header height
@@ -364,41 +387,36 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
     mFloater(floaterp),
     mContainer(containerp)
 {
+    // Hack: the nearby chat has no name so we catch that and impose one
 	if (name == "")
 		mName = "Nearby Chat";
 }
 
 // Virtual action callbacks
+void LLConversationItem::selectItem(void)
+{
+    // Select the conversation floater that is being selected
+    mContainer->selectFloater(mFloater);
+}
+
 void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
 {
-	llinfos << "Merov debug : performAction, title = " << mName << ", action = " << action << llendl;
 }
 
 void LLConversationItem::openItem( void )
 {
-	llinfos << "Merov debug : openItem, title = " << mName << llendl;
 }
 
 void LLConversationItem::closeItem( void )
 {
-	llinfos << "Merov debug : closeItem, title = " << mName << llendl;
 }
 
 void LLConversationItem::previewItem( void )
 {
-	llinfos << "Merov debug : previewItem, title = " << mName << llendl;
-}
-
-void LLConversationItem::selectItem(void)
-{
-	llinfos << "Merov debug : selectItem, title = " << mName << ", uuid = " << mUUID << llendl;
-    mContainer->selectFloater(mFloater);
 }
 
 void LLConversationItem::showProperties(void)
 {
-	llinfos << "Merov debug : showProperties, title = " << mName << llendl;
 }
 
-
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index afb65671ae..3df5a07df8 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -47,8 +47,8 @@ class LLTabContainer;
 class LLConversationItem;
 class LLIMFloaterContainer;
 
-typedef std::list<LLConversationItem*> conversations_items_list_t;
-typedef std::list<LLFolderViewItem*> conversations_widgets_list_t;
+typedef std::map<LLUUID, LLConversationItem*> conversations_items_map;
+typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
 
 // Conversation items: we hold a list of those and create an LLFolderViewItem widget for each that we tuck 
 // into the mConversationsListPanel. 
@@ -166,8 +166,8 @@ private:
 	
 	// CHUI-137 : Data
 	LLPanel* mConversationsListPanel;	// The widget we add list item to (title of each conversation)
-	conversations_items_list_t mConversationsItems;
-	conversations_widgets_list_t mConversationsWidgets;
+	conversations_items_map mConversationsItems;
+	conversations_widgets_map mConversationsWidgets;
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H
-- 
cgit v1.2.3


From 9993fa550ab3716e583a6d5699f27974c3a95eb9 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 12 Jun 2012 21:56:00 +0300
Subject: CHUI-119 WIP Suppressed of the warnings (XML corrected); fixed the
 torn-off button's states

---
 indra/newview/llimconversation.cpp                 | 40 +++++++++-------------
 indra/newview/llnearbychat.cpp                     | 14 ++++----
 .../skins/default/xui/en/floater_im_session.xml    |  9 +++--
 3 files changed, 28 insertions(+), 35 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index c2621938e1..99b28255cd 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -85,11 +85,11 @@ BOOL LLIMConversation::postBuild()
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
 
 	// Show the participants list in torn off floaters only.
-	mParticipantListPanel->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")
-									  && !mIsNearbyChat); // *TODO: temporarily disabled for Nearby chat
-	mExpandCollapseBtn->setImageOverlay(
-				getString(mParticipantListPanel->getVisible() ? "collapse_icon" : "expand_icon"));
-	mExpandCollapseBtn->setEnabled(!mIsP2PChat);
+//	mParticipantListPanel->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")
+//									  && !mIsNearbyChat); // *TODO: temporarily disabled for Nearby chat
+//	mExpandCollapseBtn->setImageOverlay(
+//				getString(mParticipantListPanel->getVisible() ? "collapse_icon" : "expand_icon"));
+//	mExpandCollapseBtn->setEnabled(!mIsP2PChat);
 
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
@@ -210,30 +210,22 @@ void LLIMConversation::updateHeaderAndToolbar()
 		}
 	}
 
-	bool is_control_panel_visible = false;
-		// Control panel should be visible only in torn off floaters.
-		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
-		mParticipantListPanel->setVisible(!mIsP2PChat && is_control_panel_visible
-				&& !mIsNearbyChat); // *TODO: temporarily disabled for Nearby chat
+	// Participant list should be visible only in torn off floaters.
+	bool is_participant_list_visible =
+			!is_hosted
+			&& gSavedSettings.getBOOL("IMShowControlPanel")
+			&& !mIsP2PChat
+			&& !mIsNearbyChat; // *TODO: temporarily disabled for Nearby chat
+
+	mParticipantListPanel->setVisible(is_participant_list_visible);
 
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
-	bool is_expanded = is_hosted || is_control_panel_visible;
+	bool is_expanded = is_hosted || is_participant_list_visible;
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
 
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
-	if (session)
-	{
-		// The button (>>) should be disabled for torn off P2P conversations.
-		mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType());
-	}
-	else
-	{
-		if (!mIsNearbyChat)
-		{
-			llwarns << "IM session not found." << llendl;
-		}
-	}
+	// The button (>>) should be disabled for torn off P2P conversations.
+	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat && !mIsNearbyChat);
 
 	if (mDragHandle)
 	{
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index e35dbf21d4..2f5a3a8767 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -126,7 +126,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key)
 :	LLIMConversation(key),
 	mChatBox(NULL),
 	mChatHistory(NULL),
-	mOutputMonitor(NULL),
+	//mOutputMonitor(NULL),
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
 {
@@ -152,8 +152,8 @@ BOOL LLNearbyChat::postBuild()
 	mChatBox->setEnableLineHistory(TRUE);
 	mChatBox->setFont(LLViewerChat::getChatFont());
 
-	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
-	mOutputMonitor->setVisible(FALSE);
+//	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
+//	mOutputMonitor->setVisible(FALSE);
 
 	// Register for font change notifications
 	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChat::onChatFontChange, this, _1));
@@ -184,6 +184,8 @@ BOOL LLNearbyChat::postBuild()
 		loadHistory();
 	}
 
+	setTitle(getString("NearbyChatTitle"));
+
 	return LLIMConversation::postBuild();
 }
 
@@ -718,12 +720,12 @@ void LLNearbyChat::displaySpeakingIndicator()
 
 	if (!id.isNull())
 	{
-		mOutputMonitor->setVisible(TRUE);
-		mOutputMonitor->setSpeakerId(id);
+		//mOutputMonitor->setVisible(TRUE);
+		//mOutputMonitor->setSpeakerId(id);
 	}
 	else
 	{
-		mOutputMonitor->setVisible(FALSE);
+		//mOutputMonitor->setVisible(FALSE);
 	}
 }
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index e5e005e36f..a4695b8c09 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -15,6 +15,9 @@
  can_tear_off="false"
  min_width="250"
  min_height="190">
+    <floater.string 
+     name="NearbyChatTitle"
+     value="Nearby Chat"/>
     <floater.string name="call_btn_start">VoicePTT_Off</floater.string>
     <floater.string name="call_btn_stop">VoicePTT_On</floater.string>
     <floater.string
@@ -131,9 +134,7 @@
   name="im_panels"
   tab_group="1"
   top_pad="0"
-  left="0"
-  auto_resize="true"
-  user_resize="true">
+  left="0">
     <layout_panel
       name="speakers_list_panel"
       follows="all"
@@ -185,8 +186,6 @@
           orientation="vertical"
           name="translate_and_chat_stack"
           tab_group="1"
-          auto_resize="true"
-          user_resize="true"
           left_pad="0"
           top="0"
           left="0">
-- 
cgit v1.2.3


From b50349ab8490c9b48e9cf89b8de186b528d90e60 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Wed, 13 Jun 2012 19:26:17 +0300
Subject: CHUI-120 WIP Fix for crash after closing the chat floater.

---
 indra/newview/llimconversation.cpp | 4 ++++
 indra/newview/llimfloater.cpp      | 4 ++++
 indra/newview/llnearbychat.cpp     | 4 ++++
 3 files changed, 12 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 99b28255cd..b45fc63825 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -114,6 +114,10 @@ BOOL LLIMConversation::postBuild()
 
 BOOL LLIMConversation::tick()
 {
+	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater
+	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy().
+	if (isDead()) return false;
+
 	// Need to resort the participant list if it's in sort by recent speaker order.
 	if (mParticipantList)
 	{
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index dcd19b5856..3458e740e7 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -487,6 +487,10 @@ void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
 // virtual
 BOOL LLIMFloater::tick()
 {
+	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater
+	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy().
+	if (isDead()) return false;
+
 	BOOL parents_retcode = LLIMConversation::tick();
 
 	if ( mMeTyping )
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 2f5a3a8767..cd181ce865 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -404,6 +404,10 @@ void LLNearbyChat::showTranslationCheckbox(BOOL show)
 
 BOOL LLNearbyChat::tick()
 {
+	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater
+	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy().
+	if (isDead()) return false;
+
 	BOOL parents_retcode = LLIMConversation::tick();
 
 	displaySpeakingIndicator();
-- 
cgit v1.2.3


From 569146f27c7350ca2245f1fa7bc4cb9c16a428ea Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Wed, 13 Jun 2012 21:21:19 +0300
Subject: CHUI-120 WIP Modified chat participants drag and drop not to use
 LLClipboard.

---
 indra/newview/llavatarlistitem.cpp  |  1 -
 indra/newview/llimfloater.cpp       |  8 +--
 indra/newview/llimfloater.h         |  2 +-
 indra/newview/lltooldraganddrop.cpp | 97 ++++++++++++++++++++++++++-----------
 4 files changed, 73 insertions(+), 35 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 7ba63bc4a2..7b5229b5e6 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -31,7 +31,6 @@
 #include "llavatarlistitem.h"
 
 #include "llbutton.h"
-#include "llclipboard.h"
 #include "llfloaterreg.h"
 #include "lltextutil.h"
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 3458e740e7..7c6de01c96 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -1004,7 +1004,7 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 {
 	if (cargo_type == DAD_PERSON)
 	{
-		if (dropPerson(static_cast<LLInventoryObject*>(cargo_data), drop))
+		if (dropPerson(static_cast<LLUUID*>(cargo_data), drop))
 		{
 			*accept = ACCEPT_YES_MULTI;
 		}
@@ -1016,13 +1016,13 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	return TRUE;
 }
 
-bool LLIMFloater::dropPerson(LLInventoryObject* item, bool drop)
+bool LLIMFloater::dropPerson(LLUUID* person_id, bool drop)
 {
-	bool res = item && item->getUUID().notNull();
+	bool res = person_id && person_id->notNull();
 	if(res)
 	{
 		uuid_vec_t ids;
-		ids.push_back(item->getUUID());
+		ids.push_back(*person_id);
 
 		res = canAddSelectedToChat(ids);
 		if(res && drop)
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index b02f779637..d74b13b88d 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -138,7 +138,7 @@ private:
 	// For display name lookups for IM window titles
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
 
-	bool dropPerson(LLInventoryObject* item, bool drop);
+	bool dropPerson(LLUUID* person_id, bool drop);
 
 	BOOL isInviteAllowed() const;
 	BOOL inviteToSession(const uuid_vec_t& agent_ids);
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 296ded6831..86708b46d5 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -58,7 +58,6 @@
 #include "llviewerwindow.h"
 #include "llvoavatarself.h"
 #include "llworld.h"
-#include "llclipboard.h"
 
 // syntactic sugar
 #define callMemberFunction(object,ptrToMember)  ((object).*(ptrToMember))
@@ -654,33 +653,41 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 		sOperationId++;
 	}
 
+	// For people drag and drop we don't need an actual inventory object,
+	// instead we need the current cargo id, which should be a person id.
+	bool is_uuid_dragged = (mSource == SOURCE_PEOPLE);
+
 	if (top_view)
 	{
 		handled = TRUE;
 
 		for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 		{
-			LLInventoryObject* cargo = locateInventory(item, cat);
+			S32 local_x, local_y;
+			top_view->screenPointToLocal( x, y, &local_x, &local_y );
+			EAcceptance item_acceptance = ACCEPT_NO;
 
+			LLInventoryObject* cargo = locateInventory(item, cat);
 			if (cargo)
 			{
-				S32 local_x, local_y;
-				top_view->screenPointToLocal( x, y, &local_x, &local_y );
-				EAcceptance item_acceptance = ACCEPT_NO;
 				handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
 													mCargoTypes[mCurItemIndex],
 													(void*)cargo,
 													&item_acceptance,
 													mToolTipMsg);
-				if (handled)
-				{
-					// use sort order to determine priority of acceptance
-					*acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
-				}
 			}
-			else
+			else if (is_uuid_dragged)
 			{
-				return;		
+				handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+													mCargoTypes[mCurItemIndex],
+													(void*)&mCargoIDs[mCurItemIndex],
+													&item_acceptance,
+													mToolTipMsg);
+			}
+			if (handled)
+			{
+				// use sort order to determine priority of acceptance
+				*acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
 			}
 		}
 
@@ -697,20 +704,27 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 
 			for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 			{
-				LLInventoryObject* cargo = locateInventory(item, cat);
+				S32 local_x, local_y;
+				EAcceptance item_acceptance;
+				top_view->screenPointToLocal( x, y, &local_x, &local_y );
 
+				LLInventoryObject* cargo = locateInventory(item, cat);
 				if (cargo)
 				{
-					S32 local_x, local_y;
-
-					EAcceptance item_acceptance;
-					top_view->screenPointToLocal( x, y, &local_x, &local_y );
 					handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE,
 														mCargoTypes[mCurItemIndex],
 														(void*)cargo,
 														&item_acceptance,
 														mToolTipMsg);
 				}
+				else if (is_uuid_dragged)
+				{
+					handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+														mCargoTypes[mCurItemIndex],
+														(void*)&mCargoIDs[mCurItemIndex],
+														&item_acceptance,
+														mToolTipMsg);
+				}
 			}
 		}
 		if (handled)
@@ -727,17 +741,27 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 
 		for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 		{
+			EAcceptance item_acceptance = ACCEPT_NO;
+
 			LLInventoryObject* cargo = locateInventory(item, cat);
 
 			// fix for EXT-3191
-			if (NULL == cargo) return;
-
-			EAcceptance item_acceptance = ACCEPT_NO;
-			handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
-												mCargoTypes[mCurItemIndex],
-												(void*)cargo,
-												&item_acceptance,
-												mToolTipMsg);
+			if (cargo)
+			{
+				handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+													mCargoTypes[mCurItemIndex],
+													(void*)cargo,
+													&item_acceptance,
+													mToolTipMsg);
+			}
+			else if (is_uuid_dragged)
+			{
+				handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+													mCargoTypes[mCurItemIndex],
+													(void*)&mCargoIDs[mCurItemIndex],
+													&item_acceptance,
+													mToolTipMsg);
+			}
 			if (handled)
 			{
 				// use sort order to determine priority of acceptance
@@ -757,17 +781,25 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 
 			for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 			{
-				LLInventoryObject* cargo = locateInventory(item, cat);
+				EAcceptance item_acceptance;
 
+				LLInventoryObject* cargo = locateInventory(item, cat);
 				if (cargo)
 				{
-					EAcceptance item_acceptance;
 					handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
 											  mCargoTypes[mCurItemIndex],
 											  (void*)cargo,
 											  &item_acceptance,
 											  mToolTipMsg);
 				}
+				else if (is_uuid_dragged)
+				{
+					handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
+											  mCargoTypes[mCurItemIndex],
+											  (void*)&mCargoIDs[mCurItemIndex],
+											  &item_acceptance,
+											  mToolTipMsg);
+				}
 			}
 		}
 
@@ -2495,7 +2527,13 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
 {
 	item = NULL;
 	cat = NULL;
-	if(mCargoIDs.empty()) return NULL;
+
+	if (mCargoIDs.empty()
+		|| (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop.
+	{
+		return NULL;
+	}
+
 	if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
 	{
 		// The object should be in user inventory.
@@ -2527,10 +2565,11 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
 			item = (LLViewerInventoryItem*)preview->getDragItem();
 		}
 	}
-	else if(mSource == SOURCE_VIEWER || mSource == SOURCE_PEOPLE)
+	else if(mSource == SOURCE_VIEWER)
 	{
 		item = (LLViewerInventoryItem*)gToolBarView->getDragItem();
 	}
+
 	if(item) return item;
 	if(cat) return cat;
 	return NULL;
-- 
cgit v1.2.3


From b01ab3b9b2d55a8536894a049354b87bb1d71cdb Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 13 Jun 2012 13:52:26 -0700
Subject: EXP-137 : Comments cleanup

---
 indra/newview/llimfloatercontainer.cpp | 19 ++++++++++---------
 indra/newview/llimfloatercontainer.h   | 23 ++++++++++++-----------
 2 files changed, 22 insertions(+), 20 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 9084c07cc7..77bb103bda 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -116,7 +116,7 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 
 	LLUUID session_id = floaterp->getKey();
 
-	// CHUI-137
+	// CHUI-137 : Temporary implementation of conversations list
 	// Create a conversation item
 	LLConversationItem* item = new LLConversationItem(floaterp->getTitle(),session_id, floaterp, this);
 	mConversationsItems[session_id] = item;
@@ -171,11 +171,12 @@ void LLIMFloaterContainer::removeFloater(LLFloater* floaterp)
 {
 	LLMultiFloater::removeFloater(floaterp);
 
-    // CHUI-137 : Clean up the conversations list
+    // CHUI-137 : Temporary implementation of conversations list
+	// Clean up the conversations list
  	LLUUID session_id = floaterp->getKey();
     // Delete the widget and the associated conversation item
-    // Note : since the mConversationsItems is a listener to the widget, deleting the widget also
-    // delete its listener
+    // Note : since the mConversationsItems is also the listener to the widget, deleting 
+    // the widget will also delete its listener
 	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(session_id);
 	if (widget_it != mConversationsWidgets.end())
     {
@@ -197,7 +198,7 @@ void LLIMFloaterContainer::removeFloater(LLFloater* floaterp)
                                panel_rect.getWidth(),
                                panel_rect.getHeight() - item_height*(index+1)));
     }
-    // CHUI-137
+    // CHUI-137 : end
    
 	LLRect contents_rect = floaterp->getRect();
 
@@ -362,7 +363,7 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
 }
 
-// CHUI-137 : Temp implementation of conversations list
+// CHUI-137 : Temporary implementation of conversations list
 LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
 {
 	LLFolderViewItem::Params params;
@@ -370,7 +371,6 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
 	params.name = item->getDisplayName();
 	//params.icon = bridge->getIcon();
 	//params.icon_open = bridge->getOpenIcon();
-		
 	//params.creation_date = bridge->getCreationDate();
 	//params.root = mFolderRoot;
 	params.listener = item;
@@ -387,7 +387,8 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
     mFloater(floaterp),
     mContainer(containerp)
 {
-    // Hack: the nearby chat has no name so we catch that and impose one
+    // Hack: the nearby chat has no name so we catch that case and impose one
+	// Of course, we won't be doing this in the final code
 	if (name == "")
 		mName = "Nearby Chat";
 }
@@ -395,7 +396,7 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
 // Virtual action callbacks
 void LLConversationItem::selectItem(void)
 {
-    // Select the conversation floater that is being selected
+    // Switch to the conversation floater that is being selected
     mContainer->selectFloater(mFloater);
 }
 
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 3df5a07df8..23927239a5 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -42,16 +42,16 @@ class LLButton;
 class LLLayoutPanel;
 class LLLayoutStack;
 class LLTabContainer;
+class LLIMFloaterContainer;
 
 // CHUI-137 : Temporary implementation of conversations list
 class LLConversationItem;
-class LLIMFloaterContainer;
 
 typedef std::map<LLUUID, LLConversationItem*> conversations_items_map;
 typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
 
-// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each that we tuck 
-// into the mConversationsListPanel. 
+// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each  
+// that we tuck into the mConversationsListPanel. 
 class LLConversationItem : public LLFolderViewEventListener
 {
 public:
@@ -89,7 +89,7 @@ public:
 	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
 	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
 
-	// The action callbacks (or so we think...)
+	// The action callbacks
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual void openItem( void );
 	virtual void closeItem( void );
@@ -97,14 +97,14 @@ public:
 	virtual void selectItem(void);
 	virtual void showProperties(void);
 	
-	// This method should be called when a drag begins. returns TRUE
-	// if the drag can begin, otherwise FALSE.
+	// This method should be called when a drag begins.
+	// Returns TRUE if the drag can begin, FALSE otherwise.
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const { return FALSE; }
 	
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
-	// requested. Returns TRUE if a drop is possible/happened,
-	// otherwise FALSE.
+	// requested. 
+	// Returns TRUE if a drop is possible/happened, FALSE otherwise.
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
 							void* cargo_data,
@@ -115,7 +115,7 @@ private:
     LLFloater* mFloater;
     LLIMFloaterContainer* mContainer;
 };
-	// CHUI-137 : End
+// CHUI-137 : End
 
 class LLIMFloaterContainer : public LLMultiFloater
 {
@@ -164,8 +164,9 @@ private:
 	LLLayoutPanel* mConversationsPane;
 	LLLayoutStack* mConversationsStack;
 	
-	// CHUI-137 : Data
-	LLPanel* mConversationsListPanel;	// The widget we add list item to (title of each conversation)
+	// CHUI-137 : Temporary implementation of conversations list
+	// Conversation list data
+	LLPanel* mConversationsListPanel;	// This is the widget we add items to (i.e. clickable title for each conversation)
 	conversations_items_map mConversationsItems;
 	conversations_widgets_map mConversationsWidgets;
 };
-- 
cgit v1.2.3


From d34746b596bad717f7d0c10e263700738a06aa43 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 14 Jun 2012 17:37:16 +0300
Subject: CHUI-144 FIXED Residents picker added to Conversations panel +
 button.

---
 indra/newview/llimfloatercontainer.cpp | 26 ++++++++++++++++++++++++++
 indra/newview/llimfloatercontainer.h   |  3 +++
 2 files changed, 29 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 3b6240de44..71b69dfbc8 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -34,8 +34,10 @@
 #include "llnearbychat.h"
 
 #include "llagent.h"
+#include "llavataractions.h"
 #include "llavatariconctrl.h"
 #include "llgroupiconctrl.h"
+#include "llfloateravatarpicker.h"
 #include "llimview.h"
 #include "lltransientfloatermgr.h"
 #include "llviewercontrol.h"
@@ -75,6 +77,8 @@ BOOL LLIMFloaterContainer::postBuild()
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
 
+	childSetAction("add_btn", boost::bind(&LLIMFloaterContainer::onAddButtonClicked, this));
+
 	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
 	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
 
@@ -313,4 +317,26 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
 }
 
+void LLIMFloaterContainer::onAddButtonClicked()
+{
+    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloaterContainer::onAvatarPicked, this, _1), TRUE, TRUE);
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+    if (picker && root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
+}
+
+void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
+{
+    if (ids.size() == 1)
+    {
+        LLAvatarActions::startIM(ids.back());
+    }
+    else
+    {
+        LLAvatarActions::startConference(ids);
+    }
+}
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 92938ff405..7b395fb18f 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -80,6 +80,9 @@ private:
 
 	void updateState(bool collapse, S32 delta_width);
 
+	void onAddButtonClicked();
+	void onAvatarPicked(const uuid_vec_t& ids);
+
 	LLButton* mExpandCollapseBtn;
 	LLLayoutPanel* mMessagesPane;
 	LLLayoutPanel* mConversationsPane;
-- 
cgit v1.2.3


From 51a39b5ac6465238178363f3ec3143dae4f73919 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 14 Jun 2012 20:00:41 +0300
Subject: CHUI-199 WIP Modified the nearby chat for using
 floater_im_session.xml; merging LLNearbyChatBar with LLNearbyChat; clean up
 code; supressed a double creation of LLNearbyChat

---
 indra/newview/llimconversation.cpp    | 14 ++++----------
 indra/newview/llimfloater.cpp         |  5 ++++-
 indra/newview/llimfloater.h           |  3 ---
 indra/newview/llnearbychat.cpp        |  4 +---
 indra/newview/llnearbychathandler.cpp |  1 -
 indra/newview/llviewerfloaterreg.cpp  |  2 +-
 6 files changed, 10 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index b45fc63825..3e2b208874 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -35,7 +35,6 @@
 #include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
 #include "lllayoutstack.h"
 #include "llnearbychat.h"
-#include "llnearbychat.h"
 
 const F32 REFRESH_INTERVAL = 0.2f;
 
@@ -84,13 +83,6 @@ BOOL LLIMConversation::postBuild()
 
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
 
-	// Show the participants list in torn off floaters only.
-//	mParticipantListPanel->setVisible(gSavedSettings.getBOOL("IMShowControlPanel")
-//									  && !mIsNearbyChat); // *TODO: temporarily disabled for Nearby chat
-//	mExpandCollapseBtn->setImageOverlay(
-//				getString(mParticipantListPanel->getVisible() ? "collapse_icon" : "expand_icon"));
-//	mExpandCollapseBtn->setEnabled(!mIsP2PChat);
-
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
 
@@ -144,9 +136,11 @@ void LLIMConversation::buildParticipantList()
 
 void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
 {
-	// TODO: Check this code when when sort order menu will be added. (EM)
-	if (true || !mParticipantList)
+	// TODO: Check this code when sort order menu will be added. (EM)
+	if (!mParticipantList)
+	{
 		return;
+	}
 
 	std::string chosen_item = userdata.asString();
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 7c6de01c96..30a9c29ec6 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -489,7 +489,10 @@ BOOL LLIMFloater::tick()
 {
 	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater
 	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy().
-	if (isDead()) return false;
+	if (isDead())
+	{
+		return false;
+	}
 
 	BOOL parents_retcode = LLIMConversation::tick();
 
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index d74b13b88d..333340c696 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -70,9 +70,6 @@ public:
 	static LLIMFloater* getInstance(const LLUUID& session_id);
 	static void addToHost(const LLUUID& session_id);
 
-	static void* createPanelGroupControl(void* userdata);
-	static void* createPanelAdHocControl(void* userdata);
-
 	// LLFloater overrides
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index cd181ce865..fbaf451412 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -408,8 +408,6 @@ BOOL LLNearbyChat::tick()
 	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy().
 	if (isDead()) return false;
 
-	BOOL parents_retcode = LLIMConversation::tick();
-
 	displaySpeakingIndicator();
 	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
 
@@ -421,7 +419,7 @@ BOOL LLNearbyChat::tick()
 		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
 	}
 
-	return parents_retcode;
+	return LLIMConversation::tick();
 }
 
 std::string LLNearbyChat::getCurrentChat()
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index e91a3fc334..c97e3585e1 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -555,7 +555,6 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	// Send event on to LLEventStream
 	sChatWatcher->post(chat);
 
-
 	if( nearby_chat->isInVisibleChain()
 		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") )
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index df1962f5fe..bf12b08321 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -186,6 +186,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
 
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
+	LLFloaterReg::add("chat_bar", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
 
 	LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
@@ -208,7 +209,6 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);	
 	LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
 
-	LLFloaterReg::add("chat_bar", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
 	LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
 	LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>);
 	LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>);
-- 
cgit v1.2.3


From c238027dd9917b1633ff5f16911fbdbe437f9a55 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 14 Jun 2012 16:47:43 -0700
Subject: CHUI-139 : Use the Chat toolbar button to open and close the
 conversations multi floater. Force Nearby Conversation if floater is empty.

---
 indra/newview/app_settings/commands.xml        |  6 +++---
 indra/newview/llimfloatercontainer.cpp         | 13 +++++++++++--
 indra/newview/skins/default/xui/en/strings.xml |  2 ++
 3 files changed, 16 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 73df064ab2..51211a8ce5 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -46,11 +46,11 @@
            available_in_toybox="true"
            icon="Command_Chat_Icon"
            label_ref="Command_Chat_Label"
-           tooltip_ref="Command_Chat_Tooltip"
+           tooltip_ref="Command_Conversations_Tooltip"
            execute_function="Floater.ToggleOrBringToFront"
-           execute_parameters="chat_bar"
+           execute_parameters="im_container"
            is_running_function="Floater.IsOpen"
-           is_running_parameters="chat_bar"
+           is_running_parameters="im_container"
            />
   <command name="compass"
            available_in_toybox="false"
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 77bb103bda..c01a167169 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -27,6 +27,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llimfloater.h"
 #include "llimfloatercontainer.h"
 
 #include "llfloaterreg.h"
@@ -86,7 +87,15 @@ BOOL LLIMFloaterContainer::postBuild()
 void LLIMFloaterContainer::onOpen(const LLSD& key)
 {
 	LLMultiFloater::onOpen(key);
-/*
+	if (getFloaterCount() == 0)
+	{
+		// If there's *no* conversation open so far, we force the opening of the nearby chat conversation
+		// *TODO: find a way to move this to XML as a default panel or something like that
+		LLSD name("chat_bar");
+		LLSD key("");
+		LLFloaterReg::toggleInstanceOrBringToFront(name,key);
+	}
+	/*
 	if (key.isDefined())
 	{
 		LLIMFloater* im_floater = LLIMFloater::findInstance(key.asUUID());
@@ -95,7 +104,7 @@ void LLIMFloaterContainer::onOpen(const LLSD& key)
 			im_floater->openFloater();
 		}
 	}
-*/
+	 */
 }
 
 // virtual
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 0a2fc13aff..7790a382d9 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3692,6 +3692,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Avatar_Label">Avatar</string>
   <string name="Command_Build_Label">Build</string>
   <string name="Command_Chat_Label">Chat</string>
+  <string name="Command_Conversations_Label">Conversations</string>
   <string name="Command_Compass_Label">Compass</string>
   <string name="Command_Destinations_Label">Destinations</string>
   <string name="Command_Gestures_Label">Gestures</string>
@@ -3718,6 +3719,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Avatar_Tooltip">Choose a complete avatar</string>
   <string name="Command_Build_Tooltip">Building objects and reshaping terrain</string>
   <string name="Command_Chat_Tooltip">Chat with people nearby using text</string>
+  <string name="Command_Conversations_Tooltip">Converse with everyone</string>
   <string name="Command_Compass_Tooltip">Compass</string>
   <string name="Command_Destinations_Tooltip">Destinations of interest</string>
   <string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
-- 
cgit v1.2.3


From 9940ca5ae7698e89c0587733f7ab922027c8ddcc Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 15 Jun 2012 09:44:27 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose llfolderview
 refactornig

---
 indra/llinventory/llinventory.cpp                  |  31 +-
 indra/llinventory/llinventory.h                    |   5 +-
 indra/llxuixml/llinitparam.h                       |  88 ++--
 indra/newview/llavataractions.cpp                  |  27 +-
 indra/newview/llfloateroutbox.cpp                  |  13 +-
 indra/newview/llfolderview.cpp                     | 398 ++-------------
 indra/newview/llfolderview.h                       |  56 +--
 indra/newview/llfoldervieweventlistener.h          | 245 ++++++++-
 indra/newview/llfolderviewitem.cpp                 | 554 ++++++---------------
 indra/newview/llfolderviewitem.h                   | 238 ++++-----
 indra/newview/llfriendcard.cpp                     |   4 +-
 indra/newview/llinventorybridge.cpp                | 335 ++++++++-----
 indra/newview/llinventorybridge.h                  |  67 +--
 indra/newview/llinventoryfilter.cpp                | 181 +++----
 indra/newview/llinventoryfilter.h                  | 145 ++++--
 indra/newview/llinventorypanel.cpp                 | 234 ++++++---
 indra/newview/llinventorypanel.h                   |  54 +-
 indra/newview/llpanellandmarks.cpp                 |  57 +--
 indra/newview/llpanelmaininventory.cpp             |  45 +-
 indra/newview/llpanelmarketplaceinbox.cpp          |  12 +-
 indra/newview/llpanelmarketplaceinboxinventory.cpp |   5 +-
 indra/newview/llpanelmarketplaceinboxinventory.h   |   4 +-
 .../newview/llpanelmarketplaceoutboxinventory.cpp  |   2 +-
 indra/newview/llpanelobjectinventory.cpp           |  26 +-
 indra/newview/llpaneloutfitedit.cpp                |  30 +-
 indra/newview/llplacesinventorybridge.cpp          |  43 +-
 indra/newview/llplacesinventorypanel.cpp           |   3 +-
 indra/newview/llsidepanelappearance.cpp            |   2 +-
 indra/newview/llsidepanelinventory.cpp             |   7 +-
 indra/newview/llsidepanelinventory.h               |   1 +
 indra/newview/lltexturectrl.cpp                    |   4 +-
 indra/newview/llviewerinventory.cpp                |  23 +-
 indra/newview/llviewerinventory.h                  |  12 +-
 indra/newview/llviewermessage.cpp                  |  20 +-
 34 files changed, 1456 insertions(+), 1515 deletions(-)

(limited to 'indra')

diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index fbf23bc3f0..784e20ad46 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -275,6 +275,18 @@ void LLInventoryObject::correctInventoryName(std::string& name)
 	LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN);
 }
 
+time_t LLInventoryObject::getCreationDate() const
+{
+	return mCreationDate;
+}
+
+void LLInventoryObject::setCreationDate(time_t creation_date_utc)
+{
+	mCreationDate = creation_date_utc;
+}
+
+
+
 
 ///----------------------------------------------------------------------------
 /// Class LLInventoryItem
@@ -297,9 +309,10 @@ LLInventoryItem::LLInventoryItem(const LLUUID& uuid,
 	mDescription(desc),
 	mSaleInfo(sale_info),
 	mInventoryType(inv_type),
-	mFlags(flags),
-	mCreationDate(creation_date_utc)
+	mFlags(flags)
 {
+	mCreationDate = creation_date_utc;
+
 	LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
 	LLStringUtil::replaceChar(mDescription, '|', ' ');
 	mPermissions.initMasks(inv_type);
@@ -312,9 +325,9 @@ LLInventoryItem::LLInventoryItem() :
 	mDescription(),
 	mSaleInfo(),
 	mInventoryType(LLInventoryType::IT_NONE),
-	mFlags(0),
-	mCreationDate(0)
+	mFlags(0)
 {
+	mCreationDate = 0;
 }
 
 LLInventoryItem::LLInventoryItem(const LLInventoryItem* other) :
@@ -379,11 +392,6 @@ const std::string& LLInventoryItem::getDescription() const
 	return mDescription;
 }
 
-time_t LLInventoryItem::getCreationDate() const
-{
-	return mCreationDate;
-}
-
 U32 LLInventoryItem::getCRC32() const
 {
 	// *FIX: Not a real crc - more of a checksum.
@@ -440,11 +448,6 @@ void LLInventoryItem::setFlags(U32 flags)
 	mFlags = flags;
 }
 
-void LLInventoryItem::setCreationDate(time_t creation_date_utc)
-{
-	mCreationDate = creation_date_utc;
-}
-
 // Currently only used in the Viewer to handle calling cards
 // where the creator is actually used to store the target.
 void LLInventoryItem::setCreator(const LLUUID& creator)
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index a5cfe59bda..dc9a09e9d6 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -75,6 +75,7 @@ public:
 	virtual LLAssetType::EType getType() const;
 	LLAssetType::EType getActualType() const; // bypasses indirection for linked items
 	BOOL getIsLinkType() const;
+	virtual time_t getCreationDate() const;
 	
 	//--------------------------------------------------------------------
 	// Mutators
@@ -85,6 +86,7 @@ public:
 	virtual void rename(const std::string& new_name);
 	void setParent(const LLUUID& new_parent);
 	void setType(LLAssetType::EType type);
+	virtual void setCreationDate(time_t creation_date_utc); // only stored for items
 
 private:
 	// in place correction for inventory name string
@@ -113,6 +115,7 @@ protected:
 	LLUUID mParentUUID; // Parent category.  Root categories have LLUUID::NULL.
 	LLAssetType::EType mType;
 	std::string mName;
+	time_t mCreationDate; // seconds from 1/1/1970, UTC
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -178,7 +181,6 @@ public:
 	void setPermissions(const LLPermissions& perm);
 	void setInventoryType(LLInventoryType::EType inv_type);
 	void setFlags(U32 flags);
-	void setCreationDate(time_t creation_date_utc);
 	void setCreator(const LLUUID& creator); // only used for calling cards
 
 	// Check for changes in permissions masks and sale info
@@ -224,7 +226,6 @@ protected:
 	LLSaleInfo mSaleInfo;
 	LLInventoryType::EType mInventoryType;
 	U32 mFlags;
-	time_t mCreationDate; // seconds from 1/1/1970, UTC
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index ce59401e87..d44ccac6e4 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -212,7 +212,7 @@ namespace LLInitParam
 		{}
 
 		ParamValue(const default_value_t& other)
-			:	T(other),
+		:	T(other),
 			mValidated(false)
 		{}
 
@@ -632,38 +632,38 @@ namespace LLInitParam
 		class BaseBlock*				mCurrentBlockPtr;		// pointer to block currently being constructed
 	};
 
-		//TODO: implement in terms of owned_ptr
-		template<typename T>
+	//TODO: implement in terms of owned_ptr
+	template<typename T>
 	class LazyValue
-		{
+	{
 		public:
 		LazyValue()
-				: mPtr(NULL)
-			{}
+		: mPtr(NULL)
+		{}
 
 		~LazyValue()
-			{
-				delete mPtr;
-			}
+		{
+			delete mPtr;
+		}
 
 		LazyValue(const T& value)
-			{
+		{
 			mPtr = new T(value);
 		}
 
 		LazyValue(const LazyValue& other)
 		:	mPtr(NULL)
-				{
+		{
 			*this = other;
-				}
+		}
 
 		LazyValue& operator = (const LazyValue& other)
 		{
 			if (!other.mPtr)
-				{
+			{
 				delete mPtr;
-					mPtr = NULL;
-				}
+				mPtr = NULL;
+			}
 			else
 			{
 				if (!mPtr)
@@ -674,9 +674,9 @@ namespace LLInitParam
 				{
 					*mPtr = *(other.mPtr);
 				}
-				}
-				return *this;
 			}
+			return *this;
+		}
 
 		bool operator==(const LazyValue& other) const
 		{
@@ -684,13 +684,13 @@ namespace LLInitParam
 			return *mPtr == *other.mPtr;
 		}
 
-			bool empty() const
-			{
-				return mPtr == NULL;
-			}
+		bool empty() const
+		{
+			return mPtr == NULL;
+		}
 
-			void set(const T& other)
-			{
+		void set(const T& other)
+		{
 			if (!mPtr)
 			{
 				mPtr = new T(other);
@@ -701,36 +701,36 @@ namespace LLInitParam
 			}
 		}
 
-			const T& get() const
-			{
+		const T& get() const
+		{
 			return *ensureInstance();
-			}
+		}
 
-			T& get()
-			{
+		T& get()
+		{
 			return *ensureInstance();
 		}
 
 		operator const T&() const
 		{ 
 			return get(); 
-			}
+		}
 
-		private:
-			// lazily allocate an instance of T
-			T* ensureInstance() const
+	private:
+		// lazily allocate an instance of T
+		T* ensureInstance() const
+		{
+			if (mPtr == NULL)
 			{
-				if (mPtr == NULL)
-				{
-					mPtr = new T();
-				}
-				return mPtr;
-			}
+				mPtr = new T();			
+                        }
+			return mPtr;
+		}
 
-		private:
+	private:
 
-			mutable T* mPtr;
-		};
+		mutable T* mPtr;
+	};
 
 	// root class of all parameter blocks
 
@@ -2492,10 +2492,10 @@ namespace LLInitParam
 		} EValueAge;
 
 		typedef ParamValue<T>			derived_t;
-		typedef CustomParamValue<T>				self_t;
-		typedef Block<derived_t>				block_t;
+		typedef CustomParamValue<T>		self_t;
+		typedef Block<derived_t>		block_t;
 		typedef T						default_value_t;
-		typedef T								value_t;
+		typedef T						value_t;
 		typedef void					baseblock_base_class_t;
 
 
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index aa626a9a30..1d5543cd20 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -711,23 +711,30 @@ namespace action_give_inventory
 //static
 std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
 {
-	std::set<LLUUID> inventory_selected_uuids;
+	std::set<LLFolderViewItem*> inventory_selected;
 
 	LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
 	if (active_panel)
 	{
-		inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
+		inventory_selected= active_panel->getRootFolder()->getSelectionList();
 	}
 
-	if (inventory_selected_uuids.empty())
+	if (inventory_selected.empty())
 	{
 		LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
 		if (sidepanel_inventory)
 		{
-			inventory_selected_uuids = sidepanel_inventory->getInboxSelectionList();
+			inventory_selected= sidepanel_inventory->getInboxSelectionList();
 		}
 	}
 
+	std::set<LLUUID> inventory_selected_uuids;
+	for (std::set<LLFolderViewItem*>::iterator it = inventory_selected.begin(), end_it = inventory_selected.end();
+		it != end_it;
+		++it)
+	{
+		inventory_selected_uuids.insert((*it)->getListener()->getUUID());
+	}
 	return inventory_selected_uuids;
 }
 
@@ -758,15 +765,15 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 
 	// check selection in the panel
 	LLFolderView* root_folder = inv_panel->getRootFolder();
-	const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList();
-	if (inventory_selected_uuids.empty()) return false; // nothing selected
+	const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
+	if (inventory_selected.empty()) return false; // nothing selected
 
 	bool can_share = true;
-	std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
-	const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
+	std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
+	const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
 	for (; it != it_end; ++it)
 	{
-		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
+		LLViewerInventoryCategory* inv_cat = gInventory.getCategory((*it)->getListener()->getUUID());
 		// any category can be offered.
 		if (inv_cat)
 		{
@@ -774,7 +781,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 		}
 
 		// check if inventory item can be given
-		LLFolderViewItem* item = root_folder->getItemByID(*it);
+		LLFolderViewItem* item = *it;
 		if (!item) return false;
 		LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getListener());
 		if (bridge && bridge->canShare())
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index c55970ad69..ba0f51b467 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -250,7 +250,8 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
 	mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
 	
 	// Set the sort order newest to oldest
-	mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
+
+	mOutboxInventoryPanel->getViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
 	mOutboxInventoryPanel->getFilter()->markDefault();
 	
 	fetchOutboxContents();
@@ -386,7 +387,7 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	// Determine if the mouse is inside the inventory panel itself or just within the floater
 	bool pointInInventoryPanel = false;
 	bool pointInInventoryPanelChild = false;
-	LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder();
+	LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder();
 	if (mOutboxInventoryPanel->getVisible())
 	{
 		S32 inv_x, inv_y;
@@ -443,10 +444,10 @@ void LLFloaterOutbox::onOutboxChanged()
 {
 	llassert(!mOutboxId.isNull());
 	
-	if (mOutboxInventoryPanel)
-	{
-		mOutboxInventoryPanel->requestSort();
-	}
+	//if (mOutboxInventoryPanel)
+	//{
+	//	mOutboxInventoryPanel->requestSort();
+	//}
 
 	fetchOutboxContents();
 
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index f375443e38..ffef4ef69a 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -26,6 +26,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llfolderview.h"
 #include "llfolderview.h"
 
 #include "llcallbacklist.h"
@@ -94,42 +95,6 @@ enum {
 
 F32 LLFolderView::sAutoOpenTime = 1.f;
 
-void delete_selected_item(void* user_data);
-void copy_selected_item(void* user_data);
-void open_selected_items(void* user_data);
-void properties_selected_items(void* user_data);
-void paste_items(void* user_data);
-
-
-//---------------------------------------------------------------------------
-
-// Tells all folders in a folderview to sort their items
-// (and only their items, not folders) by a certain function.
-class LLSetItemSortFunction : public LLFolderViewFunctor
-{
-public:
-	LLSetItemSortFunction(U32 ordering)
-		: mSortOrder(ordering) {}
-	virtual ~LLSetItemSortFunction() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-
-	U32 mSortOrder;
-};
-
-
-// Set the sort order.
-void LLSetItemSortFunction::doFolder(LLFolderViewFolder* folder)
-{
-	folder->setItemSortOrder(mSortOrder);
-}
-
-// Do nothing.
-void LLSetItemSortFunction::doItem(LLFolderViewItem* item)
-{
-	return;
-}
-
 //---------------------------------------------------------------------------
 
 // Tells all folders in a folderview to close themselves
@@ -154,7 +119,6 @@ public:
 };
 
 
-// Set the sort order.
 void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)
 {
 	folder->setOpenArrangeRecursively(mOpen);
@@ -173,7 +137,6 @@ LLFolderView::Params::Params()
 	use_label_suffix("use_label_suffix"),
 	allow_multiselect("allow_multiselect", true),
 	show_empty_message("show_empty_message", true),
-	show_load_status("show_load_status", true),
 	use_ellipses("use_ellipses", false)
 {
 	folder_indentation = -4;
@@ -183,7 +146,6 @@ LLFolderView::Params::Params()
 // Default constructor
 LLFolderView::LLFolderView(const Params& p)
 :	LLFolderViewFolder(p),
-	mRunningHeight(0),
 	mScrollContainer( NULL ),
 	mPopupMenuHandle(),
 	mAllowMultiSelect(p.allow_multiselect),
@@ -210,17 +172,15 @@ LLFolderView::LLFolderView(const Params& p)
 	mParentPanel(p.parent_panel),
 	mUseEllipses(p.use_ellipses),
 	mDraggingOverItem(NULL),
-	mStatusTextBox(NULL)
+	mStatusTextBox(NULL),
+	mViewModel(p.view_model)
 {
 	mRoot = this;
 
-	mShowLoadStatus = p.show_load_status();
-
 	LLRect rect = p.rect;
 	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
 	setRect( rect );
 	reshape(rect.getWidth(), rect.getHeight());
-	mIsOpen = TRUE; // this view is always open.
 	mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH);
 	mAutoOpenCandidate = NULL;
 	mAutoOpenTimer.stop();
@@ -305,8 +265,6 @@ LLFolderView::~LLFolderView( void )
 	mItems.clear();
 	mFolders.clear();
 
-	mItemMap.clear();
-
 	delete mFilter;
 	mFilter = NULL;
 }
@@ -316,27 +274,6 @@ BOOL LLFolderView::canFocusChildren() const
 	return FALSE;
 }
 
-static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory");
-
-void LLFolderView::setSortOrder(U32 order)
-{
-	if (order != mSortOrder)
-	{
-		LLFastTimer t(FTM_SORT);
-		
-		mSortOrder = order;
-
-		sortBy(order);
-		arrangeAll();
-	}
-}
-
-
-U32 LLFolderView::getSortOrder() const
-{
-	return mSortOrder;
-}
-
 BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 {
 	// enforce sort order of My Inventory followed by Library
@@ -348,7 +285,6 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 	{
 		mFolders.insert(mFolders.begin(), folder);
 	}
-	folder->setShowLoadStatus(mShowLoadStatus);
 	folder->setOrigin(0, 0);
 	folder->reshape(getRect().getWidth(), 0);
 	folder->setVisible(FALSE);
@@ -375,128 +311,32 @@ void LLFolderView::openTopLevelFolders()
 	}
 }
 
-void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
-	// call base class to do proper recursion
-	LLFolderViewFolder::setOpenArrangeRecursively(openitem, recurse);
-	// make sure root folder is always open
-	mIsOpen = TRUE;
-}
-
-static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
-
 // This view grows and shrinks to enclose all of its children items and folders.
+// mItemHeight = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0;
+// *width should be 0
+// conform show folder state works
 S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )
 {
-	if (getListener()->getUUID().notNull())
-	{
-		if (mNeedsSort)
-		{
-			mFolders.sort(mSortFunction);
-			mItems.sort(mSortFunction);
-			mNeedsSort = false;
-		}
-	}
-
-	LLFastTimer t2(FTM_ARRANGE);
-
-	filter_generation = mFilter->getMinRequiredGeneration();
 	mMinWidth = 0;
+	S32 target_height;
 
-	mHasVisibleChildren = hasFilteredDescendants(filter_generation);
-	// arrange always finishes, so optimistically set the arrange generation to the most current
-	mLastArrangeGeneration = getRoot()->getArrangeGeneration();
-
-	LLInventoryFilter::EFolderShow show_folder_state =
-		getRoot()->getFilter()->getShowFolderState();
-
-	S32 total_width = LEFT_PAD;
-	S32 running_height = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0;
-	S32 target_height = running_height;
-	S32 parent_item_height = getRect().getHeight();
-
-	for (folders_t::iterator iter = mFolders.begin();
-		 iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		LLFolderViewFolder* folderp = (*fit);
-		if (getDebugFilters())
-		{
-			folderp->setVisible(TRUE);
-		}
-		else
-		{
-			folderp->setVisible(show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
-									(folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
-		}
-
-		if (folderp->getVisible())
-		{
-			S32 child_height = 0;
-			S32 child_width = 0;
-			S32 child_top = parent_item_height - running_height;
-			
-			target_height += folderp->arrange( &child_width, &child_height, filter_generation );
-
-			mMinWidth = llmax(mMinWidth, child_width);
-			total_width = llmax( total_width, child_width );
-			running_height += child_height;
-			folderp->setOrigin( ICON_PAD, child_top - (*fit)->getRect().getHeight() );
-		}
-	}
-
-	for (items_t::iterator iter = mItems.begin();
-		 iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		LLFolderViewItem* itemp = (*iit);
-		itemp->setVisible(itemp->getFiltered(filter_generation));
-
-		if (itemp->getVisible())
-		{
-			S32 child_width = 0;
-			S32 child_height = 0;
-			S32 child_top = parent_item_height - running_height;
-			
-			target_height += itemp->arrange( &child_width, &child_height, filter_generation );
-			itemp->reshape(itemp->getRect().getWidth(), child_height);
-
-			mMinWidth = llmax(mMinWidth, child_width);
-			total_width = llmax( total_width, child_width );
-			running_height += child_height;
-			itemp->setOrigin( ICON_PAD, child_top - itemp->getRect().getHeight() );
-		}
-	}
-
-	if(!mHasVisibleChildren)// is there any filtered items ?
-	{
-		//Nope. We need to display status textbox, let's reserve some place for it
-		running_height = mStatusTextBox->getTextPixelHeight();
-		target_height = running_height;
-	}
+	LLFolderViewFolder::arrange(&mMinWidth, &target_height, mFilter->getFirstSuccessGeneration());
 
-	mRunningHeight = running_height;
 	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
-	reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
+	reshape( llmax(scroll_rect.getWidth(), mMinWidth), mCurHeight );
 
 	LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
 	if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
 	{
-		reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
+		reshape( llmax(scroll_rect.getWidth(), mMinWidth), mCurHeight );
 	}
 
 	// move item renamer text field to item's new position
 	updateRenamerPosition();
 
-	mTargetHeight = (F32)target_height;
 	return llround(mTargetHeight);
 }
 
-const std::string LLFolderView::getFilterSubString(BOOL trim)
-{
-	return mFilter->getFilterSubString(trim);
-}
-
 static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory");
 
 void LLFolderView::filter( LLInventoryFilter& filter )
@@ -525,7 +365,7 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
 		scroll_rect = mScrollContainer->getContentWindowRect();
 	}
 	width = llmax(mMinWidth, scroll_rect.getWidth());
-	height = llmax(mRunningHeight, scroll_rect.getHeight());
+	height = llmax(mCurHeight, scroll_rect.getHeight());
 
 	// Restrict width within scroll container's width
 	if (mUseEllipses && mScrollContainer)
@@ -623,30 +463,6 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
 	return rv;
 }
 
-void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus)
-{
-	LLFolderViewItem* itemp = getItemByID(obj_id);
-	if(itemp && itemp->getListener())
-	{
-		itemp->arrangeAndSet(TRUE, take_keyboard_focus);
-		mSelectThisID.setNull();
-		return;
-	}
-	else
-	{
-		// save the desired item to be selected later (if/when ready)
-		mSelectThisID = obj_id;
-	}
-}
-
-void LLFolderView::updateSelection()
-{
-	if (mSelectThisID.notNull())
-	{
-		setSelectionByID(mSelectThisID, false);
-	}
-}
-
 BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
 {
 	BOOL rv = FALSE;
@@ -697,9 +513,6 @@ void LLFolderView::sanitizeSelection()
 	// and we want to preserve context
 	LLFolderViewItem* original_selected_item = getCurSelectedItem();
 
-	// Cache "Show all folders" filter setting
-	BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS);
-
 	std::vector<LLFolderViewItem*> items_to_remove;
 	selected_items_t::iterator item_iter;
 	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
@@ -710,20 +523,11 @@ void LLFolderView::sanitizeSelection()
 		BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item
 		// modify with parent open and filters states
 		LLFolderViewFolder* parent_folder = item->getParentFolder();
-		if ( parent_folder )
+		// Move up through parent folders and see what's visible
+		while(parent_folder)
 		{
-			if ( show_all_folders )
-			{	// "Show all folders" is on, so this folder is visible
-				visible = TRUE;
-			}
-			else
-			{	// Move up through parent folders and see what's visible
-				while(parent_folder)
-				{
-					visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();
-					parent_folder = parent_folder->getParentFolder();
-				}
-			}
+			visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();
+			parent_folder = parent_folder->getParentFolder();
 		}
 
 		//  deselect item if any ancestor is closed or didn't pass filter requirements.
@@ -816,15 +620,10 @@ void LLFolderView::clearSelection()
 	mSelectThisID.setNull();
 }
 
-std::set<LLUUID> LLFolderView::getSelectionList() const
+std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const
 {
-	std::set<LLUUID> selection;
-	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); 
-		 item_it != mSelectedItems.end(); 
-		 ++item_it)
-	{
-		selection.insert((*item_it)->getListener()->getUUID());
-	}
+	std::set<LLFolderViewItem*> selection;
+	std::copy(mSelectedItems.begin(), mSelectedItems.end(), std::inserter(selection, selection.begin()));
 	return selection;
 }
 
@@ -862,7 +661,7 @@ void LLFolderView::draw()
 	if (mDebugFilters)
 	{
 		std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d",
-										mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration());
+										mFilter->getCurrentGeneration(), mFilter->getFirstSuccessGeneration(), mFilter->getFirstRequiredGeneration());
 		LLFontGL::getFontMonospace()->renderUTF8(current_filter_string, 0, 2, 
 			getRect().getHeight() - LLFontGL::getFontMonospace()->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), 
 			LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
@@ -901,25 +700,23 @@ void LLFolderView::draw()
 		mSearchString.clear();
 	}
 
-	if (hasVisibleChildren()
-		|| mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS)
+	if (hasVisibleChildren())
 	{
 		mStatusText.clear();
 		mStatusTextBox->setVisible( FALSE );
 	}
 	else if (mShowEmptyMessage)
 	{
-		if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
+		if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getFirstSuccessGeneration())
 		{
+			RN: Get this from filter
 			mStatusText = LLTrans::getString("Searching");
 		}
 		else
 		{
 			if (getFilter())
 			{
-				LLStringUtil::format_map_t args;
-				args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig());
-				mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args);
+				mStatusText = getFilter()->getEmptyLookupMessage();
 			}
 		}
 		mStatusTextBox->setValue(mStatusText);
@@ -963,7 +760,7 @@ void LLFolderView::finishRenamingItem( void )
 
 	closeRenamer();
 
-	// List is re-sorted alphabeticly, so scroll to make sure the selected item is visible.
+	// List is re-sorted alphabetically, so scroll to make sure the selected item is visible.
 	scrollToShowSelection();
 }
 
@@ -1074,8 +871,8 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 		}
 		else if (count > 1)
 		{
-			LLDynamicArray<LLFolderViewEventListener*> listeners;
-			LLFolderViewEventListener* listener;
+			LLDynamicArray<LLFolderViewModelItem*> listeners;
+			LLFolderViewModelItemInventory* listener;
 			LLFolderViewItem* last_item = items[count - 1];
 			LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
 			while(new_selection && new_selection->isSelected())
@@ -1102,12 +899,12 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 			for(S32 i = 0; i < count; ++i)
 			{
 				listener = items[i]->getListener();
-				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewEventListener*>::FAIL))
+				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItemInventory*>::FAIL))
 				{
 					listeners.put(listener);
 				}
 			}
-			listener = listeners.get(0);
+			listener = static_cast<LLFolderViewModelItemInventory*>(listeners.get(0));
 			if(listener)
 			{
 				listener->removeBatch(listeners);
@@ -1138,7 +935,7 @@ void LLFolderView::openSelectedItems( void )
 				// IT_{OBJECT,ATTACHMENT} creates LLProperties
 				// floaters; others create LLPreviews.  Put
 				// each one in the right type of container.
-				LLFolderViewEventListener* listener = (*item_it)->getListener();
+				LLFolderViewModelItemInventory* listener = (*item_it)->getListener();
 				bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
 				if (is_prop)
 					LLFloater::setFloaterHost(multi_propertiesp);
@@ -1294,7 +1091,7 @@ void LLFolderView::copy()
 	S32 count = mSelectedItems.size();
 	if(getVisible() && getEnabled() && (count > 0))
 	{
-		LLFolderViewEventListener* listener = NULL;
+		LLFolderViewModelItemInventory* listener = NULL;
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
@@ -1318,7 +1115,7 @@ BOOL LLFolderView::canCut() const
 	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 	{
 		const LLFolderViewItem* item = *selected_it;
-		const LLFolderViewEventListener* listener = item->getListener();
+		const LLFolderViewModelItemInventory* listener = item->getListener();
 
 		if (!listener || !listener->isItemRemovable())
 		{
@@ -1335,7 +1132,7 @@ void LLFolderView::cut()
 	S32 count = mSelectedItems.size();
 	if(getVisible() && getEnabled() && (count > 0))
 	{
-		LLFolderViewEventListener* listener = NULL;
+		LLFolderViewModelItemInventory* listener = NULL;
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
@@ -1363,7 +1160,7 @@ BOOL LLFolderView::canPaste() const
 		{
 			// *TODO: only check folders and parent folders of items
 			const LLFolderViewItem* item = (*item_it);
-			const LLFolderViewEventListener* listener = item->getListener();
+			const LLFolderViewModelItemInventory* listener = item->getListener();
 			if(!listener || !listener->isClipboardPasteable())
 			{
 				const LLFolderViewFolder* folderp = item->getParentFolder();
@@ -1391,7 +1188,7 @@ void LLFolderView::paste()
 		for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 		{
 			LLFolderViewItem* item = *selected_it;
-			LLFolderViewEventListener* listener = item->getListener();
+			LLFolderViewModelItemInventory* listener = item->getListener();
 			if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
 			{
 				item = item->getParentFolder();
@@ -1402,7 +1199,7 @@ void LLFolderView::paste()
 		std::set<LLFolderViewItem*>::iterator set_iter;
 		for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)
 		{
-			LLFolderViewEventListener* listener = (*set_iter)->getListener();
+			LLFolderViewModelItemInventory* listener = (*set_iter)->getListener();
 			if(listener && listener->isClipboardPasteable())
 			{
 				listener->pasteFromClipboard();
@@ -1845,7 +1642,7 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
 	S32 count = mSelectedItems.size();
 	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
 	if (   handled
-		&& ( count > 0 && (hasVisibleChildren() || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible
+		&& ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible
 		&& menu )
 	{
 		if (mCallbackRegistrar)
@@ -2032,55 +1829,6 @@ void LLFolderView::setShowSingleSelection(BOOL show)
 	}
 }
 
-void LLFolderView::addItemID(const LLUUID& id, LLFolderViewItem* itemp)
-{
-	mItemMap[id] = itemp;
-}
-
-void LLFolderView::removeItemID(const LLUUID& id)
-{
-	mItemMap.erase(id);
-}
-
-LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
-LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
-{
-	LLFastTimer _(FTM_GET_ITEM_BY_ID);
-	if (id == getListener()->getUUID())
-	{
-		return this;
-	}
-
-	std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
-	map_it = mItemMap.find(id);
-	if (map_it != mItemMap.end())
-	{
-		return map_it->second;
-	}
-
-	return NULL;
-}
-
-LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
-{
-	if (id == getListener()->getUUID())
-	{
-		return this;
-	}
-
-	for (folders_t::iterator iter = mFolders.begin();
-		 iter != mFolders.end();
-		 ++iter)
-	{
-		LLFolderViewFolder *folder = (*iter);
-		if (folder->getListener()->getUUID() == id)
-		{
-			return folder;
-		}
-	}
-	return NULL;
-}
-
 bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
 {
 	std::string action = userdata.asString();
@@ -2111,7 +1859,7 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
 	}
 
 
-	std::set<LLUUID> selected_items = getSelectionList();
+	std::set<LLFolderViewItem*> selected_items = getSelectionList();
 
 	LLMultiPreview* multi_previewp = NULL;
 	LLMultiProperties* multi_propertiesp = NULL;
@@ -2132,11 +1880,11 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
 		LLFloater::setFloaterHost(multi_propertiesp);
 	}
 
-	std::set<LLUUID>::iterator set_iter;
+	std::set<LLFolderViewItem*>::iterator set_iter;
 
 	for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
 	{
-		LLFolderViewItem* folder_item = getItemByID(*set_iter);
+		LLFolderViewItem* folder_item = *set_iter;
 		if(!folder_item) continue;
 		LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
 		if(!bridge) continue;
@@ -2486,72 +2234,18 @@ void LLFolderView::onRenamerLost()
 	}
 }
 
-LLInventoryFilter* LLFolderView::getFilter()
+LLFolderViewFilter* LLFolderView::getFilter()
 {
 	return mFilter;
 }
 
-void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask )
-{
-	mFilter->setFilterPermissions(filter_perm_mask);
-}
-
-U32 LLFolderView::getFilterObjectTypes() const
-{
-	return mFilter->getFilterObjectTypes();
-}
-
-PermissionMask LLFolderView::getFilterPermissions() const
-{
-	return mFilter->getFilterPermissions();
-}
-
-BOOL LLFolderView::isFilterModified()
-{
-	return mFilter->isNotDefault();
-}
-
-void delete_selected_item(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->removeSelectedItems();
-	}
-}
-
-void copy_selected_item(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->copy();
-	}
-}
-
-void paste_items(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->paste();
-	}
-}
-
-void open_selected_items(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->openSelectedItems();
-	}
-}
-
-void properties_selected_items(void* user_data)
+S32 LLFolderView::getItemHeight()
 {
-	if(user_data)
+	S32 debug_height = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0;
+	if(!hasVisibleChildren())
 	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->propertiesSelectedItems();
+		//We need to display status textbox, let's reserve some place for it
+		return llmax(debug_height, mStatusTextBox->getTextPixelHeight());
 	}
+	return debug_height;
 }
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 9a6bf05cd1..15a3f662c4 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -47,9 +47,10 @@
 #include "lltooldraganddrop.h"
 #include "llviewertexture.h"
 
-class LLFolderViewEventListener;
+class LLFolderViewModelInterface;
 class LLFolderViewFolder;
 class LLFolderViewItem;
+class LLFolderViewFilter;
 class LLInventoryModel;
 class LLPanel;
 class LLLineEditor;
@@ -76,8 +77,8 @@ public:
 		Optional<bool>			use_label_suffix,
 								allow_multiselect,
 								show_empty_message,
-								show_load_status,
 								use_ellipses;
+		Mandatory<LLFolderViewModelInterface*>	view_model;
 
 		Params();
 	};
@@ -88,9 +89,8 @@ public:
 
 	virtual LLFolderView*	getRoot() { return this; }
 
-	// FolderViews default to sort by name.  This will change that,
-	// and resort the items if necessary.
-	void setSortOrder(U32 order);
+	LLFolderViewModelInterface* getViewModel() { return mViewModel; }
+
 	void setFilterPermMask(PermissionMask filter_perm_mask);
 	
 	typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
@@ -98,14 +98,7 @@ public:
 	void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
 	
 	// filter is never null
-	LLInventoryFilter* getFilter();
-	const std::string getFilterSubString(BOOL trim = FALSE);
-	U32 getFilterObjectTypes() const;
-	PermissionMask getFilterPermissions() const;
-	// *NOTE: use getFilter()->getShowFolderState();
-	//LLInventoryFilter::EFolderShow getShowFolderState();
-	U32 getSortOrder() const;
-	BOOL isFilterModified();
+	LLFolderViewFilter* getFilter();
 
 	bool getAllowMultiSelect() { return mAllowMultiSelect; }
 
@@ -113,19 +106,18 @@ public:
 	void closeAllFolders();
 	void openTopLevelFolders();
 
-	virtual void toggleOpen() {};
-	virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
 	virtual BOOL addFolder( LLFolderViewFolder* folder);
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
 	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+	virtual S32 getItemHeight();
 
 	void arrangeAll() { mArrangeGeneration++; }
 	S32 getArrangeGeneration() { return mArrangeGeneration; }
 
-	// applies filters to control visibility of inventory items
-	virtual void filter( LLInventoryFilter& filter);
+	// applies filters to control visibility of items
+	virtual void filter( LLFolderViewFilter& filter);
 
 	// get the last selected item
 	virtual LLFolderViewItem* getCurSelectedItem( void );
@@ -134,21 +126,15 @@ public:
 	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
 		BOOL take_keyboard_focus);
 
-	// Used by menu callbacks
-	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
-
-	// Called once a frame to update the selection if mSelectThisID has been set
-	void updateSelection();
-
 	// This method is used to toggle the selection of an item. Walks
 	// children, and keeps track of selected objects.
 	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
 
-	virtual std::set<LLUUID> getSelectionList() const;
+	virtual std::set<LLFolderViewItem*> getSelectionList() const;
 
 	// make sure if ancestor is selected, descendents are not
 	void sanitizeSelection();
-	void clearSelection();
+	virtual void clearSelection();
 	void addToSelectionList(LLFolderViewItem* item);
 	void removeFromSelectionList(LLFolderViewItem* item);
 
@@ -170,6 +156,7 @@ public:
 	void autoOpenItem(LLFolderViewFolder* item);
 	void closeAutoOpenedFolders();
 	BOOL autoOpenTest(LLFolderViewFolder* item);
+	BOOL isOpen() const { return TRUE; } // root folder always open
 
 	// copy & paste
 	virtual void	copy();
@@ -218,11 +205,6 @@ public:
 	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
 	bool getUseEllipses() { return mUseEllipses; }
 
-	void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
-	void removeItemID(const LLUUID& id);
-	LLFolderViewItem* getItemByID(const LLUUID& id);
-	LLFolderViewFolder* getFolderByID(const LLUUID& id);
-	
 	bool doToSelected(LLInventoryModel* model, const LLSD& userdata);
 	
 	void	doIdle();						// Real idle routine
@@ -267,6 +249,8 @@ protected:
 
 	void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response);
 
+	LLInventorySort& getSortFunction() { return mSortFunction; }
+
 protected:
 	LLHandle<LLView>					mPopupMenuHandle;
 	
@@ -297,7 +281,7 @@ protected:
 	LLFrameTimer					mAutoOpenTimer;
 	LLFrameTimer					mSearchTimer;
 	std::string						mSearchString;
-	LLInventoryFilter*				mFilter;
+	LLFolderViewFilter*				mFilter;
 	BOOL							mShowSelectionContext;
 	BOOL							mShowSingleSelection;
 	LLFrameTimer					mMultiSelectionFadeTimer;
@@ -307,14 +291,13 @@ protected:
 	signal_t						mReshapeSignal;
 	S32								mSignalSelectCallback;
 	S32								mMinWidth;
-	S32								mRunningHeight;
-	std::map<LLUUID, LLFolderViewItem*> mItemMap;
 	BOOL							mDragAndDropThisFrame;
 	
-	LLUUID							mSelectThisID; // if non null, select this item
-	
 	LLPanel*						mParentPanel;
 
+	LLInventorySort					mSortFunction;
+	LLFolderViewModelInterface*		mViewModel;
+
 	/**
 	 * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
 	 * NOTE: For now it uses only to cut LLFolderViewItem::mLabel text to be used for Landmarks in Places Panel.
@@ -334,9 +317,6 @@ public:
 
 };
 
-bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b);
-bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b);
-
 // Flags for buildContextMenu()
 const U32 SUPPRESS_OPEN_ITEM = 0x1;
 const U32 FIRST_SELECTED_ITEM = 0x2;
diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h
index aee31ca033..280708a39c 100644
--- a/indra/newview/llfoldervieweventlistener.h
+++ b/indra/newview/llfoldervieweventlistener.h
@@ -32,72 +32,263 @@
 #include "llpermissionsflags.h"
 #include "llpointer.h"
 #include "llwearabletype.h"
+#include "lltooldraganddrop.h"
 
+// These are grouping of inventory types.
+// Order matters when sorting system folders to the top.
+enum EInventorySortGroup
+{
+	SG_SYSTEM_FOLDER,
+	SG_TRASH_FOLDER,
+	SG_NORMAL_FOLDER,
+	SG_ITEM
+};
 
-class LLFolderViewItem;
-class LLFolderView;
 class LLFontGL;
 class LLInventoryModel;
 class LLMenuGL;
-class LLScrollContainer;
 class LLUIImage;
 class LLUUID;
+class LLFolderViewItem;
+class LLFolderViewFolder;
 
-// This is an abstract base class that users of the folderview classes
-// would use to catch the useful events emitted from the folder
-// views.
-class LLFolderViewEventListener
+class LLFolderViewFilter
 {
 public:
-	virtual ~LLFolderViewEventListener( void ) {}
+	LLFolderViewFilter() {}
+	virtual ~LLFolderViewFilter() {}
+
+	// +-------------------------------------------------------------------+
+	// + Execution And Results
+	// +-------------------------------------------------------------------+
+	virtual bool 				check(const LLFolderViewItem* item) = 0;
+	virtual bool				check(const LLInventoryItem* item) = 0;
+	virtual bool				checkFolder(const LLFolderViewFolder* folder) const = 0;
+	virtual bool				checkFolder(const LLUUID& folder_id) const = 0;
+
+	virtual void 				setEmptyLookupMessage(const std::string& message) = 0;
+	const virtual std::string&	getEmptyLookupMessage() const = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Status
+	// +-------------------------------------------------------------------+
+	virtual bool 				isActive() const = 0;
+	virtual bool 				isModified() const = 0;
+	virtual bool 				isModifiedAndClear() = 0;
+	virtual void 				clearModified() = 0;
+	virtual const std::string& 	getName() const = 0;
+	virtual const std::string& 	getFilterText() = 0;
+	//RN: this is public to allow system to externally force a global refilter
+	virtual void 				setModified(EFilterBehavior behavior = FILTER_RESTART) = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Count
+	// +-------------------------------------------------------------------+
+	virtual void 				setFilterCount(S32 count) = 0;
+	virtual S32 				getFilterCount() const = 0;
+	virtual void 				decrementFilterCount() = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Default
+	// +-------------------------------------------------------------------+
+	virtual BOOL 				isNotDefault() const = 0;
+	virtual void 				markDefault() = 0;
+	virtual void 				resetDefault() = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Generation
+	// +-------------------------------------------------------------------+
+	virtual S32 				getCurrentGeneration() const = 0;
+	virtual S32 				getFirstSuccessGeneration() const = 0;
+	virtual S32 				getFirstRequiredGeneration() const = 0;
+};
+
+struct LLFolderViewModelInterface
+{
+	virtual void requestSortAll() = 0;
+	virtual void requestSort(class LLFolderViewFolder*) = 0;
+
+	virtual void sort(class LLFolderViewFolder*) = 0;
+	virtual void filter(class LLFolderViewFolder*) = 0;
+};
+
+struct LLFolderViewModelCommon : public LLFolderViewModelInterface
+{
+	LLFolderViewModelCommon()
+	:	mTargetSortVersion(0)
+	{}
+
+	virtual void requestSortAll()
+	{
+		// sort everything
+		mTargetSortVersion++;
+	}
+
+	virtual void requestSort(class LLFolderViewFolder* folder)
+	{
+		folder->requestSort();
+	}
+	
+protected:
+	bool needsSort(class LLFolderViewModelItem* item)
+	{
+		return item->getSortVersion() < mTargetSortVersion;
+	}
+
+	S32 mTargetSortVersion;
+};
+
+
+// This is am abstract base class that users of the folderview classes
+// would use to bridge the folder view with the underlying data
+class LLFolderViewModelItem
+{
+public:
+	virtual ~LLFolderViewModelItem( void ) {};
+
+	virtual void update() {}	//called when drawing
 	virtual const std::string& getName() const = 0;
 	virtual const std::string& getDisplayName() const = 0;
-	virtual const LLUUID& getUUID() const = 0;
-	virtual time_t getCreationDate() const = 0;	// UTC seconds
-	virtual PermissionMask getPermissionMask() const = 0;
-	virtual LLFolderType::EType getPreferredType() const = 0;
+
 	virtual LLPointer<LLUIImage> getIcon() const = 0;
 	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
+
 	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
 	virtual std::string getLabelSuffix() const = 0;
+
 	virtual void openItem( void ) = 0;
 	virtual void closeItem( void ) = 0;
-	virtual void previewItem( void ) = 0;
 	virtual void selectItem(void) = 0;
-	virtual void showProperties(void) = 0;
+
 	virtual BOOL isItemRenameable() const = 0;
 	virtual BOOL renameItem(const std::string& new_name) = 0;
+
 	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder
+	virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
+
 	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed
-	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
 	virtual BOOL removeItem() = 0;
-	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
-	virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
+
 	virtual BOOL isItemCopyable() const = 0;
 	virtual BOOL copyToClipboard() const = 0;
 	virtual void cutToClipboard() = 0;
+
 	virtual BOOL isClipboardPasteable() const = 0;
 	virtual void pasteFromClipboard() = 0;
 	virtual void pasteLinkFromClipboard() = 0;
+
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
-	virtual BOOL isUpToDate() const = 0;
-	virtual BOOL hasChildren() const = 0;
-	virtual LLInventoryType::EType getInventoryType() const = 0;
-	virtual void performAction(LLInventoryModel* model, std::string action) = 0;
-	virtual LLWearableType::EType getWearableType() const = 0;
-	
+
 	// This method should be called when a drag begins. returns TRUE
 	// if the drag can begin, otherwise FALSE.
+	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
-	
+
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
 	// requested. Returns TRUE if a drop is possible/happened,
 	// otherwise FALSE.
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
-							EDragAndDropType cargo_type,
-							void* cargo_data,
-							std::string& tooltip_msg) = 0;
+		EDragAndDropType cargo_type,
+		void* cargo_data,
+		std::string& tooltip_msg) = 0;
+
+	virtual void requestSort() = 0;
+	virtual S32 getSortVersion() = 0;
+	virtual void setSortVersion(S32 version) = 0;
+};
+
+class LLFolderViewModelItemCommon : public LLFolderViewModelItem
+{
+public:
+	LLFolderViewModelItemCommon()
+	:	mSortVersion(-1)
+	{}
+
+	void requestSort() { mSortVersion = -1; }
+	S32 getSortVersion() { return mSortVersion; }
+	void setSortVersion(S32 version) { mSortVersion = VERSION;}
+
+protected:
+	S32 mSortVersion;
+};
+
+template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
+class LLFolderViewModel : public LLFolderViewModelCommon
+{
+protected:
+	LLFolderViewModel() {}
+	
+	typedef SORT_TYPE		SortType;
+	typedef ITEM_TYPE		ItemType;
+	typedef FOLDER_TYPE		FolderType;
+	typedef FILTER_TYPE		FilterType;
+	
+	virtual const SortType& getSorter() const 		 { return mSorter; }
+	virtual void setSorter(const SortType& type) 	 { mSorter = sorter; requestSortAll(); }
+	virtual FilterType& getFilter() const 			 { return mFilter; }
+	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
+
+public:
+
+	struct ViewModelCompare()
+	{
+		ViewModelCompare(const SortType& sorter)
+		:	mSorter(sorter)
+		{}
+		
+		int operator () (const LLFolderViewItem* a, const LLFolderViewItem* b)
+		{
+			return mSorter(static_cast<const ItemType*>(a->getListener()), static_cast<const ItemType*>(b->getListener()));
+		}
+
+		int operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b)
+		{
+			return mSorter(static_cast<const ItemType*>(a->getListener()), static_cast<const ItemType*>(b->getListener()));
+		}
+
+		const SortType& mSorter;
+	}
+
+	void sort(LLFolderViewFolder* folder)
+	{
+		if (needsSort(folder))
+		{
+			std::sort(folder->getFoldersBegin(), folder->getFoldersEnd(), ViewModelCompare(getSorter()));
+			std::sort(folder->getItemsBegin(), folder->getItemsEnd(), ViewModelCompare(getSorter()));
+			folder->getListener()->setSortVersion(mTargetSortVersion);
+			folder->requestArrange();
+		}
+	}
+
+	void filter(LLFolderViewFolder* folder)
+	{
+		FilterType& filter = getFilter();
+		for (std::list<LLFolderViewItem*>::iterator it = folder->getItemsBegin(), end_it = folder->getItemsEnd();
+			it != end_it;
+			++it)
+		{
+			LLFolderViewItem* child_item = *it;
+			child_item->setFiltered(filter(static_cast<ItemType*>(child_item->getListener())), filter.getCurrentGeneration())
+		}
+
+		for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
+			it != end_it;
+			++it)
+		{
+			LLFolderViewItem* child_folder = *it;
+			child_folder->setFiltered(filter(static_cast<ItemType*>(child_folder->getListener())), filter.getCurrentGeneration())
+		}
+	}
+
+protected:
+	SortType	mSorter;
+	FilterType	mFilter;
 };
 
+
+
+
+
 #endif
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 43d3675d17..f452ae25c3 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -29,6 +29,7 @@
 
 // viewer includes
 #include "llfolderview.h"		// Items depend extensively on LLFolderViews
+#include "llfolderview.h"
 #include "llfoldervieweventlistener.h"
 #include "llviewerfoldertype.h"
 #include "llinventorybridge.h"	// for LLItemBridge in LLInventorySort::operator()
@@ -121,15 +122,12 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mStringMatchOffset(std::string::npos),
 	mControlLabelRotation(0.f),
 	mDragAndDropTarget(FALSE),
-	mIsLoading(FALSE),
 	mLabel(p.name),
 	mRoot(p.root),
-	mCreationDate(p.creation_date),
 	mIcon(p.icon),
 	mIconOpen(p.icon_open),
 	mIconOverlay(p.icon_overlay),
 	mListener(p.listener),
-	mShowLoadStatus(false),
 	mIsMouseOverTitle(false)
 {
 }
@@ -218,14 +216,13 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
 // until we find out otherwise
 BOOL LLFolderViewItem::potentiallyVisible()
 {
-	// we haven't been checked against min required filter
-	// or we have and we passed
-	return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
+	return getFiltered() // we've passed the filter
+		||	getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration()); // or we don't know yet
 }
 
 BOOL LLFolderViewItem::getFiltered() 
 { 
-	return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); 
+	return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
 }
 
 BOOL LLFolderViewItem::getFiltered(S32 filter_generation) 
@@ -244,60 +241,47 @@ void LLFolderViewItem::setIcon(LLUIImagePtr icon)
 	mIcon = icon;
 }
 
-// refresh information from the listener
-void LLFolderViewItem::refreshFromListener()
+void LLFolderViewItem::refresh()
 {
-	if(mListener)
-	{
-		mLabel = mListener->getDisplayName();
-		LLFolderType::EType preferred_type = mListener->getPreferredType();
-
-		// *TODO: to be removed when database supports multi language. This is a
-		// temporary attempt to display the inventory folder in the user locale.
-		// mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
-		//		it uses the same way to find localized string
+	if(!getListener()) return;
 
-		// HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
-		// Translation of Accessories folder in Library inventory folder
-		bool accessories = false;
-		if(mLabel == std::string("Accessories"))
-		{
-			//To ensure that Accessories folder is in Library we have to check its parent folder.
-			//Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
-			LLInventoryCategory* cat = gInventory.getCategory(mListener->getUUID());
-			if(cat)
-			{
-				const LLUUID& parent_folder_id = cat->getParentUUID();
-				accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
-			}
-		}
+	mLabel = getListener()->getDisplayName();
+	LLFolderType::EType preferred_type = getListener()->getPreferredType();
 
-		//"Accessories" inventory category has folder type FT_NONE. So, this folder
-		//can not be detected as protected with LLFolderType::lookupIsProtectedType
-		if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
-		{
-			LLTrans::findString(mLabel, "InvFolder " + mLabel);
-		};
+	// *TODO: to be removed when database supports multi language. This is a
+	// temporary attempt to display the inventory folder in the user locale.
+	// mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
+	//		it uses the same way to find localized string
 
-		setToolTip(mLabel);
-		setIcon(mListener->getIcon());
-		time_t creation_date = mListener->getCreationDate();
-		if ((creation_date > 0) && (mCreationDate != creation_date))
-		{
-			setCreationDate(creation_date);
-			dirtyFilter();
-		}
-		if (mRoot->useLabelSuffix())
+	// HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
+	// Translation of Accessories folder in Library inventory folder
+	bool accessories = false;
+	if(mLabel == std::string("Accessories"))
+	{
+		//To ensure that Accessories folder is in Library we have to check its parent folder.
+		//Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
+		LLInventoryCategory* cat = gInventory.getCategory(getListener()->getUUID());
+		if(cat)
 		{
-			mLabelStyle = mListener->getLabelStyle();
-			mLabelSuffix = mListener->getLabelSuffix();
+			const LLUUID& parent_folder_id = cat->getParentUUID();
+			accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
 		}
 	}
-}
 
-void LLFolderViewItem::refresh()
-{
-	refreshFromListener();
+	//"Accessories" inventory category has folder type FT_NONE. So, this folder
+	//can not be detected as protected with LLFolderType::lookupIsProtectedType
+	if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
+	{
+		LLTrans::findString(mLabel, "InvFolder " + mLabel);
+	};
+
+	setToolTip(mLabel);
+	setIcon(getListener()->getIcon());
+	if (mRoot->useLabelSuffix())
+	{
+		mLabelStyle = getListener()->getLabelStyle();
+		mLabelSuffix = getListener()->getLabelSuffix();
+	}
 
 	std::string searchable_label(mLabel);
 	searchable_label.append(mLabelSuffix);
@@ -316,11 +300,7 @@ void LLFolderViewItem::refresh()
 	}
 
 	mLabelWidthDirty = true;
-}
-
-void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
-	functor(mListener);
+	dirtyFilter();
 }
 
 // This function is called when items are added or view filters change. It's
@@ -386,19 +366,14 @@ void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL
 	getRoot()->changeSelection(selection, selected);
 }
 
-std::set<LLUUID> LLFolderViewItem::getSelectionList() const
+std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const
 {
-	std::set<LLUUID> selection;
+	std::set<LLFolderViewItem*> selection;
 	return selection;
 }
 
-EInventorySortGroup LLFolderViewItem::getSortGroup()  const
-{ 
-	return SG_ITEM; 
-}
-
 // addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
+BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 {
 	if (!folder)
 	{
@@ -459,7 +434,7 @@ void LLFolderViewItem::filter( LLInventoryFilter& filter)
 	}
 
 	setFiltered(passed_filter, filter.getCurrentGeneration());
-	mStringMatchOffset = filter.getStringMatchOffset();
+	mStringMatchOffset = filter.getStringMatchOffset(this);
 	filter.decrementFilterCount();
 
 	if (getRoot()->getDebugFilters())
@@ -522,9 +497,9 @@ void LLFolderViewItem::selectItem(void)
 {
 	if (mIsSelected == FALSE)
 	{
-		if (mListener)
+		if (getListener())
 		{
-			mListener->selectItem();
+			getListener()->selectItem();
 		}
 		mIsSelected = TRUE;
 	}
@@ -532,9 +507,9 @@ void LLFolderViewItem::selectItem(void)
 
 BOOL LLFolderViewItem::isMovable()
 {
-	if( mListener )
+	if( getListener() )
 	{
-		return mListener->isItemMovable();
+		return getListener()->isItemMovable();
 	}
 	else
 	{
@@ -544,9 +519,9 @@ BOOL LLFolderViewItem::isMovable()
 
 BOOL LLFolderViewItem::isRemovable()
 {
-	if( mListener )
+	if( getListener() )
 	{
-		return mListener->isItemRemovable();
+		return getListener()->isItemRemovable();
 	}
 	else
 	{
@@ -572,9 +547,9 @@ BOOL LLFolderViewItem::remove()
 	{
 		return FALSE;
 	}
-	if(mListener)
+	if(getListener())
 	{
-		return mListener->removeItem();
+		return getListener()->removeItem();
 	}
 	return TRUE;
 }
@@ -582,25 +557,25 @@ BOOL LLFolderViewItem::remove()
 // Build an appropriate context menu for the item.
 void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
-	if(mListener)
+	if(getListener())
 	{
-		mListener->buildContextMenu(menu, flags);
+		getListener()->buildContextMenu(menu, flags);
 	}
 }
 
 void LLFolderViewItem::openItem( void )
 {
-	if( mListener )
+	if( getListener() )
 	{
-		mListener->openItem();
+		getListener()->openItem();
 	}
 }
 
 void LLFolderViewItem::preview( void )
 {
-	if (mListener)
+	if (getListener())
 	{
-		mListener->previewItem();
+		getListener()->previewItem();
 	}
 }
 
@@ -608,9 +583,9 @@ void LLFolderViewItem::rename(const std::string& new_name)
 {
 	if( !new_name.empty() )
 	{
-		if( mListener )
+		if( getListener() )
 		{
-			mListener->renameItem(new_name);
+			getListener()->renameItem(new_name);
 
 			if(mParentFolder)
 			{
@@ -633,11 +608,11 @@ LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)
 
 const std::string& LLFolderViewItem::getName( void ) const
 {
-	if(mListener)
+	if(getListener())
 	{
-		return mListener->getName();
+		return getListener()->getName();
 	}
-	return mLabel;
+	return z;
 }
 
 // LLView functionality
@@ -713,21 +688,19 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 
 				// *TODO: push this into listener and remove
 				// dependency on llagent
-				if (mListener
-					&& gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID()))
+				if (getListener())
 				{
-					src = LLToolDragAndDrop::SOURCE_AGENT;
+					src = getListener()->getDragSource();
 				}
-				else if (mListener
-					&& gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID()))
+				else
 				{
-					src = LLToolDragAndDrop::SOURCE_LIBRARY;
+					src = LLToolDragAndDrop::SOURCE_VIEWER;
 				}
 
 				can_drag = root->startDrag(src);
 				if (can_drag)
 				{
-					// if (mListener) mListener->startDrag();
+					// if (getListener()) getListener()->startDrag();
 					// RN: when starting drag and drop, clear out last auto-open
 					root->autoOpenTest(NULL);
 					root->setShowSelectionContext(TRUE);
@@ -816,9 +789,9 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 {
 	BOOL accepted = FALSE;
 	BOOL handled = FALSE;
-	if(mListener)
+	if(getListener())
 	{
-		accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+		accepted = getListener()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
 		handled = accepted;
 		if (accepted)
 		{
@@ -864,15 +837,14 @@ void LLFolderViewItem::draw()
 	const S32 FOCUS_LEFT = 1;
 	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
-	const BOOL in_inventory = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID());
-	const BOOL in_library = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID());
+	getListener()->update();
 
 	//--------------------------------------------------------------------------------//
 	// Draw open folder arrow
 	//
-	const bool up_to_date = mListener && mListener->isUpToDate();
+	const bool up_to_date = getListener() && getListener()->isUpToDate();
 	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
-										|| (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
+										|| (!up_to_date && getListener() && getListener()->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
 	if (possibly_has_children)
 	{
 		LLUIImage* arrow_image = default_params.folder_arrow_image;
@@ -1030,30 +1002,6 @@ void LLFolderViewItem::draw()
 					 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
 					 S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);
 
-	//--------------------------------------------------------------------------------//
-	// Draw "Loading..." text
-	//
-	bool root_is_loading = false;
-	if (in_inventory)
-	{
-		root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress(); 
-	}
-	if (in_library)
-	{
-		root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
-	}
-	if ((mIsLoading
-		&&	mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
-			||	(LLInventoryModelBackgroundFetch::instance().folderFetchActive()
-				&&	root_is_loading
-				&&	mShowLoadStatus))
-	{
-		std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";
-		font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor,
-						 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 
-						 S32_MAX, S32_MAX, &right_x, FALSE);
-	}
-
 	//--------------------------------------------------------------------------------//
 	// Draw label suffix
 	//
@@ -1067,28 +1015,29 @@ void LLFolderViewItem::draw()
 	//--------------------------------------------------------------------------------//
 	// Highlight string match
 	//
-	if (mStringMatchOffset != std::string::npos)
-	{
-		// don't draw backgrounds for zero-length strings
-		S32 filter_string_length = getRoot()->getFilterSubString().size();
-		if (filter_string_length > 0)
-		{
-			std::string combined_string = mLabel + mLabelSuffix;
-			S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
-			S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
-			S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
-			S32 top = getRect().getHeight() - TOP_PAD;
-		
-			LLUIImage* box_image = default_params.selection_image;
-			LLRect box_rect(left, top, right, bottom);
-			box_image->draw(box_rect, sFilterBGColor);
-			F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
-			F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-			font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
-							  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-							  filter_string_length, S32_MAX, &right_x, FALSE );
-		}
-	}
+	RN: expose interface for highlighting
+	//if (mStringMatchOffset != std::string::npos)
+	//{
+	//	// don't draw backgrounds for zero-length strings
+	//	S32 filter_string_length = getRoot()->getFilterSubString().size();
+	//	if (filter_string_length > 0)
+	//	{
+	//		std::string combined_string = mLabel + mLabelSuffix;
+	//		S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
+	//		S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
+	//		S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
+	//		S32 top = getRect().getHeight() - TOP_PAD;
+	//	
+	//		LLUIImage* box_image = default_params.selection_image;
+	//		LLRect box_rect(left, top, right, bottom);
+	//		box_image->draw(box_rect, sFilterBGColor);
+	//		F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
+	//		F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+	//		font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
+	//						  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+	//						  filter_string_length, S32_MAX, &right_x, FALSE );
+	//	}
+	//}
 }
 
 
@@ -1097,19 +1046,16 @@ void LLFolderViewItem::draw()
 ///----------------------------------------------------------------------------
 
 LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): 
-	LLFolderViewItem( p ),	// 0 = no create time
+	LLFolderViewItem( p ),
 	mIsOpen(FALSE),
 	mExpanderHighlighted(FALSE),
 	mCurHeight(0.f),
 	mTargetHeight(0.f),
 	mAutoOpenCountdown(0.f),
-	mSubtreeCreationDate(0),
-	mAmTrash(LLFolderViewFolder::UNKNOWN),
 	mLastArrangeGeneration( -1 ),
 	mLastCalculatedWidth(0),
 	mCompletedFilterGeneration(-1),
 	mMostFilteredDescendantGeneration(-1),
-	mNeedsSort(false),
 	mPassedFolderFilter(FALSE)
 {
 }
@@ -1130,32 +1076,30 @@ void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
 
 bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
 {
-	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
+	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
 }
 
 // addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
+BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
 {
 	if (!folder)
 	{
 		return FALSE;
 	}
 	mParentFolder = folder;
-	root->addItemID(getListener()->getUUID(), this);
 	return folder->addFolder(this);
 }
 
+static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
+
 // Finds width and height of this object and its children. Also
 // makes sure that this view and its children are the right size.
 S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 {
 	// sort before laying out contents
-	if (mNeedsSort)
-	{
-		mFolders.sort(mSortFunction);
-		mItems.sort(mSortFunction);
-		mNeedsSort = false;
-	}
+	getRoot->getViewModel()->sort(this);
+
+	LLFastTimer t2(FTM_ARRANGE);
 
 	mHasVisibleChildren = hasFilteredDescendants(filter_generation);
 
@@ -1166,7 +1110,6 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 	mCurHeight = llmax((F32)*height, mCurHeight);
 
 	// initialize running height value as height of single item in case we have no children
-	*height = getItemHeight();
 	F32 running_height = (F32)*height;
 	F32 target_height = (F32)*height;
 
@@ -1176,7 +1119,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 		// set last arrange generation first, in case children are animating
 		// and need to be arranged again
 		mLastArrangeGeneration = getRoot()->getArrangeGeneration();
-		if (mIsOpen)
+		if (isOpen())
 		{
 			// Add sizes of children
 			S32 parent_item_height = getRect().getHeight();
@@ -1252,7 +1195,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 	// animate current height towards target height
 	if (llabs(mCurHeight - mTargetHeight) > 1.f)
 	{
-		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
+		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
 
 		requestArrange();
 
@@ -1303,9 +1246,7 @@ BOOL LLFolderViewFolder::needsArrange()
 
 void LLFolderViewFolder::requestSort()
 {
-	mNeedsSort = true;
-	// whenever item order changes, we need to lay things out again
-	requestArrange();
+	getRoot()->getViewModel()->requestSort(this);
 }
 
 void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
@@ -1327,7 +1268,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 	// if failed to pass filter newer than must_pass_generation
 	// you will automatically fail this time, so we only
 	// check against items that have passed the filter
-	S32 must_pass_generation = filter.getMustPassGeneration();
+	S32 must_pass_generation = filter.getFirstRequiredGeneration();
 	
 	bool autoopen_folders = (filter.hasFilterString());
 
@@ -1380,11 +1321,11 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 
 	// when applying a filter, matching folders get their contents downloaded first
 	if (filter.isNotDefault()
-		&& getFiltered(filter.getMinRequiredGeneration())
-		&&	(mListener
-			&& !gInventory.isCategoryComplete(mListener->getUUID())))
+		&& getFiltered(filter.getFirstSuccessGeneration())
+		&&	(getListener()
+			&& !gInventory.isCategoryComplete(getListener()->getUUID())))
 	{
-		LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());
+		LLInventoryModelBackgroundFetch::instance().start(getListener()->getUUID());
 	}
 
 	// now query children
@@ -1405,7 +1346,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 		if (folder->getCompletedFilterGeneration() >= filter_generation)
 		{
 			// track latest generation to pass any child items
-			if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))
+			if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getFirstSuccessGeneration()))
 			{
 				mMostFilteredDescendantGeneration = filter_generation;
 				requestArrange();
@@ -1459,7 +1400,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 
 		item->filter( filter );
 
-		if (item->getFiltered(filter.getMinRequiredGeneration()))
+		if (item->getFiltered(filter.getFirstSuccessGeneration()))
 		{
 			mMostFilteredDescendantGeneration = filter_generation;
 			requestArrange();
@@ -1524,8 +1465,8 @@ void LLFolderViewFolder::dirtyFilter()
 
 BOOL LLFolderViewFolder::getFiltered() 
 { 
-	return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration()) 
-		&& LLFolderViewItem::getFiltered(); 
+	return getFilteredFolder(getRoot()->getFilter()->getFirstSuccessGeneration())
+		&& LLFolderViewItem::getFiltered();
 }
 
 BOOL LLFolderViewFolder::getFiltered(S32 filter_generation) 
@@ -1541,7 +1482,7 @@ BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)
 
 BOOL LLFolderViewFolder::hasFilteredDescendants()
 {
-	return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
+	return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
 }
 
 // Passes selection information on to children and record selection
@@ -1896,14 +1837,6 @@ void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
 
 void LLFolderViewFolder::destroyView()
 {
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		LLFolderViewItem* item = (*iit);
-		getRoot()->removeItemID(item->getListener()->getUUID());
-	}
-
 	std::for_each(mItems.begin(), mItems.end(), DeletePointer());
 	mItems.clear();
 
@@ -1913,8 +1846,6 @@ void LLFolderViewFolder::destroyView()
 		folderp->destroyView(); // removes entry from mFolders
 	}
 
-	//deleteAllChildren();
-
 	if (mParentFolder)
 	{
 		mParentFolder->removeView(this);
@@ -1976,103 +1907,14 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
 	dirtyFilter();
 	//because an item is going away regardless of filter status, force rearrange
 	requestArrange();
-	getRoot()->removeItemID(item->getListener()->getUUID());
 	removeChild(item);
 }
 
-bool LLFolderViewFolder::isTrash() const
-{
-	if (mAmTrash == LLFolderViewFolder::UNKNOWN)
-	{
-		mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH;
-	}
-	return mAmTrash == LLFolderViewFolder::TRASH;
-}
-
-void LLFolderViewFolder::sortBy(U32 order)
-{
-	if (!mSortFunction.updateSort(order))
-	{
-		// No changes.
-		return;
-	}
-
-	// Propagate this change to sub folders
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		(*fit)->sortBy(order);
-	}
-
-	// Don't sort the topmost folders (My Inventory and Library)
-	if (mListener->getUUID().notNull())
-	{
-		mFolders.sort(mSortFunction);
-		mItems.sort(mSortFunction);
-	}
-
-	if (order & LLInventoryFilter::SO_DATE)
-	{
-		time_t latest = 0;
-
-		if (!mItems.empty())
-		{
-			LLFolderViewItem* item = *(mItems.begin());
-			latest = item->getCreationDate();
-		}
-
-		if (!mFolders.empty())
-		{
-			LLFolderViewFolder* folder = *(mFolders.begin());
-			if (folder->getCreationDate() > latest)
-			{
-				latest = folder->getCreationDate();
-			}
-		}
-		mSubtreeCreationDate = latest;
-	}
-}
-
-void LLFolderViewFolder::setItemSortOrder(U32 ordering)
-{
-	if (mSortFunction.updateSort(ordering))
-	{
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			(*fit)->setItemSortOrder(ordering);
-		}
-
-		mFolders.sort(mSortFunction);
-		mItems.sort(mSortFunction);
-	}
-}
-
-EInventorySortGroup LLFolderViewFolder::getSortGroup() const
-{
-	if (isTrash())
-	{
-		return SG_TRASH_FOLDER;
-	}
-
-	if( mListener )
-	{
-		if(LLFolderType::lookupIsProtectedType(mListener->getPreferredType()))
-		{
-			return SG_SYSTEM_FOLDER;
-		}
-	}
-
-	return SG_NORMAL_FOLDER;
-}
-
 BOOL LLFolderViewFolder::isMovable()
 {
-	if( mListener )
+	if( getListener() )
 	{
-		if( !(mListener->isItemMovable()) )
+		if( !(getListener()->isItemMovable()) )
 		{
 			return FALSE;
 		}
@@ -2103,9 +1945,9 @@ BOOL LLFolderViewFolder::isMovable()
 
 BOOL LLFolderViewFolder::isRemovable()
 {
-	if( mListener )
+	if( getListener() )
 	{
-		if( !(mListener->isItemRemovable()) )
+		if( !(getListener()->isItemRemovable()) )
 		{
 			return FALSE;
 		}
@@ -2145,37 +1987,23 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	
 	item->dirtyFilter();
 
-	// Update the folder creation date if the folder has no creation date
-	bool setting_date = false;
-	const time_t item_creation_date = item->getCreationDate();
-	if ((item_creation_date > 0) && (mCreationDate == 0))
-	{
-		setCreationDate(item_creation_date);
-		setting_date = true;
-	}
-
 	// Handle sorting
 	requestArrange();
 	requestSort();
 
-	// Traverse parent folders and update creation date and resort, if necessary
-	LLFolderViewFolder* parentp = getParentFolder();
-	while (parentp)
-	{
-		// Update the parent folder creation date
-		if (setting_date && (parentp->mCreationDate == 0))
-		{
-			parentp->setCreationDate(item_creation_date);
-		}
+	FIXME: RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
+	//// Traverse parent folders and update creation date and resort, if necessary
+	//LLFolderViewFolder* parentp = this;
+	//while (parentp)
+	//{
+	//	if (parentp->mSortFunction.isByDate())
+	//	{
+	//		// parent folder doesn't have a time stamp yet, so get it from us
+	//		parentp->requestSort();
+	//	}
 
-		if (parentp->mSortFunction.isByDate())
-		{
-			// parent folder doesn't have a time stamp yet, so get it from us
-			parentp->requestSort();
-		}
-
-		parentp = parentp->getParentFolder();
-	}
+	//	parentp = parentp->getParentFolder();
+	//}
 
 	return TRUE;
 }
@@ -2192,12 +2020,15 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 	// rearrange all descendants too, as our indentation level might have changed
 	folder->requestArrange(TRUE);
 	requestSort();
-	LLFolderViewFolder* parentp = getParentFolder();
-	while (parentp && !parentp->mSortFunction.isByDate())
+	if (getRoot()->getSortFunction().isByDate())
 	{
-		// parent folder doesn't have a time stamp yet, so get it from us
-		parentp->requestSort();
-		parentp = parentp->getParentFolder();
+		LLFolderViewFolder* parentp = getParentFolder();
+		while(parentp)
+		{
+			// parent folder doesn't have a time stamp yet, so get it from us
+			parentp->requestSort();
+			parentp = parentp->getParentFolder();
+		}
 	}
 	return TRUE;
 }
@@ -2224,7 +2055,7 @@ void LLFolderViewFolder::requestArrange(BOOL include_descendants)
 
 void LLFolderViewFolder::toggleOpen()
 {
-	setOpen(!mIsOpen);
+	setOpen(!isOpen());
 }
 
 // Force a folder open or closed
@@ -2235,17 +2066,17 @@ void LLFolderViewFolder::setOpen(BOOL openitem)
 
 void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
 {
-	BOOL was_open = mIsOpen;
+	BOOL was_open = isOpen();
 	mIsOpen = openitem;
-	if (mListener)
+	if (getListener())
 	{
 		if(!was_open && openitem)
 		{
-			mListener->openItem();
+			getListener()->openItem();
 		}
 		else if(was_open && !openitem)
 		{
-			mListener->closeItem();
+			getListener()->closeItem();
 		}
 	}
 
@@ -2265,7 +2096,7 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r
 		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
 	}
 
-	if (was_open != mIsOpen)
+	if (was_open != isOpen())
 	{
 		requestArrange();
 	}
@@ -2334,23 +2165,6 @@ void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
 	}
 }
 
-void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
-	functor(mListener);
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		(*fit)->applyListenerFunctorRecursively(functor);
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		(*iit)->applyListenerFunctorRecursively(functor);
-	}
-}
-
 // LLView functionality
 BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
 										   BOOL drop,
@@ -2361,7 +2175,7 @@ BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
 {
 	BOOL handled = FALSE;
 
-	if (mIsOpen)
+	if (isOpen())
 	{
 		handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
 	}
@@ -2383,7 +2197,7 @@ BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
 													   EAcceptance* accept,
 													   std::string& tooltip_msg)
 {
-	BOOL accepted = mListener && mListener->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+	BOOL accepted = getListener() && getListener()->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
 	
 	if (accepted) 
 	{
@@ -2409,9 +2223,9 @@ BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
 	BOOL handled = FALSE;
 	// fetch contents of this folder, as context menu can depend on contents
 	// still, user would have to open context menu again to see the changes
-	gInventory.fetchDescendentsOf(mListener->getUUID());
+	gInventory.fetchDescendentsOf(getListener()->getUUID());
 
-	if( mIsOpen )
+	if( isOpen() )
 	{
 		handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
 	}
@@ -2441,7 +2255,7 @@ BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
 BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
 {
 	BOOL handled = FALSE;
-	if( mIsOpen )
+	if( isOpen() )
 	{
 		handled = childrenHandleMouseDown(x,y,mask) != NULL;
 	}
@@ -2475,7 +2289,7 @@ BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 	*/
 
 	BOOL handled = FALSE;
-	if( mIsOpen )
+	if( isOpen() )
 	{
 		handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
 	}
@@ -2503,7 +2317,7 @@ void LLFolderViewFolder::draw()
 	{
 		mControlLabelRotation = mAutoOpenCountdown * -90.f;
 	}
-	else if (mIsOpen)
+	else if (isOpen())
 	{
 		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
 	}
@@ -2512,31 +2326,10 @@ void LLFolderViewFolder::draw()
 		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
 	}
 
-	bool possibly_has_children = false;
-	bool up_to_date = mListener && mListener->isUpToDate();
-	if(!up_to_date
-		&& mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
-	{
-		possibly_has_children = true;
-	}
-
-
-	BOOL loading = (mIsOpen
-					&& possibly_has_children
-					&& !up_to_date );
-
-	if ( loading && !mIsLoading )
-	{
-		// Measure how long we've been in the loading state
-		mTimeSinceRequestStart.reset();
-	}
-
-	mIsLoading = loading;
-
 	LLFolderViewItem::draw();
 
 	// draw children if root folder, or any other folder that is open or animating to closed state
-	if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight ))
+	if( getRoot() == this || (isOpen() || mCurHeight != mTargetHeight ))
 	{
 		LLView::draw();
 	}
@@ -2544,20 +2337,14 @@ void LLFolderViewFolder::draw()
 	mExpanderHighlighted = FALSE;
 }
 
-time_t LLFolderViewFolder::getCreationDate() const
-{
-	return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
-}
-
-
 BOOL	LLFolderViewFolder::potentiallyVisible()
 {
 	// folder should be visible by it's own filter status
 	return LLFolderViewItem::potentiallyVisible() 	
 		// or one or more of its descendants have passed the minimum filter requirement
-		|| hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration())
+		|| hasFilteredDescendants()
 		// or not all of its descendants have been checked against minimum filter requirement
-		|| getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration(); 
+		|| getCompletedFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration();
 }
 
 // this does prefix traversal, as folders are listed above their contents
@@ -2771,41 +2558,27 @@ LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* it
 	return result;
 }
 
-
-bool LLInventorySort::updateSort(U32 order)
-{
-	if (order != mSortOrder)
-	{
-		mSortOrder = order;
-		mByDate = (order & LLInventoryFilter::SO_DATE);
-		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
-		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
-		return true;
-	}
-	return false;
-}
-
-bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b)
+bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b)
 {
 	// ignore sort order for landmarks in the Favorites folder.
 	// they should be always sorted as in Favorites bar. See EXT-719
 	if (a->getSortGroup() == SG_ITEM
 		&& b->getSortGroup() == SG_ITEM
-		&& a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK
-		&& b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+		&& a->getInventoryType() == LLInventoryType::IT_LANDMARK
+		&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 
 		static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
 
-		LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID();
-		LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID();
+		LLUUID a_uuid = a->getParentFolder()->getUUID();
+		LLUUID b_uuid = b->getParentFolder()->getUUID();
 
 		if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
 		{
 			// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
 			// or to LLInvFVBridge
-			LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a->getListener()))->getItem();
-			LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b->getListener()))->getItem();
+			LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a))->getItem();
+			LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b))->getItem();
 			if (!aitem || !bitem)
 				return false;
 			S32 a_sort = aitem->getSortField();
@@ -2852,8 +2625,6 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde
 	}
 	else
 	{
-		// BUG: This is very very slow.  The getCreationDate() is log n in number
-		// of inventory items.
 		time_t first_create = a->getCreationDate();
 		time_t second_create = b->getCreationDate();
 		if (first_create == second_create)
@@ -2866,3 +2637,4 @@ bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolde
 		}
 	}
 }
+
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 4e8dc2da16..317228f1ad 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -30,52 +30,13 @@
 #include "lldarray.h"  // *TODO: Eliminate, forward declare
 #include "lluiimage.h"
 
-class LLFontGL;
 class LLFolderView;
-class LLFolderViewEventListener;
+class LLFolderViewModelItemInventory;
 class LLFolderViewFolder;
 class LLFolderViewFunctor;
-class LLFolderViewItem;
-class LLFolderViewListenerFunctor;
 class LLInventoryFilter;
-class LLMenuGL;
-class LLUIImage;
 class LLViewerInventoryItem;
 
-// These are grouping of inventory types.
-// Order matters when sorting system folders to the top.
-enum EInventorySortGroup
-{ 
-	SG_SYSTEM_FOLDER, 
-	SG_TRASH_FOLDER, 
-	SG_NORMAL_FOLDER, 
-	SG_ITEM 
-};
-
-// *TODO: do we really need one sort object per folder?
-// can we just have one of these per LLFolderView ?
-class LLInventorySort
-{
-public:
-	LLInventorySort() 
-		: mSortOrder(0),
-		mByDate(false),
-		mSystemToTop(false),
-		mFoldersByName(false) { }
-
-	// Returns true if order has changed
-	bool updateSort(U32 order);
-	U32 getSort() { return mSortOrder; }
-	bool isByDate() { return mByDate; }
-
-	bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
-private:
-	U32  mSortOrder;
-	bool mByDate;
-	bool mSystemToTop;
-	bool mFoldersByName;
-};
-
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLFolderViewItem
 //
@@ -91,78 +52,71 @@ public:
 
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
 	{
-		Optional<LLUIImage*>					icon;
-		Optional<LLUIImage*>					icon_open;  // used for folders
-		Optional<LLUIImage*>					icon_overlay;  // for links
-		Optional<LLFolderView*>					root;
-		Mandatory<LLFolderViewEventListener*>	listener;
+		Optional<LLUIImage*>						icon,
+													icon_open,     // used for folders
+													icon_overlay,  // for links
+													folder_arrow_image,
+													selection_image;
+		Optional<LLFolderView*>						root;
+		Mandatory<LLFolderViewModelItemInventory*>	listener;
 
-		Optional<LLUIImage*>					folder_arrow_image;
-		Optional<S32>							folder_indentation; // pixels
-		Optional<LLUIImage*>					selection_image;
-		Optional<S32>							item_height; // pixels
-		Optional<S32>							item_top_pad; // pixels
+		Optional<S32>								folder_indentation, // pixels
+													item_height,
+													item_top_pad;
 
-		Optional<S32>							creation_date; //UTC seconds
+		Optional<time_t>							creation_date;
 
 		Params();
 	};
 
 	// layout constants
-	static const S32 LEFT_PAD = 5;
+	static const S32 LEFT_PAD 				 = 5;
 	// LEFT_INDENTATION is set via folder_indentation above
-	static const S32 ICON_PAD = 2;
-	static const S32 ICON_WIDTH = 16;
-	static const S32 TEXT_PAD = 1;
-	static const S32 TEXT_PAD_RIGHT = 4;
-	static const S32 ARROW_SIZE = 12;
+	static const S32 ICON_PAD 				 = 2;
+	static const S32 ICON_WIDTH 			 = 16;
+	static const S32 TEXT_PAD 				 = 1;
+	static const S32 TEXT_PAD_RIGHT 		 = 4;
+	static const S32 ARROW_SIZE 			 = 12;
 	static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
 	// animation parameters
 	static const F32 FOLDER_CLOSE_TIME_CONSTANT;
 	static const F32 FOLDER_OPEN_TIME_CONSTANT;
 
-	// Mostly for debugging printout purposes.
 	const std::string& getSearchableLabel() { return mSearchableLabel; }
 	
-	BOOL isLoading() const { return mIsLoading; }
-
 private:
 	BOOL						mIsSelected;
 
 protected:
 	friend class LLUICtrlFactory;
-	friend class LLFolderViewEventListener;
+	friend class LLFolderViewModelItem;
 
 	LLFolderViewItem(const Params& p);
 
-	std::string					mLabel;
-	std::string					mSearchableLabel;
-	S32							mLabelWidth;
-	bool						mLabelWidthDirty;
-	time_t						mCreationDate;
-	LLFolderViewFolder*			mParentFolder;
-	LLFolderViewEventListener*	mListener;
-	BOOL						mIsCurSelection;
-	BOOL						mSelectPending;
-	LLFontGL::StyleFlags		mLabelStyle;
-	std::string					mLabelSuffix;
-	LLUIImagePtr				mIcon;
-	std::string					mStatusText;
-	LLUIImagePtr				mIconOpen;
-	LLUIImagePtr				mIconOverlay;
-	BOOL						mHasVisibleChildren;
-	S32							mIndentation;
-	S32							mItemHeight;
-	BOOL						mPassedFilter;
-	S32							mLastFilterGeneration;
-	std::string::size_type		mStringMatchOffset;
-	F32							mControlLabelRotation;
-	LLFolderView*				mRoot;
-	BOOL						mDragAndDropTarget;
-	BOOL                        mIsLoading;
-	LLTimer                     mTimeSinceRequestStart;
-	bool						mShowLoadStatus;
-	bool						mIsMouseOverTitle;
+	std::string						mLabel;
+	std::string						mSearchableLabel;
+	S32								mLabelWidth;
+	bool							mLabelWidthDirty;
+	LLFolderViewFolder*				mParentFolder;
+	LLFolderViewModelItemInventory*	mListener;
+	BOOL							mIsCurSelection;
+	BOOL							mSelectPending;
+	LLFontGL::StyleFlags			mLabelStyle;
+	std::string						mLabelSuffix;
+	LLUIImagePtr					mIcon;
+	std::string						mStatusText;
+	LLUIImagePtr					mIconOpen;
+	LLUIImagePtr					mIconOverlay;
+	BOOL							mHasVisibleChildren;
+	S32								mIndentation;
+	S32								mItemHeight;
+	BOOL							mPassedFilter;
+	S32								mLastFilterGeneration;
+	std::string::size_type			mStringMatchOffset;
+	F32								mControlLabelRotation;
+	LLFolderView*					mRoot;
+	BOOL							mDragAndDropTarget;
+	bool							mIsMouseOverTitle;
 
 	// helper function to change the selection from the root.
 	void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
@@ -174,11 +128,11 @@ protected:
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
-	virtual void setCreationDate(time_t creation_date_utc)	{ mCreationDate = creation_date_utc; }
-
 public:
 	BOOL postBuild();
 
+	virtual void openItem( void );
+
 	// This function clears the currently selected item, and records
 	// the specified selected item appropriately for display and use
 	// in the UI. If open is TRUE, then folders are opened up along
@@ -198,9 +152,7 @@ public:
 
 	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
 	enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
-	virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
-
-	virtual EInventorySortGroup getSortGroup() const;
+	virtual BOOL addToFolder(LLFolderViewFolder* folder);
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
@@ -231,7 +183,7 @@ public:
 	virtual void selectItem();
 
 	// gets multiple-element selection
-	virtual std::set<LLUUID> getSelectionList() const;
+	virtual std::set<LLFolderViewItem*> getSelectionList() const;
 
 	// Returns true is this object and all of its children can be removed (deleted by user)
 	virtual BOOL isRemovable();
@@ -252,15 +204,13 @@ public:
 
 	BOOL hasVisibleChildren() { return mHasVisibleChildren; }
 
-	void setShowLoadStatus(bool status) { mShowLoadStatus = status; }
-
 	// Call through to the viewed object and return true if it can be
 	// removed. Returns true if it's removed.
 	//virtual BOOL removeRecursively(BOOL single_item);
 	BOOL remove();
 
 	// Build an appropriate context menu for the item.	Flags unused.
-	void buildContextMenu(LLMenuGL& menu, U32 flags);
+	void buildContextMenu(class LLMenuGL& menu, U32 flags);
 
 	// This method returns the actual name of the thing being
 	// viewed. This method will ask the viewed object itself.
@@ -273,8 +223,6 @@ public:
 	// contents possible before the entire view has been constructed.
 	const std::string& getLabel() const { return mLabel; }
 
-	// Used for sorting, like getLabel() above.
-	virtual time_t getCreationDate() const { return mCreationDate; }
 
 	LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
 	const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
@@ -282,22 +230,15 @@ public:
 	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
 	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
 
-	const LLFolderViewEventListener* getListener( void ) const { return mListener; }
-	LLFolderViewEventListener* getListener( void ) { return mListener; }
+	const LLFolderViewModelItemInventory* getListener( void ) const { return mListener; }
+	LLFolderViewModelItemInventory* getListener( void ) { return mListener; }
 	
-	// Gets the inventory item if it exists (null otherwise)
-	LLViewerInventoryItem * getInventoryItem(void);
-
 	// just rename the object.
 	void rename(const std::string& new_name);
 
-	// open
-	virtual void openItem( void );
-	virtual void preview(void);
 
 	// Show children (unfortunate that this is called "open")
 	virtual void setOpen(BOOL open = TRUE) {};
-
 	virtual BOOL isOpen() const { return FALSE; }
 
 	virtual LLFolderView*	getRoot();
@@ -314,11 +255,8 @@ public:
 	void setIcon(LLUIImagePtr icon);
 
 	// refresh information from the object being viewed.
-	void refreshFromListener();
 	virtual void refresh();
 
-	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
-
 	// LLView functionality
 	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
 	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
@@ -338,14 +276,40 @@ public:
 		EAcceptance* accept,
 		std::string& tooltip_msg);
 
+	// Gets the inventory item if it exists (null otherwise)
+	LLViewerInventoryItem * getInventoryItem(void);
+	// open
+	virtual void preview(void);
+
 private:
 	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
 };
 
+class LLInventorySort
+{
+public:
+	LLInventorySort(U32 order)
+	:	mSortOrder(0),
+		mByDate(false),
+		mSystemToTop(false),
+		mFoldersByName(false)
+	{
+		mSortOrder = order;
+		mByDate = (order & LLInventoryFilter::SO_DATE);
+		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+	}
 
-// function used for sorting.
-typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
+	bool isByDate() { return mByDate; }
+	U32 getSortOrder() { return mSortOrder; }
 
+	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b);
+private:
+	U32  mSortOrder;
+	bool mByDate;
+	bool mSystemToTop;
+	bool mFoldersByName;
+};
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLFolderViewFolder
@@ -362,10 +326,6 @@ protected:
 	friend class LLUICtrlFactory;
 
 public:
-	typedef enum e_trash
-	{
-		UNKNOWN, TRASH, NOT_TRASH
-	} ETrash;
 
 	typedef std::list<LLFolderViewItem*> items_t;
 	typedef std::list<LLFolderViewFolder*> folders_t;
@@ -373,15 +333,12 @@ public:
 protected:
 	items_t mItems;
 	folders_t mFolders;
-	LLInventorySort	mSortFunction;
 
 	BOOL		mIsOpen;
 	BOOL		mExpanderHighlighted;
 	F32			mCurHeight;
 	F32			mTargetHeight;
 	F32			mAutoOpenCountdown;
-	time_t		mSubtreeCreationDate;
-	mutable ETrash mAmTrash;
 	S32			mLastArrangeGeneration;
 	S32			mLastCalculatedWidth;
 	S32			mCompletedFilterGeneration;
@@ -407,17 +364,13 @@ public:
 	LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE  );
 
 	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-	virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+	virtual BOOL addToFolder(LLFolderViewFolder* folder);
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
 	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
 
 	BOOL needsArrange();
-	void requestSort();
-
-	// Returns the sort group (system, trash, folder) for this folder.
-	virtual EInventorySortGroup getSortGroup() const;
 
 	virtual void	setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
 	virtual S32		getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
@@ -478,15 +431,11 @@ public:
 
 	// extractItem() removes the specified item from the folder, but
 	// doesn't delete it.
-	void extractItem( LLFolderViewItem* item );
+	virtual void extractItem( LLFolderViewItem* item );
 
 	// This function is called by a child that needs to be resorted.
 	void resort(LLFolderViewItem* item);
 
-	void setItemSortOrder(U32 ordering);
-	void sortBy(U32);
-	//BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
-
 	void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
 
 	// folders can be opened. This will usually be called by internal
@@ -500,6 +449,8 @@ public:
 	// don't rearrange child folder contents unless explicitly requested
 	virtual void requestArrange(BOOL include_descendants = FALSE);
 
+	virtual void requestSort();
+
 	// internal method which doesn't update the entire view. This
 	// method was written because the list iterators destroy the state
 	// of other iterations, thus, we can't arrange while iterating
@@ -518,7 +469,6 @@ public:
 		std::string& tooltip_msg);
 
 	void applyFunctorRecursively(LLFolderViewFunctor& functor);
-	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
 
 	// Just apply this functor to the folder's immediate children.
 	void applyFunctorToChildren(LLFolderViewFunctor& functor);
@@ -544,32 +494,18 @@ public:
 									   std::string& tooltip_msg);
 	virtual void draw();
 
-	time_t getCreationDate() const;
-	bool isTrash() const;
 
-	folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
-	folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
+	folders_t::iterator getFoldersBegin() const { return mFolders.begin(); }
+	folders_t::iterator getFoldersEnd() const { return mFolders.end(); }
 	folders_t::size_type getFoldersCount() const { return mFolders.size(); }
 
-	items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
-	items_t::const_iterator getItemsEnd() const { return mItems.end(); }
+	items_t::iterator getItemsBegin() const { return mItems.begin(); }
+	items_t::iterator getItemsEnd() const { return mItems.end(); }
 	items_t::size_type getItemsCount() const { return mItems.size(); }
+
 	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
 	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);
 };
 
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewListenerFunctor
-//
-// This simple abstract base class can be used to applied to all
-// listeners in a hierarchy.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewListenerFunctor
-{
-public:
-	virtual ~LLFolderViewListenerFunctor() {}
-	virtual void operator()(LLFolderViewEventListener* listener) = 0;
-};
 
 #endif  // LLFOLDERVIEWITEM_H
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 11401d6c68..a64ddd185d 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -47,13 +47,13 @@ static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "All";
 // helper functions
 
 // NOTE: For now Friends & All folders are created as protected folders of the LLFolderType::FT_CALLINGCARD type.
-// So, their names will be processed in the LLFolderViewItem::refreshFromListener() to be localized
+// So, their names will be processed in the LLFolderViewItem::refresh() to be localized
 // using "InvFolder LABEL_NAME" as LLTrans::findString argument.
 
 // We must use in this file their hard-coded names to ensure found them on different locales. EXT-5829.
 // These hard-coded names will be stored in InventoryItems but shown localized in FolderViewItems
 
-// If hack in the LLFolderViewItem::refreshFromListener() to localize protected folder is removed
+// If hack in the LLFolderViewItem::refresh() to localize protected folder is removed
 // or these folders are not protected these names should be localized in another place/way.
 inline const std::string get_friend_folder_name()
 {
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 2de2b17373..47444d3762 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -115,10 +115,10 @@ void teleport_via_landmark(const LLUUID& asset_id);
 static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
 static bool check_category(LLInventoryModel* model,
 						   const LLUUID& cat_id,
-						   LLFolderView* active_folder_view,
+						   LLInventoryPanel* active_panel,
 						   LLInventoryFilter* filter);
 static bool check_item(const LLUUID& item_id,
-					   LLFolderView* active_folder_view,
+					   LLInventoryPanel* active_panel,
 					   LLInventoryFilter* filter);
 
 // Helper functions
@@ -191,9 +191,24 @@ LLFolderType::EType LLInvFVBridge::getPreferredType() const
 // Folders don't have creation dates.
 time_t LLInvFVBridge::getCreationDate() const
 {
-	return 0;
+	LLInventoryObject* objectp = getInventoryObject();
+	if (objectp)
+	{
+		return objectp->getCreationDate();
+	}
+	return (time_t)0;
+}
+
+void LLInvFVBridge::setCreationDate(time_t creation_date_utc)
+{
+	LLInventoryObject* objectp = getInventoryObject();
+	if (objectp)
+	{
+		objectp->setCreationDate(creation_date_utc);
+	}
 }
 
+
 // Can be destroyed (or moved to trash)
 BOOL LLInvFVBridge::isItemRemovable() const
 {
@@ -233,7 +248,7 @@ void LLInvFVBridge::showProperties()
 	*/
 }
 
-void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
 {
 	// Deactivate gestures when moving them into Trash
 	LLInvFVBridge* bridge;
@@ -242,11 +257,11 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
 	LLViewerInventoryCategory* cat = NULL;
 	LLInventoryModel::cat_array_t	descendent_categories;
 	LLInventoryModel::item_array_t	descendent_items;
-	S32 count = batch.count();
+	S32 count = batch.size();
 	S32 i,j;
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
 		if (item)
@@ -259,7 +274,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
 	}
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
 		if (cat)
@@ -277,7 +292,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
 	removeBatchNoCheck(batch);
 }
 
-void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void  LLInvFVBridge::removeBatchNoCheck(std::vector<LLFolderViewModelItem*>&  batch)
 {
 	// this method moves a bunch of items and folders to the trash. As
 	// per design guidelines for the inventory model, the message is
@@ -293,14 +308,14 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
 	uuid_vec_t move_ids;
 	LLInventoryModel::update_map_t update;
 	bool start_new_message = true;
-	S32 count = batch.count();
+	S32 count = batch.size();
 	S32 i;
 
 	// first, hide any 'preview' floaters that correspond to the items
 	// being deleted.
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
 		if(item)
@@ -313,7 +328,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
 
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
 		if(item)
@@ -809,6 +824,12 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const
 	return panel ? panel->getModel() : NULL;
 }
 
+LLInventoryFilter* getInventoryFilter() const
+{
+	LLInventoryPanel* panel = mInventoryPanel.get();
+	return panel ? panel->getFilter() : NULL;
+}
+
 BOOL LLInvFVBridge::isItemInTrash() const
 {
 	LLInventoryModel* model = getInventoryModel();
@@ -1183,7 +1204,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 
 		if (can_list)
 		{
-			LLFolderViewFolder * object_folderp = mRoot->getFolderByID(object_id);
+			LLFolderViewFolder * object_folderp =   mInventoryPanel->getFolderByID(object_id);
 			if (object_folderp)
 			{
 				can_list = !object_folderp->isLoading();
@@ -1194,7 +1215,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 		{
 			// Get outbox id
 			const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
-			LLFolderViewItem * outbox_itemp = mRoot->getItemByID(outbox_id);
+			LLFolderViewItem * outbox_itemp =   mInventoryPanel->getItemByID(outbox_id);
 
 			if (outbox_itemp)
 			{
@@ -1216,6 +1237,21 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 #endif
 }
 
+LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const
+{
+	if (gInventory.isObjectDescendentOf(getUUID(),   gInventory.getRootFolderID()))
+	{
+		return LLToolDragAndDrop::SOURCE_AGENT;
+	}
+	else if (gInventory.isObjectDescendentOf(getUUID(),   gInventory.getLibraryRootFolderID()))
+	{
+		return LLToolDragAndDrop::SOURCE_LIBRARY;
+	}
+
+	return SOURCE_VIEWER;
+}
+
+
 
 // +=================================================+
 // |        InventoryFVBridgeBuilder                 |
@@ -1296,7 +1332,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryItem* itemp = model->getItem(mUUID);
 		if (!itemp) return;
 
-		LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID());
+		LLFolderViewItem* folder_view_itemp =   mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
 		if (!folder_view_itemp) return;
 
 		folder_view_itemp->getListener()->pasteFromClipboard();
@@ -1308,7 +1344,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryItem* itemp = model->getItem(mUUID);
 		if (!itemp) return;
 
-		LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID());
+		LLFolderViewItem* folder_view_itemp =   mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
 		if (!folder_view_itemp) return;
 
 		folder_view_itemp->getListener()->pasteLinkFromClipboard();
@@ -1718,6 +1754,60 @@ BOOL LLFolderBridge::isItemMovable() const
 void LLFolderBridge::selectItem()
 {
 }
+std::string& LLFolderBridge::getDisplayName() const
+{
+	return mDisplayName;
+}
+
+
+void LLFolderBridge::update()
+{
+	bool possibly_has_children = false;
+	bool up_to_date = isUpToDate();
+	if(!up_to_date && hasChildren()) // we know we have children but  haven't  fetched them (doesn't obey filter)
+	{
+		possibly_has_children = true;
+	}
+
+	BOOL loading = (possibly_has_children
+		&& !up_to_date );
+
+	if (loading != mIsLoading)
+	{
+		if ( loading && !mIsLoading )
+		{
+			// Measure how long we've been in the loading state
+			mTimeSinceRequestStart.reset();
+		}
+
+		const BOOL in_inventory = gInventory.isObjectDescendentOf(getUUID(),   gInventory.getRootFolderID());
+		const BOOL in_library = gInventory.isObjectDescendentOf(getUUID(),   gInventory.getLibraryRootFolderID());
+
+		bool root_is_loading = false;
+		if (in_inventory)
+		{
+			root_is_loading =   LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();
+		}
+		if (in_library)
+		{
+			root_is_loading =   LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
+		}
+		if ((mIsLoading
+				&&	mTimeSinceRequestStart.getElapsedTimeF32() >=   gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
+			||	(LLInventoryModelBackgroundFetch::instance().folderFetchActive()
+				&&	root_is_loading))
+		{
+			mDisplayName = LLInvFVBridge::getDisplayName() + " ( " +   LLTrans::getString("LoadingData") + " ) ";
+			mIsLoading = true;
+		}
+		else
+		{
+			mDisplayName = LLInvFVBridge::getDisplayName();
+			mIsLoading = false;
+		}
+	}
+}
+
 
 
 // Iterate through a folder's children to determine if
@@ -1746,7 +1836,7 @@ BOOL LLFolderBridge::isItemRemovable() const
 	}
 
 	LLInventoryPanel* panel = mInventoryPanel.get();
-	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
+	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ?   panel->getItemByID(mUUID) : NULL);
 	if (folderp)
 	{
 		LLIsItemRemovable folder_test;
@@ -1969,7 +2059,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 	LLInventoryPanel* destination_panel = mInventoryPanel.get();
 	if (!destination_panel) return false;
 
-	LLInventoryFilter* filter = destination_panel->getFilter();
+	LLInventoryFilter* filter = getInventoryFilter();
 	if (!filter) return false;
 
 	const LLUUID &cat_id = inv_cat->getUUID();
@@ -2188,7 +2278,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 				{
 					// Check whether the folder being dragged from active inventory panel
 					// passes the filter of the destination panel.
-					is_movable = check_category(model, cat_id, active_folder_view, filter);
+					is_movable = check_category(model, cat_id, active_panel, filter);
 				}
 			}
 		}
@@ -2621,7 +2711,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 {
 	if ("open" == action)
 	{
-		LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mRoot->getItemByID(mUUID));
+		LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder   *>(mInventoryPanel.get()->getItemByID(mUUID));
 		if (f)
 		{
 			f->setOpen(TRUE);
@@ -2890,7 +2980,7 @@ void LLFolderBridge::pasteFromClipboard()
 
 		if (move_is_into_outbox)
 		{
-			LLFolderViewItem * outbox_itemp = mRoot->getItemByID(mUUID);
+			LLFolderViewItem * outbox_itemp =   mInventoryPanel.get()->getItemByID(mUUID);
 
 			if (outbox_itemp)
 			{
@@ -3055,7 +3145,7 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
 	return ((item_array.count() > 0) ? TRUE : FALSE );
 }
 
-void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
+void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items, menuentry_vec_t& disabled_items)
 {
 	LLInventoryModel* model = getInventoryModel();
 	llassert(model != NULL);
@@ -3066,30 +3156,30 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
 	if (lost_and_found_id == mUUID)
 	{
 		// This is the lost+found folder.
-		mItems.push_back(std::string("Empty Lost And Found"));
+		items.push_back(std::string("Empty Lost And Found"));
 
-		mDisabledItems.push_back(std::string("New Folder"));
-		mDisabledItems.push_back(std::string("New Script"));
-		mDisabledItems.push_back(std::string("New Note"));
-		mDisabledItems.push_back(std::string("New Gesture"));
-		mDisabledItems.push_back(std::string("New Clothes"));
-		mDisabledItems.push_back(std::string("New Body Parts"));
-	}
+		disabled_items.push_back(std::string("New Folder"));
+		disabled_items.push_back(std::string("New Script"));
+		disabled_items.push_back(std::string("New Note"));
+		disabled_items.push_back(std::string("New Gesture"));
+		disabled_items.push_back(std::string("New Clothes"));
+		disabled_items.push_back(std::string("New Body Parts"));
+        }
 
 	if(trash_id == mUUID)
 	{
 		// This is the trash.
-		mItems.push_back(std::string("Empty Trash"));
+		items.push_back(std::string("Empty Trash"));
 	}
 	else if(isItemInTrash())
 	{
 		// This is a folder in the trash.
-		mItems.clear(); // clear any items that used to exist
-		addTrashContextMenuOptions(mItems, mDisabledItems);
+		items.clear(); // clear any items that used to exist
+		addTrashContextMenuOptions(items, disabled_items);
 	}
 	else if(isOutboxFolder())
 	{
-		addOutboxContextMenuOptions(flags, mItems, mDisabledItems);
+		addOutboxContextMenuOptions(flags, items, disabled_items);
 	}
 	else if(isAgentInventory()) // do not allow creating in library
 	{
@@ -3103,40 +3193,40 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
 				// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
 				if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
 				{
-					mItems.push_back(std::string("New Folder"));
+					items.push_back(std::string("New Folder"));
 				}
 
-				mItems.push_back(std::string("New Script"));
-				mItems.push_back(std::string("New Note"));
-				mItems.push_back(std::string("New Gesture"));
-				mItems.push_back(std::string("New Clothes"));
-				mItems.push_back(std::string("New Body Parts"));
+				items.push_back(std::string("New Script"));
+				items.push_back(std::string("New Note"));
+				items.push_back(std::string("New Gesture"));
+				items.push_back(std::string("New Clothes"));
+				items.push_back(std::string("New Body Parts"));
 			}
 #if SUPPORT_ENSEMBLES
 			// Changing folder types is an unfinished unsupported feature
 			// and can lead to unexpected behavior if enabled.
-			mItems.push_back(std::string("Change Type"));
+			items.push_back(std::string("Change Type"));
 			const LLViewerInventoryCategory *cat = getCategory();
 			if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
 			{
-				mDisabledItems.push_back(std::string("Change Type"));
+				disabled_items.push_back(std::string("Change Type"));
 			}
 #endif
-			getClipboardEntries(false, mItems, mDisabledItems, flags);
+			getClipboardEntries(false, items, disabled_items, flags);
 		}
 		else
 		{
 			// Want some but not all of the items from getClipboardEntries for outfits.
 			if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT))
 			{
-				mItems.push_back(std::string("Rename"));
+				items.push_back(std::string("Rename"));
 
-				addDeleteContextMenuOptions(mItems, mDisabledItems);
+				addDeleteContextMenuOptions(items, disabled_items);
 				// EXT-4030: disallow deletion of currently worn outfit
 				const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
 				if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory()))
 				{
-					mDisabledItems.push_back(std::string("Delete"));
+					disabled_items.push_back(std::string("Delete"));
 				}
 			}
 		}
@@ -3165,20 +3255,41 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
 	// Preemptively disable system folder removal if more than one item selected.
 	if ((flags & FIRST_SELECTED_ITEM) == 0)
 	{
-		mDisabledItems.push_back(std::string("Delete System Folder"));
+		disabled_items.push_back(std::string("Delete System Folder"));
 	}
 
 	if (!isOutboxFolder())
 	{
-		mItems.push_back(std::string("Share"));
+		items.push_back(std::string("Share"));
 		if (!canShare())
 		{
-			mDisabledItems.push_back(std::string("Share"));
+			disabled_items.push_back(std::string("Share"));
+		}
+	}
+	// Add menu items that are dependent on the contents of the folder.
+	LLViewerInventoryCategory* category = (LLViewerInventoryCategory *)   model->getCategory(mUUID);
+	if (category)
+	{
+		uuid_vec_t folders;
+		folders.push_back(category->getUUID());
+
+		sSelf = getHandle();
+		LLRightClickInventoryFetchDescendentsObserver* fetch = new   LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
+		fetch->startFetch();
+		inc_busy_count();
+		if (fetch->isFinished())
+		{
+			buildContextMenuFolderOptions(flags, items, disabled_items);
+		}
+		else
+		{
+			// it's all on its way - add an observer, and the inventory will call   done for us when everything is here.
+			gInventory.addObserver(fetch);
 		}
 	}
 }
 
-void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
+void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t& items, menuentry_vec_t& disabled_items)
 {
 	// Build folder specific options back up
 	LLInventoryModel* model = getInventoryModel();
@@ -3205,21 +3316,21 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
 		LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
 		if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
 		{
-			mItems.push_back(std::string("Calling Card Separator"));
-			mItems.push_back(std::string("Conference Chat Folder"));
-			mItems.push_back(std::string("IM All Contacts In Folder"));
+			items.push_back(std::string("Calling Card Separator"));
+			items.push_back(std::string("Conference Chat Folder"));
+			items.push_back(std::string("IM All Contacts In Folder"));
 		}
 	}
 
 	if (!isItemRemovable())
 	{
-		mDisabledItems.push_back(std::string("Delete"));
+		disabled_items.push_back(std::string("Delete"));
 	}
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
 	if (LLFolderType::lookupIsProtectedType(type))
 	{
-		mItems.push_back(std::string("Delete System Folder"));
+		items.push_back(std::string("Delete System Folder"));
 	}
 #endif
 
@@ -3234,7 +3345,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
 		checkFolderForContentsOfType(model, is_object) ||
 		checkFolderForContentsOfType(model, is_gesture) )
 	{
-		mItems.push_back(std::string("Folder Wearables Separator"));
+		items.push_back(std::string("Folder Wearables Separator"));
 
 		// Only enable add/replace outfit for non-system folders.
 		if (!is_system_folder)
@@ -3242,25 +3353,25 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
 			// Adding an outfit onto another (versus replacing) doesn't make sense.
 			if (type != LLFolderType::FT_OUTFIT)
 			{
-				mItems.push_back(std::string("Add To Outfit"));
+				items.push_back(std::string("Add To Outfit"));
 			}
 
-			mItems.push_back(std::string("Replace Outfit"));
+			items.push_back(std::string("Replace Outfit"));
 		}
 		if (is_ensemble)
 		{
-			mItems.push_back(std::string("Wear As Ensemble"));
+			items.push_back(std::string("Wear As Ensemble"));
 		}
-		mItems.push_back(std::string("Remove From Outfit"));
+		items.push_back(std::string("Remove From Outfit"));
 		if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
 		{
-			mDisabledItems.push_back(std::string("Remove From Outfit"));
+			disabled_items.push_back(std::string("Remove From Outfit"));
 		}
 		if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
 		{
-			mDisabledItems.push_back(std::string("Replace Outfit"));
+			disabled_items.push_back(std::string("Replace Outfit"));
 		}
-		mItems.push_back(std::string("Outfit Separator"));
+		items.push_back(std::string("Outfit Separator"));
 	}
 }
 
@@ -3269,39 +3380,16 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
 	sSelf.markDead();
 
-	mItems.clear();
-	mDisabledItems.clear();
+	menuentry_vec_t items;
+	menuentry_vec_t disabled_items;
 
 	lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
 
 	LLInventoryModel* model = getInventoryModel();
 	if(!model) return;
 
-	buildContextMenuBaseOptions(flags);
-
-	// Add menu items that are dependent on the contents of the folder.
-	LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
-	if (category)
-	{
-		uuid_vec_t folders;
-		folders.push_back(category->getUUID());
-
-		sSelf = getHandle();
-		LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders, FALSE);
-		fetch->startFetch();
-		inc_busy_count();
-		if (fetch->isFinished())
-		{
-			buildContextMenuFolderOptions(flags);
-		}
-		else
-		{
-			// it's all on its way - add an observer, and the inventory will call done for us when everything is here.
-			gInventory.addObserver(fetch);
-		}
-	}
-
-	hide_context_entries(menu, mItems, mDisabledItems);
+	buildContextMenuBaseOptions(flags, items, disabled_items);
+        hide_context_entries(menu, items, disabled_items);
 
 	// Reposition the menu, in case we're adding items to an existing menu.
 	menu.needsArrange();
@@ -3402,9 +3490,7 @@ void LLFolderBridge::createNewCategory(void* user_data)
 {
 	LLFolderBridge* bridge = (LLFolderBridge*)user_data;
 	if(!bridge) return;
-	LLInventoryPanel* panel = bridge->mInventoryPanel.get();
-	if (!panel) return;
-	LLInventoryModel* model = panel->getModel();
+	LLInventoryModel* model = bridge->getInventoryModel();
 	if(!model) return;
 	LLUUID id;
 	id = model->createNewCategory(bridge->getUUID(),
@@ -3482,6 +3568,24 @@ void LLFolderBridge::createNewEyes(void* user_data)
 	LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_EYES);
 }
 
+EInventorySortGroup LLFolderBridge::getSortGroup() const
+{
+	LLFolderType::EType preferred_type = getPreferredType();
+
+	if (preferred_type == LLFolderType::FT_TRASH)
+	{
+		return SG_TRASH_FOLDER;
+	}
+
+	if(LLFolderType::lookupIsProtectedType(preferred_type))
+	{
+		return SG_SYSTEM_FOLDER;
+	}
+
+	return SG_NORMAL_FOLDER;
+}
+
+
 // static
 void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::EType type)
 {
@@ -3635,7 +3739,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 	LLInventoryPanel* destination_panel = mInventoryPanel.get();
 	if (!destination_panel) return false;
 
-	LLInventoryFilter* filter = destination_panel->getFilter();
+	LLInventoryFilter* filter = getInventoryFilter();
 	if (!filter) return false;
 
 	const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
@@ -3752,10 +3856,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 		// passes the filter of the destination panel.
 		if (accept && active_panel)
 		{
-			LLFolderView* active_folder_view = active_panel->getRootFolder();
-			if (!active_folder_view) return false;
-
-			LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID());
+			LLFolderViewItem* fv_item =   active_panel->getItemByID(inv_item->getUUID());
 			if (!fv_item) return false;
 
 			accept = filter->check(fv_item);
@@ -3770,10 +3871,12 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			}
 			// If an item is being dragged between windows, unselect everything in the active window 
 			// so that we don't follow the selection to its new location (which is very annoying).
+                        // RN: a better solution would be to deselect automatically when an   item is moved
+			// and then select any item that is dropped only in the panel that it   is dropped in
 			if (active_panel && (destination_panel != active_panel))
-				{
-					active_panel->unSelectAll();
-				}
+			{
+				active_panel->unSelectAll();
+			}
 
 			//--------------------------------------------------------------------------------
 			// Destination folder logic
@@ -3975,10 +4078,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			// passes the filter of the destination panel.
 			if (accept && active_panel)
 			{
-				LLFolderView* active_folder_view = active_panel->getRootFolder();
-				if (!active_folder_view) return false;
-
-				LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID());
+				LLFolderViewItem* fv_item =   active_panel->getItemByID(inv_item->getUUID());
 				if (!fv_item) return false;
 
 				accept = filter->check(fv_item);
@@ -4021,10 +4121,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 // static
 bool check_category(LLInventoryModel* model,
 					const LLUUID& cat_id,
-					LLFolderView* active_folder_view,
+					LLInventoryPanel* active_panel,
 					LLInventoryFilter* filter)
 {
-	if (!model || !active_folder_view || !filter)
+	if (!model || !active_panel || !filter)
 		return false;
 
 	if (!filter->checkFolder(cat_id))
@@ -4044,13 +4144,13 @@ bool check_category(LLInventoryModel* model,
 		// Empty folder should be checked as any other folder view item.
 		// If we are filtering by date the folder should not pass because
 		// it doesn't have its own creation date. See LLInvFVBridge::getCreationDate().
-		return check_item(cat_id, active_folder_view, filter);
+		return check_item(cat_id, active_panel, filter);
 	}
 
 	for (S32 i = 0; i < num_descendent_categories; ++i)
 	{
 		LLInventoryCategory* category = descendent_categories[i];
-		if(!check_category(model, category->getUUID(), active_folder_view, filter))
+		if(!check_category(model, category->getUUID(), active_panel, filter))
 		{
 			return false;
 		}
@@ -4059,7 +4159,7 @@ bool check_category(LLInventoryModel* model,
 	for (S32 i = 0; i < num_descendent_items; ++i)
 	{
 		LLViewerInventoryItem* item = descendent_items[i];
-		if(!check_item(item->getUUID(), active_folder_view, filter))
+		if(!check_item(item->getUUID(), active_panel, filter))
 		{
 			return false;
 		}
@@ -4070,12 +4170,12 @@ bool check_category(LLInventoryModel* model,
 
 // static
 bool check_item(const LLUUID& item_id,
-				LLFolderView* active_folder_view,
+				LLInventoryPanel* active_panel,
 				LLInventoryFilter* filter)
 {
-	if (!active_folder_view || !filter) return false;
+	if (!active_panel || !filter) return false;
 
-	LLFolderViewItem* fv_item = active_folder_view->getItemByID(item_id);
+	LLFolderViewItem* fv_item = active_panel->getItemByID(item_id);
 	if (!fv_item) return false;
 
 	return filter->check(fv_item);
@@ -4404,7 +4504,7 @@ LLCallingCardBridge::~LLCallingCardBridge()
 void LLCallingCardBridge::refreshFolderViewItem()
 {
 	LLInventoryPanel* panel = mInventoryPanel.get();
-	LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL;
+	LLFolderViewItem* itemp = panel ? panel->getItemByID(mUUID) : NULL;
 	if (itemp)
 	{
 		itemp->refresh();
@@ -5897,7 +5997,8 @@ void LLLinkFolderBridge::gotoItem()
 	const LLUUID &cat_uuid = getFolderID();
 	if (!cat_uuid.isNull())
 	{
-		if (LLFolderViewItem *base_folder = mRoot->getItemByID(cat_uuid))
+                LLFolderViewItem *base_folder =   mInventoryPanel.get()->getItemByID(cat_uuid)
+		if (base_folder)
 		{
 			if (LLInventoryModel* model = getInventoryModel())
 			{
@@ -6235,9 +6336,8 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
 /************************************************************************/
 void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
-	LLFolderBridge::buildContextMenu(menu, flags);
-
-	menuentry_vec_t disabled_items, items = getMenuItems();
+	menuentry_vec_t disabled_items, items;
+        buildContextMenuOptions(flags, items, disabled_items);
 
 	items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end());
 
@@ -6286,5 +6386,4 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(
 
 }
 
-
 // EOF
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 3b4f845f54..e9c54dc4bc 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -32,6 +32,7 @@
 #include "llfoldervieweventlistener.h"
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
+#include "llinventorypanel.h"
 #include "llviewercontrol.h"
 #include "llwearable.h"
 
@@ -41,7 +42,7 @@ class LLInventoryModel;
 class LLMenuGL;
 class LLCallingCardObserver;
 class LLViewerJointAttachment;
-
+class LLFolderView;
 
 typedef std::vector<std::string> menuentry_vec_t;
 
@@ -56,7 +57,7 @@ typedef std::vector<std::string> menuentry_vec_t;
 // functionality a bit. (except for folders, you can create those
 // manually...)
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInvFVBridge : public LLFolderViewEventListener
+class LLInvFVBridge : public LLFolderViewModelItemInventory
 {
 public:
 	// This method is a convenience function which creates the correct
@@ -83,13 +84,14 @@ public:
 	virtual void restoreToWorld() {}
 
 	//--------------------------------------------------------------------
-	// Inherited LLFolderViewEventListener functions
+	// Inherited LLFolderViewModelItemInventory functions
 	//--------------------------------------------------------------------
 	virtual const std::string& getName() const;
 	virtual const std::string& getDisplayName() const;
 	virtual PermissionMask getPermissionMask() const;
 	virtual LLFolderType::EType getPreferredType() const;
 	virtual time_t getCreationDate() const;
+        virtual void setCreationDate(time_t creation_date_utc);
 	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
 	virtual void openItem() {}
@@ -103,8 +105,8 @@ public:
 	virtual BOOL isItemInTrash() const;
 	virtual BOOL isLink() const;
 	//virtual BOOL removeItem() = 0;
-	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
-	virtual void move(LLFolderViewEventListener* new_parent_bridge) {}
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
+	virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
 	virtual BOOL isItemCopyable() const { return FALSE; }
 	virtual BOOL copyToClipboard() const { return FALSE; }
 	virtual void cutToClipboard();
@@ -115,6 +117,7 @@ public:
 	void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items, 
 							 menuentry_vec_t &disabled_items, U32 flags);
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+        virtual LLToolDragAndDrop::ESource getDragSource() const;
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
@@ -122,6 +125,7 @@ public:
 							std::string& tooltip_msg) { return FALSE; }
 	virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
 	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+        EInventorySortGroup getSortGroup()  const { return SG_ITEM; }
 
 	//--------------------------------------------------------------------
 	// Convenience functions for adding various common menu options.
@@ -140,14 +144,15 @@ protected:
 
 	LLInventoryObject* getInventoryObject() const;
 	LLInventoryModel* getInventoryModel() const;
-	
+	LLInventoryFilter* getInventoryFilter() const;
+
 	BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?
 	BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory?
 
-	BOOL isAgentInventory() const; // false if lost or in the inventory library
-	BOOL isCOFFolder() const; // true if COF or descendent of
-	BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
-	BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox
+	BOOL isAgentInventory() const;  // false if lost or in the inventory library
+	BOOL isCOFFolder() const;       // true if COF or descendant of
+	BOOL isInboxFolder() const;     // true if COF or descendant of   marketplace inbox
+	BOOL isOutboxFolder() const;    // true if COF or descendant of   marketplace outbox
 	BOOL isOutboxFolderDirectParent() const;
 	const LLUUID getOutboxFolder() const;
 
@@ -160,13 +165,14 @@ protected:
 									 LLViewerInventoryCategory* item,
 									 const LLUUID& new_parent,
 									 BOOL restamp);
-	void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
+	void removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch);
 protected:
-	LLHandle<LLInventoryPanel> mInventoryPanel;
-	LLFolderView* mRoot;
-	const LLUUID mUUID;	// item id
-	LLInventoryType::EType mInvType;
-	BOOL mIsLink;
+	LLHandle<LLInventoryPanel>	mInventoryPanel;
+	LLFolderView*				mRoot;
+	const LLUUID				mUUID;	// item id
+	LLInventoryType::EType		mInvType;
+	bool						mIsLink;
+	LLTimer						mTimeSinceRequestStart;
 	void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
 };
 
@@ -233,15 +239,18 @@ class LLFolderBridge : public LLInvFVBridge
 public:
 	LLFolderBridge(LLInventoryPanel* inventory, 
 				   LLFolderView* root,
-				   const LLUUID& uuid) :
-		LLInvFVBridge(inventory, root, uuid),
+				   const LLUUID& uuid) 
+        :       LLInvFVBridge(inventory, root, uuid),
 		mCallingCards(FALSE),
-		mWearables(FALSE)
+		mWearables(FALSE),
+		mIsLoading(false)
 	{}
 		
 	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);
 	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg);
 
+        const std::string& getDisplayName() const;
+
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual void openItem();
 	virtual void closeItem();
@@ -277,14 +286,17 @@ public:
 	virtual BOOL isClipboardPasteableAsLink() const;
 	virtual BOOL copyToClipboard() const;
 	
+	EInventorySortGroup getSortGroup()  const;
+	virtual void update();
+
 	static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
 
 	LLViewerInventoryCategory* getCategory() const;
 	LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
 
 protected:
-	void buildContextMenuBaseOptions(U32 flags);
-	void buildContextMenuFolderOptions(U32 flags);
+	void buildContextMenuOptions(U32 flags, menuentry_vec_t& items,   menuentry_vec_t& disabled_items);
+	void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items,   menuentry_vec_t& disabled_items);
 
 	//--------------------------------------------------------------------
 	// Menu callbacks
@@ -310,8 +322,6 @@ protected:
 	void modifyOutfit(BOOL append);
 	void determineFolderType();
 
-	menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items
-
 	void dropToFavorites(LLInventoryItem* inv_item);
 	void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
 
@@ -323,11 +333,12 @@ public:
 	static void staticFolderOptionsMenu();
 
 private:
-	BOOL				mCallingCards;
-	BOOL				mWearables;
-	menuentry_vec_t		mItems;
-	menuentry_vec_t		mDisabledItems;
-	LLRootHandle<LLFolderBridge> mHandle;
+	bool							mCallingCards;
+	bool							mWearables;
+	bool							mIsLoading;
+	LLTimer							mTimeSinceRequestStart;
+	std::string						mDisplayName;
+	LLRootHandle<LLFolderBridge>	mHandle;
 };
 
 class LLTextureBridge : public LLItemBridge
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 5496c273f2..9c84be5eac 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -41,39 +41,39 @@
 // linden library includes
 #include "lltrans.h"
 
-LLInventoryFilter::FilterOps::FilterOps() :
-	mFilterObjectTypes(0xffffffffffffffffULL),
-	mFilterCategoryTypes(0xffffffffffffffffULL),
-	mFilterWearableTypes(0xffffffffffffffffULL),
-	mMinDate(time_min()),
-	mMaxDate(time_max()),
-	mHoursAgo(0),
-	mShowFolderState(SHOW_NON_EMPTY_FOLDERS),
-	mPermissions(PERM_NONE),
-	mFilterTypes(FILTERTYPE_OBJECT),
-	mFilterUUID(LLUUID::null),
-	mFilterLinks(FILTERLINK_INCLUDE_LINKS)
+LLInventoryFilter::FilterOps::FilterOps(const Params& p)
+:	mFilterObjectTypes(p.object_types),
+	mFilterCategoryTypes(p.category_types),
+	mFilterWearableTypes(p.wearable_types),
+	mMinDate(p.date_range.min_date),
+	mMaxDate(p.date_range.max_date),
+	mHoursAgo(p.hours_ago),
+	mShowFolderState(p.show_folder_state),
+	mPermissions(p.permissions),
+	mFilterTypes(p.types),
+	mFilterUUID(p.uuid),
+	mFilterLinks(p.links)
 {
 }
 
 ///----------------------------------------------------------------------------
 /// Class LLInventoryFilter
 ///----------------------------------------------------------------------------
-LLInventoryFilter::LLInventoryFilter(const std::string& name)
+LLInventoryFilter::LLInventoryFilter(const std::string& name, const   Params& p)
 :	mName(name),
 	mModified(FALSE),
 	mNeedTextRebuild(TRUE),
-	mEmptyLookupMessage("InventoryNoMatchingItems")
+	mEmptyLookupMessage("InventoryNoMatchingItems"),
+        mFilterOps(p.filter_ops)
 {
-	mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
+	mOrder = p.sort_order; // This gets overridden by a pref immediately
 
-	mSubStringMatchOffset = 0;
-	mFilterSubString.clear();
-	mFilterGeneration = 0;
-	mMustPassGeneration = S32_MAX;
-	mMinRequiredGeneration = 0;
+	mFilterSubString(p.substring);
+	mLastSuccessGeneration = 0;
+	mLastFailGeneration = S32_MAX;
+	getFirstSuccessGeneration = 0;
 	mFilterCount = 0;
-	mNextFilterGeneration = mFilterGeneration + 1;
+	mNextFilterGeneration = mLastSuccessGeneration + 1;
 
 	mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
 	mFilterBehavior = FILTER_NONE;
@@ -95,7 +95,7 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
 		return TRUE;
 	}
 
-	mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
+	std::string::size_type string_offset = mFilterSubString.size() ?   item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
 
 	const BOOL passed_filtertype = checkAgainstFilterType(item);
 	const BOOL passed_permissions = checkAgainstPermissions(item);
@@ -103,20 +103,20 @@ BOOL LLInventoryFilter::check(const LLFolderViewItem* item)
 	const BOOL passed = (passed_filtertype &&
 						 passed_permissions &&
 						 passed_filterlink &&
-						 (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
+						 (mFilterSubString.size() == 0 || string_offset !=  std::string::npos));
 
 	return passed;
 }
 
 bool LLInventoryFilter::check(const LLInventoryItem* item)
 {
-	mSubStringMatchOffset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
+	std::string::size_type string_offset = mFilterSubString.size() ?   item->getName().find(mFilterSubString) : std::string::npos;
 
 	const bool passed_filtertype = checkAgainstFilterType(item);
 	const bool passed_permissions = checkAgainstPermissions(item);
 	const bool passed = (passed_filtertype &&
 						 passed_permissions &&
-						 (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
+						 (mFilterSubString.size() == 0 || string_offset !=  std::string::npos));
 
 	return passed;
 }
@@ -130,7 +130,7 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
 		return false;
 	}
 
-	const LLFolderViewEventListener* listener = folder->getListener();
+	const LLFolderViewModelItemInventory* listener = folder->getListener();
 	if (!listener)
 	{
 		llwarns << "Folder view event listener not found." << llendl;
@@ -168,7 +168,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 
 BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
 {
-	const LLFolderViewEventListener* listener = item->getListener();
+	const LLFolderViewModelItemInventory* listener = item->getListener();
 	if (!listener) return FALSE;
 
 	LLInventoryType::EType object_type = listener->getInventoryType();
@@ -311,7 +311,7 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) cons
 
 BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
 {
-	const LLFolderViewEventListener* listener = item->getListener();
+	const LLFolderViewModelItemInventory* listener = item->getListener();
 	if (!listener) return FALSE;
 
 	PermissionMask perm = listener->getPermissionMask();
@@ -339,7 +339,7 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) con
 
 BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
 {
-	const LLFolderViewEventListener* listener = item->getListener();
+	const LLFolderViewModelItemInventory* listener = item->getListener();
 	if (!listener) return TRUE;
 
 	const LLUUID object_id = listener->getUUID();
@@ -359,9 +359,9 @@ const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
 	return mFilterSubString;
 }
 
-std::string::size_type LLInventoryFilter::getStringMatchOffset() const
+std::string::size_type   LLInventoryFilter::getStringMatchOffset(LLFolderViewItem* item) const
 {
-	return mSubStringMatchOffset;
+	return mFilterSubString.size() ? item->getName().find(mFilterSubString)   : std::string::npos;
 }
 
 // has user modified default filter params?
@@ -685,7 +685,7 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)
 {
 	mModified = TRUE;
 	mNeedTextRebuild = TRUE;
-	mFilterGeneration = mNextFilterGeneration++;
+	mLastSuccessGeneration = mNextFilterGeneration++;
 
 	if (mFilterBehavior == FILTER_NONE)
 	{
@@ -704,17 +704,17 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)
 		switch(mFilterBehavior)
 		{
 			case FILTER_RESTART:
-				mMustPassGeneration = mFilterGeneration;
-				mMinRequiredGeneration = mFilterGeneration;
+				mLastFailGeneration = mLastSuccessGeneration;
+				mFirstSuccessGeneration = mLastSuccessGeneration;
 				break;
 			case FILTER_LESS_RESTRICTIVE:
-				mMustPassGeneration = mFilterGeneration;
+				mLastFailGeneration = mLastSuccessGeneration;
 				break;
 			case FILTER_MORE_RESTRICTIVE:
-				mMinRequiredGeneration = mFilterGeneration;
+				mFirstSuccessGeneration = mLastSuccessGeneration;
 				// must have passed either current filter generation (meaningless, as it hasn't been run yet)
 				// or some older generation, so keep the value
-				mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
+				mLastFailGeneration = llmin(mLastFailGeneration,  mLastSuccessGeneration);
 				break;
 			default:
 				llerrs << "Bad filter behavior specified" << llendl;
@@ -930,60 +930,34 @@ const std::string& LLInventoryFilter::getFilterText()
 	return mFilterText;
 }
 
-void LLInventoryFilter::toLLSD(LLSD& data) const
+void LLInventoryFilter::toParams(Params& params) const
 {
-	data["filter_types"] = (LLSD::Integer)getFilterObjectTypes();
-	data["min_date"] = (LLSD::Integer)getMinDate();
-	data["max_date"] = (LLSD::Integer)getMaxDate();
-	data["hours_ago"] = (LLSD::Integer)getHoursAgo();
-	data["show_folder_state"] = (LLSD::Integer)getShowFolderState();
-	data["permissions"] = (LLSD::Integer)getFilterPermissions();
-	data["substring"] = (LLSD::String)getFilterSubString();
-	data["sort_order"] = (LLSD::Integer)getSortOrder();
-	data["since_logoff"] = (LLSD::Boolean)isSinceLogoff();
+	params.filter_ops.types = getFilterObjectTypes();
+	params.filter_ops.date_range.min_date = getMinDate();
+	params.filter_ops.date_range.max_date = getMaxDate();
+	params.filter_ops.hours_ago = getHoursAgo();
+	params.filter_ops.show_folder_state = getShowFolderState();
+	params.filter_ops.permissions = getFilterPermissions();
+	params.substring = getFilterSubString();
+	params.sort_order = getSortOrder();
+	params.since_logoff = isSinceLogoff();
 }
 
-void LLInventoryFilter::fromLLSD(LLSD& data)
+void LLInventoryFilter::fromParams(const Params& data)
 {
-	if(data.has("filter_types"))
+	if (!params.validateBlock())
 	{
-		setFilterObjectTypes((U32)data["filter_types"].asInteger());
+		return;
 	}
 
-	if(data.has("min_date") && data.has("max_date"))
-	{
-		setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger());
-	}
-
-	if(data.has("hours_ago"))
-	{
-		setHoursAgo((U32)data["hours_ago"].asInteger());
-	}
-
-	if(data.has("show_folder_state"))
-	{
-		setShowFolderState((EFolderShow)data["show_folder_state"].asInteger());
-	}
-
-	if(data.has("permissions"))
-	{
-		setFilterPermissions((PermissionMask)data["permissions"].asInteger());
-	}
-
-	if(data.has("substring"))
-	{
-		setFilterSubString(std::string(data["substring"].asString()));
-	}
-
-	if(data.has("sort_order"))
-	{
-		setSortOrder((U32)data["sort_order"].asInteger());
-	}
-
-	if(data.has("since_logoff"))
-	{
-		setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
-	}
+	setFilterObjectTypes(params.filter_ops.types);
+	setDateRange(params.filter_ops.date_range.min_date,   params.filter_ops.date_range.max_date);
+	setHoursAgo(params.filter_ops.hours_ago);
+	setShowFolderState(params.filter_ops.show_folder_state);
+	setFilterPermissions(params.filter_ops.permissions);
+	setFilterSubString(params.substring);
+	setSortOrder(params.sort_order);
+	setDateRangeLastLogoff(params.since_logoff);
 }
 
 U64 LLInventoryFilter::getFilterObjectTypes() const
@@ -1052,15 +1026,15 @@ void LLInventoryFilter::decrementFilterCount()
 
 S32 LLInventoryFilter::getCurrentGeneration() const 
 { 
-	return mFilterGeneration; 
+	return mLastSuccessGeneration;
 }
-S32 LLInventoryFilter::getMinRequiredGeneration() const 
+S32 LLInventoryFilter::getFirstSuccessGeneration() const
 { 
-	return mMinRequiredGeneration; 
+	return mFirstSuccessGeneration; 
 }
-S32 LLInventoryFilter::getMustPassGeneration() const 
+S32 LLInventoryFilter::getFirstRequiredGeneration() const
 { 
-	return mMustPassGeneration; 
+	return mLastFailGeneration; 
 }
 
 void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
@@ -1068,9 +1042,13 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
 	mEmptyLookupMessage = message;
 }
 
+RN: turn this into a param
 const std::string& LLInventoryFilter::getEmptyLookupMessage() const
 {
-	return mEmptyLookupMessage;
+	LLStringUtil::format_map_t args;
+	args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
+
+	return LLTrans::getString(mEmptyLookupMessage, args);
 
 }
 
@@ -1080,3 +1058,26 @@ bool LLInventoryFilter::areDateLimitsSet()
 			|| mFilterOps.mMaxDate != time_max()
 			|| mFilterOps.mHoursAgo != 0;
 }
+
+LLInventoryFilter& LLInventoryFilter::operator=( const  LLInventoryFilter&  other )
+{
+	fromParams(other.toParams());
+}
+
+
+bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool   emit_errors /*= true*/ )
+{
+	bool valid = LLInitParam::Block<DateRange>::validateBlock(emit_errors);
+	if (valid)
+	{
+		if (max_date() < min_date())
+		{
+			if (emit_errors)
+			{
+				llwarns << "max_date should be greater or equal to min_date" <<   llendl;
+			}
+			valid = false;
+		}
+	}
+	return valid;
+}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 6be2acfaa3..7f33be3878 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -34,7 +34,7 @@ class LLFolderViewItem;
 class LLFolderViewFolder;
 class LLInventoryItem;
 
-class LLInventoryFilter
+class LLInventoryFilter : public LLFolderViewFilter
 {
 public:
 	enum EFolderShow
@@ -53,13 +53,13 @@ public:
 	};
 
 	enum EFilterType	{
-		FILTERTYPE_NONE = 0,
-		FILTERTYPE_OBJECT = 0x1 << 0,	// normal default search-by-object-type
-		FILTERTYPE_CATEGORY = 0x1 << 1,	// search by folder type
-		FILTERTYPE_UUID	= 0x1 << 2,		// find the object with UUID and any links to it
-		FILTERTYPE_DATE = 0x1 << 3,		// search by date range
-		FILTERTYPE_WEARABLE = 0x1 << 4,	// search by wearable type
-		FILTERTYPE_EMPTYFOLDERS = 0x1 << 5	// pass if folder is not a system folder to be hidden if empty
+		FILTERTYPE_NONE 		= 0,
+		FILTERTYPE_OBJECT 		= 0x1 << 0,		// normal default search-by-object-type
+		FILTERTYPE_CATEGORY 	= 0x1 << 1,		// search by folder type
+		FILTERTYPE_UUID			= 0x1 << 2,		// find the object with UUID and any   links to it
+		FILTERTYPE_DATE 		= 0x1 << 3,		// search by date range
+		FILTERTYPE_WEARABLE 	= 0x1 << 4,		// search by wearable type
+		FILTERTYPE_EMPTYFOLDERS = 0x1 << 5		// pass if folder is not a system   folder to be hidden if
 	};
 
 	enum EFilterLink
@@ -71,13 +71,87 @@ public:
 
 	enum ESortOrderType
 	{
-		SO_NAME = 0,						// Sort inventory by name
-		SO_DATE = 0x1,						// Sort inventory by date
-		SO_FOLDERS_BY_NAME = 0x1 << 1,		// Force folder sort by name
-		SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2	// Force system folders to be on top
+		SO_NAME 				 = 0,			// Sort inventory by name
+		SO_DATE 				 = 0x1,			// Sort inventory by date
+		SO_FOLDERS_BY_NAME 		 = 0x1 << 1,	// Force folder sort by name
+		SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2		// Force system folders to be on   top
 	};
 
-	LLInventoryFilter(const std::string& name);
+	struct FilterOps
+	{
+		struct DateRange : public LLInitParam::Block<DateRange>
+		{
+			Optional<time_t> min_date;
+			Optional<time_t> max_date;
+
+			DateRange()
+			:	min_date("min_date", time_min()),
+				max_date("max_date", time_max())
+			{}
+
+			bool validateBlock(bool emit_errors = true);
+		};
+
+		struct Params : public LLInitParam::Block<Params>
+		{
+			Optional<U32>				types;
+			Optional<U64>				object_types,
+										wearable_types,
+										category_types;
+			Optional<EFilterLink>		links;
+			Optional<LLUUID>			uuid;
+			Optional<DateRange>			date_range;
+			Optional<S32>				hours_ago;
+			Optional<EFolderShow>		show_folder_state;
+			Optional<PermissionMask>	permissions;
+
+			Params()
+			:	types("filter_types", FILTERTYPE_OBJECT),
+				object_types("object_types", 0xffffFFFFffffFFFFULL),
+				wearable_types("wearable_types", 0xffffFFFFffffFFFFULL),
+				category_types("category_types", 0xffffFFFFffffFFFFULL),
+				links("links", FILTERLINK_INCLUDE_LINKS),
+				uuid("uuid"),
+				date_range("date_range"),
+				hours_ago("hours_ago", 0),
+				show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS),
+				permissions("permissions", PERM_NONE)
+			{}
+		};
+
+		FilterOps(const Params& = Params());
+
+		U32 			mFilterTypes;
+
+		U64				mFilterObjectTypes;   // For _OBJECT
+		U64				mFilterWearableTypes;
+		U64				mFilterCategoryTypes; // For _CATEGORY
+		LLUUID      	mFilterUUID; 		  // for UUID
+
+		time_t			mMinDate;
+		time_t			mMaxDate;
+		U32				mHoursAgo;
+		EFolderShow		mShowFolderState;
+		PermissionMask	mPermissions;
+		U64				mFilterLinks;
+	};
+							
+	struct Params : public LLInitParam::Block<Params>
+	{
+		Optional<FilterOps::Params>	filter_ops;
+		Optional<std::string>		substring;
+		Optional<U32>				sort_order;
+		Optional<bool>				since_logoff;
+
+		Params()
+		:	filter_ops(""),
+			substring("substring"),
+			sort_order("sort_order"),
+			since_logoff("since_logoff")
+		{}
+	};
+									
+	LLInventoryFilter(const std::string& name, const Params& p);
 	virtual ~LLInventoryFilter();
 
 	// +-------------------------------------------------------------------+
@@ -86,7 +160,7 @@ public:
 	void 				setFilterObjectTypes(U64 types);
 	U64 				getFilterObjectTypes() const;
 	U64					getFilterCategoryTypes() const;
-	BOOL 				isFilterObjectTypesWith(LLInventoryType::EType t) const;
+	bool 				isFilterObjectTypesWith(LLInventoryType::EType t) const;
 	void 				setFilterCategoryTypes(U64 types);
 	void 				setFilterUUID(const LLUUID &object_id);
 	void				setFilterWearableTypes(U64 types);
@@ -96,7 +170,7 @@ public:
 	void 				setFilterSubString(const std::string& string);
 	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;
 	const std::string& 	getFilterSubStringOrig() const { return mFilterSubStringOrig; } 
-	BOOL 				hasFilterString() const;
+	bool 				hasFilterString() const;
 
 	void 				setFilterPermissions(PermissionMask perms);
 	PermissionMask 		getFilterPermissions() const;
@@ -115,18 +189,17 @@ public:
 	// +-------------------------------------------------------------------+
 	// + Execution And Results
 	// +-------------------------------------------------------------------+
-	BOOL 				check(const LLFolderViewItem* item);
+	bool 				check(const LLFolderViewItem* item);
 	bool				check(const LLInventoryItem* item);
 	bool				checkFolder(const LLFolderViewFolder* folder) const;
 	bool				checkFolder(const LLUUID& folder_id) const;
-	BOOL 				checkAgainstFilterType(const LLFolderViewItem* item) const;
+	bool 				checkAgainstFilterType(const LLFolderViewItem* item) const;
 	bool 				checkAgainstFilterType(const LLInventoryItem* item) const;
-	BOOL 				checkAgainstPermissions(const LLFolderViewItem* item) const;
+	bool 				checkAgainstPermissions(const LLFolderViewItem* item) const;
 	bool 				checkAgainstPermissions(const LLInventoryItem* item) const;
-	BOOL 				checkAgainstFilterLinks(const LLFolderViewItem* item) const;
-
-	std::string::size_type getStringMatchOffset() const;
+	bool 				checkAgainstFilterLinks(const LLFolderViewItem* item) const;
 
+	std::string::size_type getStringMatchOffset(LLFolderViewItem* item)   const;
 	// +-------------------------------------------------------------------+
 	// + Presentation
 	// +-------------------------------------------------------------------+
@@ -142,10 +215,10 @@ public:
 	// +-------------------------------------------------------------------+
 	// + Status
 	// +-------------------------------------------------------------------+
-	BOOL 				isActive() const;
-	BOOL 				isModified() const;
-	BOOL 				isModifiedAndClear();
-	BOOL 				isSinceLogoff() const;
+	bool 				isActive() const;
+	bool 				isModified() const;
+	bool 				isModifiedAndClear();
+	bool 				isSinceLogoff() const;
 	void 				clearModified();
 	const std::string& 	getName() const;
 	const std::string& 	getFilterText();
@@ -162,7 +235,7 @@ public:
 	// +-------------------------------------------------------------------+
 	// + Default
 	// +-------------------------------------------------------------------+
-	BOOL 				isNotDefault() const;
+	bool 				isNotDefault() const;
 	void 				markDefault();
 	void 				resetDefault();
 
@@ -170,14 +243,17 @@ public:
 	// + Generation
 	// +-------------------------------------------------------------------+
 	S32 				getCurrentGeneration() const;
-	S32 				getMinRequiredGeneration() const;
-	S32 				getMustPassGeneration() const;
+	S32 				getFirstSuccessGeneration() const;
+	S32 				getFirstRequiredGeneration() const;
+
 
 	// +-------------------------------------------------------------------+
 	// + Conversion
 	// +-------------------------------------------------------------------+
-	void 				toLLSD(LLSD& data) const;
-	void 				fromLLSD(LLSD& data);
+	void 				toParams(Params& params) const;
+	void 				fromParams(const Params& p);
+
+	LLInventoryFilter& operator =(const LLInventoryFilter& other);
 
 private:
 	bool				areDateLimitsSet();
@@ -203,7 +279,8 @@ private:
 	U32						mOrder;
 	U32 					mLastLogoff;
 
-	FilterOps				mFilterOps;
+	std::string::size_type	mSubStringMatchOffset;
+        FilterOps				mFilterOps;
 	FilterOps				mDefaultFilterOps;
 
 	std::string::size_type	mSubStringMatchOffset;
@@ -211,9 +288,9 @@ private:
 	std::string				mFilterSubStringOrig;
 	const std::string		mName;
 
-	S32						mFilterGeneration;
-	S32						mMustPassGeneration;
-	S32						mMinRequiredGeneration;
+	S32						mLastSuccessGeneration;
+	S32						mLastFailGeneration;
+	S32						mFirstSuccessGeneration;
 	S32						mNextFilterGeneration;
 
 	S32						mFilterCount;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 01a8ecfb5d..f5e2a23da0 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -37,6 +37,7 @@
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfolderview.h"
+#include "llfolderviewitem.h"
 #include "llimfloater.h"
 #include "llimview.h"
 #include "llinventorybridge.h"
@@ -54,6 +55,62 @@ const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("Recent
 const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
 static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
 
+//
+// class LLFolderViewModelInventory
+//
+void LLFolderViewModelInventory::requestSort(class LLFolderViewFolder*   folder)
+{
+	base_t::requestSort(folder);
+	if (getSorter().isByDate())
+	{
+		// sort by date potentially affects parent folders which use a date
+		// derived from newest item in them
+		requestSort(folder->getParentFolder());
+	}
+}
+
+static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort");
+
+void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
+{
+	LLFastTimer _(FTM_INVENTORY_SORT);
+
+	if (!needsSort(folder)) return;
+
+	LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(folder->getListener());
+	if (modelp->getUUID().isNull()) return;
+
+	for (std::list<LLFolderViewFolder*>::iterator it =   folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
+		it != end_it;
+		++it)
+	{
+		LLFolderViewFolder* child_folderp = *it;
+		sort(child_folderp);
+
+		if (child_folderp->getFoldersCount() > 0)
+		{
+			time_t most_recent_folder_time =
+				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getFoldersBegin()->getListener())->getCreationDate();
+			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getListener());
+			if (most_recent_folder_time > modelp->getCreationDate())
+			{
+				modelp->setCreationDate(most_recent_folder_time);
+			}
+		}
+		if (child_folderp->getItemsCount() > 0)			
+		{
+			time_t most_recent_item_time =
+				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getItemsBegin()->getListener())->getCreationDate();
+
+			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getListener());
+			if (most_recent_item_time > modelp->getCreationDate())
+			{
+				modelp->setCreationDate(most_recent_item_time);
+			}
+		}
+	}
+	base_t::sort(folder);
+}
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInventoryPanelObserver
@@ -133,7 +190,6 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mAllowMultiSelect(p.allow_multi_select),
 	mShowItemLinkOverlays(p.show_item_link_overlays),
 	mShowEmptyMessage(p.show_empty_message),
-	mShowLoadStatus(p.show_load_status),
 	mViewsInitialized(false),
 	mInvFVBridgeBuilder(NULL)
 {
@@ -253,14 +309,11 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 
 LLInventoryPanel::~LLInventoryPanel()
 {
-	if (mFolderRoot)
-	{
-		U32 sort_order = mFolderRoot->getSortOrder();
-		if (mSortOrderSetting != INHERIT_SORT_ORDER)
-		{
-			gSavedSettings.setU32(mSortOrderSetting, sort_order);
-		}
-	}
+        U32 sort_order = getViewModel()->getSortOrder();
+        if (mSortOrderSetting != INHERIT_SORT_ORDER)
+        {
+                gSavedSettings.setU32(mSortOrderSetting, sort_order);
+        }
 
 	gIdleCallbacks.deleteFunction(onIdle, this);
 
@@ -276,26 +329,18 @@ LLInventoryPanel::~LLInventoryPanel()
 void LLInventoryPanel::draw()
 {
 	// Select the desired item (in case it wasn't loaded when the selection was requested)
-	mFolderRoot->updateSelection();
+	updateSelection();
 	LLPanel::draw();
 }
 
 LLInventoryFilter* LLInventoryPanel::getFilter()
 {
-	if (mFolderRoot) 
-	{
-		return mFolderRoot->getFilter();
-	}
-	return NULL;
+	return getViewModel()->getFilter();
 }
 
 const LLInventoryFilter* LLInventoryPanel::getFilter() const
 {
-	if (mFolderRoot)
-	{
-		return mFolderRoot->getFilter();
-	}
-	return NULL;
+	return getViewModel()->getFilter();
 }
 
 void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
@@ -308,12 +353,12 @@ void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType
 
 U32 LLInventoryPanel::getFilterObjectTypes() const 
 { 
-	return mFolderRoot->getFilterObjectTypes(); 
+	return getFilter()->getFilterObjectTypes();
 }
 
 U32 LLInventoryPanel::getFilterPermMask() const 
 { 
-	return mFolderRoot->getFilterPermissions(); 
+	return getFilter()->getFilterPermissions();
 }
 
 
@@ -334,16 +379,17 @@ void LLInventoryPanel::setFilterSubString(const std::string& string)
 
 const std::string LLInventoryPanel::getFilterSubString() 
 { 
-	return mFolderRoot->getFilterSubString(); 
+	return getFilter()->getFilterSubString();
 }
 
 
 void LLInventoryPanel::setSortOrder(U32 order)
 {
+        LLInventorySort sorter(order);
 	getFilter()->setSortOrder(order);
-	if (getFilter()->isModified())
+	if (order != getViewModel()->getSortOrder())
 	{
-		mFolderRoot->setSortOrder(order);
+		getViewModel()->setSorter(LLInventorySort(order));
 		// try to keep selection onscreen, even if it wasn't to start with
 		mFolderRoot->scrollToShowSelection();
 	}
@@ -351,12 +397,7 @@ void LLInventoryPanel::setSortOrder(U32 order)
 
 U32 LLInventoryPanel::getSortOrder() const 
 { 
-	return mFolderRoot->getSortOrder(); 
-}
-
-void LLInventoryPanel::requestSort()
-{
-	mFolderRoot->requestSort();
+	return getViewModel()->getSortOrder();
 }
 
 void LLInventoryPanel::setSinceLogoff(BOOL sl)
@@ -405,7 +446,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 	{
 		const LLUUID& item_id = (*items_iter);
 		const LLInventoryObject* model_item = model->getObject(item_id);
-		LLFolderViewItem* view_item = mFolderRoot->getItemByID(item_id);
+		LLFolderViewItem* view_item = getItemByID(item_id);
 
 		// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
 		// to folder is the fast way to get a folder without searching through folders tree.
@@ -439,6 +480,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			if (model_item && view_item)
 			{
 				view_item->destroyView();
+                                removeItemID(view_item->getListener()->getUUID());
 			}
 			view_item = buildNewViews(item_id);
 			view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
@@ -497,9 +539,9 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			else if (model_item && view_item)
 			{
 				// Don't process the item if it is the root
-				if (view_item->getRoot() != view_item)
+				if (view_item->getParentFolder())
 				{
-					LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID());
+					LLFolderViewFolder* new_parent =   (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
 					// Item has been moved.
 					if (view_item->getParentFolder() != new_parent)
 					{
@@ -507,13 +549,15 @@ void LLInventoryPanel::modelChanged(U32 mask)
 						{
 							// Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
 							view_item->getParentFolder()->extractItem(view_item);
-							view_item->addToFolder(new_parent, mFolderRoot);
+							view_item->addToFolder(new_parent);
+							addItemID(view_item->getListener()->getUUID(), view_item);
 						}
 						else 
 						{
 							// Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that 
 							// doesn't include trash).  Just remove the item's UI.
 							view_item->destroyView();
+                                                        removeItemID(view_item->getListener()->getUUID());
 						}
 					}
 				}
@@ -526,6 +570,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			{
 				// Remove the item's UI.
 				view_item->destroyView();
+                                removeItemID(view_item->getListener()->getUUID());
 			}
 		}
 	}
@@ -574,14 +619,14 @@ void LLInventoryPanel::initializeViews()
 	if (gAgent.isFirstLogin())
 	{
 		// Auto open the user's library
-		LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID());
+		LLFolderViewFolder* lib_folder =   getFolderByID(gInventory.getLibraryRootFolderID());
 		if (lib_folder)
 		{
 			lib_folder->setOpen(TRUE);
 		}
 		
 		// Auto close the user's my inventory folder
-		LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID());
+		LLFolderViewFolder* my_inv_folder =   getFolderByID(gInventory.getRootFolderID());
 		if (my_inv_folder)
 		{
 			my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
@@ -592,10 +637,11 @@ void LLInventoryPanel::initializeViews()
 LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
 {
 	// Destroy the old view for this ID so we can rebuild it.
-	LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
+	LLFolderViewItem* old_view = getItemByID(id);
 	if (old_view)
 	{
 		old_view->destroyView();
+                removeItemID(old_view->getListener()->getUUID());
 	}
 
 	return buildNewViews(id);
@@ -619,7 +665,6 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
 	p.use_label_suffix = useLabelSuffix;
 	p.allow_multiselect = mAllowMultiSelect;
 	p.show_empty_message = mShowEmptyMessage;
-	p.show_load_status = mShowLoadStatus;
 
 	return LLUICtrlFactory::create<LLFolderView>(p);
 }
@@ -680,7 +725,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
  	else if (objectp)
  	{
  		const LLUUID &parent_id = objectp->getParentUUID();
- 		parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
+ 		parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
   		
   		if (parent_folder)
   		{
@@ -704,12 +749,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   																				objectp->getUUID());
   				if (new_listener)
   				{
-					LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
-					if (folderp)
-					{
-						folderp->setItemSortOrder(mFolderRoot->getSortOrder());
-					}
-  					itemp = folderp;
+					itemp = createFolderViewFolder(new_listener);
   				}
   			}
   			else
@@ -732,7 +772,8 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
  
   			if (itemp)
   			{
-  				itemp->addToFolder(parent_folder, mFolderRoot);
+  				itemp->addToFolder(parent_folder);
+				addItemID(itemp->getListener()->getUUID(), itemp);
    			}
 		}
 	}
@@ -904,7 +945,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
 	{
 		return;
 	}
-	mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus);
+	setSelectionByID(obj_id, take_keyboard_focus);
 }
 
 void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb) 
@@ -917,7 +958,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::
 
 void LLInventoryPanel::clearSelection()
 {
-	mFolderRoot->clearSelection();
+	mSelectThisID.setNull();
 }
 
 void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
@@ -953,12 +994,12 @@ void LLInventoryPanel::doToSelected(const LLSD& userdata)
 
 void LLInventoryPanel::doCreate(const LLSD& userdata)
 {
-	menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata);
+	menu_create_inventory_item(this, LLFolderBridge::sSelf.get(), userdata);
 }
 
 bool LLInventoryPanel::beginIMSession()
 {
-	std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
+	std::set<LLFolderViewItem*> selected_items =   mFolderRoot->getSelectionList();
 
 	std::string name;
 	static int session_num = 1;
@@ -966,12 +1007,11 @@ bool LLInventoryPanel::beginIMSession()
 	LLDynamicArray<LLUUID> members;
 	EInstantMessage type = IM_SESSION_CONFERENCE_START;
 
-	std::set<LLUUID>::const_iterator iter;
+	std::set<LLFolderViewItem*>::const_iterator iter;
 	for (iter = selected_items.begin(); iter != selected_items.end(); iter++)
 	{
 
-		LLUUID item = *iter;
-		LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item);
+		LLFolderViewItem* folder_item = (*iter);
 			
 		if(folder_item) 
 		{
@@ -1013,8 +1053,6 @@ bool LLInventoryPanel::beginIMSession()
 			}
 			else
 			{
-				LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item);
-				if(!folder_item) return true;
 				LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener();
 
 				if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
@@ -1056,13 +1094,13 @@ bool LLInventoryPanel::beginIMSession()
 bool LLInventoryPanel::attachObject(const LLSD& userdata)
 {
 	// Copy selected item UUIDs to a vector.
-	std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
+	std::set<LLFolderViewItem*> selected_items =   mFolderRoot->getSelectionList();
 	uuid_vec_t items;
-	for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin(); 
+	for (std::set<LLFolderViewItem*>::const_iterator set_iter =   selected_items.begin();
 		 set_iter != selected_items.end(); 
 		 ++set_iter)
 	{
-		items.push_back(*set_iter);
+		items.push_back((*set_iter)->getListener()->getUUID());
 	}
 
 	// Attach selected items.
@@ -1209,6 +1247,84 @@ BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) co
 	return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
 }
 
+void LLInventoryPanel::addItemID( const LLUUID& id, LLFolderViewItem*   itemp )
+{
+	mItemMap[id] = itemp;
+}
+
+void LLInventoryPanel::removeItemID(const LLUUID& id)
+{
+	LLInventoryModel::cat_array_t categories;
+	LLInventoryModel::item_array_t items;
+	gInventory.collectDescendents(id, categories, items, TRUE);
+
+	mItemMap.erase(id);
+
+	for (LLInventoryModel::cat_array_t::iterator it = categories.begin(),    end_it = categories.end();
+		it != end_it;
+		++it)
+	{
+		mItemMap.erase((*it)->getUUID());
+	}
+
+	for (LLInventoryModel::item_array_t::iterator it = items.begin(),   end_it  = items.end();
+		it != end_it;
+		++it)
+	{
+		mItemMap.erase((*it)->getUUID());
+	}
+}
+
+LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
+LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id)
+{
+	LLFastTimer _(FTM_GET_ITEM_BY_ID);
+	if (id == mFolderRoot->getListener()->getUUID())
+	{
+		return mFolderRoot;
+	}
+
+	std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
+	map_it = mItemMap.find(id);
+	if (map_it != mItemMap.end())
+	{
+		return map_it->second;
+	}
+
+	return NULL;
+}
+
+LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)
+{
+	LLFolderViewItem* item = getItemByID(id);
+	return dynamic_cast<LLFolderViewFolder*>(item);
+}
+
+
+void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL    take_keyboard_focus )
+{
+	LLFolderViewItem* itemp = getItemByID(obj_id);
+	if(itemp && itemp->getListener())
+	{
+		itemp->arrangeAndSet(TRUE, take_keyboard_focus);
+		mSelectThisID.setNull();
+		return;
+	}
+	else
+	{
+		// save the desired item to be selected later (if/when ready)
+		mSelectThisID = obj_id;
+	}
+}
+
+void LLInventoryPanel::updateSelection()
+{
+	if (mSelectThisID.notNull())
+	{
+		setSelectionByID(mSelectThisID, false);
+	}
+}
+
 
 /************************************************************************/
 /* Recent Inventory Panel related class                                 */
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 7d805f6862..787cacba43 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -30,6 +30,7 @@
 
 #include "llassetstorage.h"
 #include "lldarray.h"
+#include "llfolderviewitem.h"
 #include "llfloater.h"
 #include "llinventory.h"
 #include "llinventoryfilter.h"
@@ -55,6 +56,18 @@ class LLFilterEditor;
 class LLTabContainer;
 class LLInvPanelComplObserver;
 
+class LLFolderViewModelInventory
+:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter>
+{
+	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t;
+
+	virtual ~LLFolderViewModelInventory() {}
+
+	void sort(LLFolderViewFolder* folder);
+	void requestSort(LLFolderViewFolder* folder);
+};
+
+
 class LLInventoryPanel : public LLPanel
 {
 	//--------------------------------------------------------------------
@@ -85,7 +98,6 @@ public:
 		Optional<std::string>               start_folder;
 		Optional<bool>						use_label_suffix;
 		Optional<bool>						show_empty_message;
-		Optional<bool>						show_load_status;
 		Optional<LLScrollContainer::Params>	scroll;
 		Optional<bool>						accepts_drag_and_drop;
 
@@ -98,7 +110,6 @@ public:
 			start_folder("start_folder"),
 			use_label_suffix("use_label_suffix", true),
 			show_empty_message("show_empty_message", true),
-			show_load_status("show_load_status"),
 			scroll("scroll"),
 			accepts_drag_and_drop("accepts_drag_and_drop")
 		{}
@@ -182,22 +193,35 @@ public:
 	
 	static void openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id);
 
+	void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
+	void removeItemID(const LLUUID& id);
+	LLFolderViewItem* getItemByID(const LLUUID& id);
+	LLFolderViewFolder* getFolderByID(const LLUUID& id);
+	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
+	void updateSelection();
+	 	
+	LLFolderViewModelInventory* getViewModel() { return &mViewModel; }
+	const LLFolderViewModelInventory* getViewModel() const { return   &mViewModel; }
+
 protected:
 	void openStartFolderOrMyInventory(); // open the first level of inventory
 	void onItemsCompletion();			// called when selected items are complete
 
-	LLInventoryModel*			mInventory;
+        LLUUID						mSelectThisID;	
+        LLInventoryModel*			mInventory;
 	LLInventoryObserver*		mInventoryObserver;
 	LLInvPanelComplObserver*	mCompletionObserver;
 	BOOL						mAcceptsDragAndDrop;
 	BOOL 						mAllowMultiSelect;
 	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons
 	BOOL						mShowEmptyMessage;
-	BOOL						mShowLoadStatus;
 
 	LLFolderView*				mFolderRoot;
 	LLScrollContainer*			mScroller;
 
+	LLFolderViewModelInventory	mViewModel;
+	
+	std::map<LLUUID, LLFolderViewItem*> mItemMap;
 	/**
 	 * Pointer to LLInventoryFVBridgeBuilder.
 	 *
@@ -218,7 +242,6 @@ public:
 	
 	void setSortOrder(U32 order);
 	U32 getSortOrder() const;
-	void requestSort();
 
 private:
 	std::string					mSortOrderSetting;
@@ -252,4 +275,25 @@ private:
 	LLUUID				mStartFolderID;
 };
 
+class LLFolderViewModelItemInventory
+	:	public LLFolderViewModelItemCommon
+{
+public:
+	virtual const LLUUID& getUUID() const = 0;
+	virtual time_t getCreationDate() const = 0;	// UTC seconds
+	virtual void setCreationDate(time_t creation_date_utc) = 0;
+	virtual PermissionMask getPermissionMask() const = 0;
+	virtual LLFolderType::EType getPreferredType() const = 0;
+	virtual void previewItem( void ) = 0;
+	virtual void showProperties(void) = 0;
+	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual.
+	virtual BOOL isUpToDate() const = 0;
+	virtual BOOL hasChildren() const = 0;
+	virtual LLInventoryType::EType getInventoryType() const = 0;
+	virtual void performAction(LLInventoryModel* model, std::string action)   = 0;
+	virtual LLWearableType::EType getWearableType() const = 0;
+	virtual EInventorySortGroup getSortGroup() const;
+	virtual void requestSort(const LLInventorySort& sorter);
+};
+
 #endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index c7454e85a9..fd207f098f 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -299,7 +299,7 @@ void LLLandmarksPanel::onTeleport()
 		return;
 	}
 
-	LLFolderViewEventListener* listenerp = current_item->getListener();
+	LLFolderViewModelItem* listenerp = current_item->getListener();
 	if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		listenerp->openItem();
@@ -360,7 +360,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()
 	LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
 	if (!cur_item) return;
 
-	LLFolderViewEventListener* listenerp = cur_item->getListener();
+	LLFolderViewModelItem* listenerp = cur_item->getListener();
 	if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		LLSD key;
@@ -376,7 +376,7 @@ void LLLandmarksPanel::updateShowFolderState()
 	if (!mLandmarksInventoryPanel->getFilter())
 		return;
 
-	bool show_all_folders = mLandmarksInventoryPanel->getRootFolder()->getFilterSubString().empty();
+	bool show_all_folders =   mLandmarksInventoryPanel->getFilterSubString().empty();
 	if (show_all_folders)
 	{
 		show_all_folders = category_has_descendents(mLandmarksInventoryPanel);
@@ -466,7 +466,7 @@ LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPa
 
 	LLFolderView* root = inventory_list->getRootFolder();
 
-	LLFolderViewItem* item = root->getItemByID(obj_id);
+	LLFolderViewItem* item = inventory_list->getItemByID(obj_id);
 	if (!item)
 		return NULL;
 
@@ -665,20 +665,20 @@ void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory
 {
 	if (inventory_list != mFavoritesInventoryPanel)
 	{
-		mFavoritesInventoryPanel->getRootFolder()->clearSelection();
+		mFavoritesInventoryPanel->clearSelection();
 	}
 
 	if (inventory_list != mLandmarksInventoryPanel)
 	{
-		mLandmarksInventoryPanel->getRootFolder()->clearSelection();
+		mLandmarksInventoryPanel->clearSelection();
 	}
 	if (inventory_list != mMyInventoryPanel)
 	{
-		mMyInventoryPanel->getRootFolder()->clearSelection();
+		mMyInventoryPanel->clearSelection();
 	}
 	if (inventory_list != mLibraryInventoryPanel)
 	{
-		mLibraryInventoryPanel->getRootFolder()->clearSelection();
+		mLibraryInventoryPanel->clearSelection();
 	}
 }
 
@@ -738,7 +738,7 @@ void LLLandmarksPanel::onActionsButtonClick()
 		if(!cur_item)
 			return;
 
-		LLFolderViewEventListener* listenerp = cur_item->getListener();
+		LLFolderViewModelItem* listenerp = cur_item->getListener();
 		if(!listenerp)
 			return;
 
@@ -794,7 +794,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 		LLFolderViewItem* item = getCurSelectedItem();
 		if (item && mCurrentSelectedList == mLandmarksInventoryPanel)
 		{
-			LLFolderViewEventListener* folder_bridge = NULL;
+			LLFolderViewModelItem* folder_bridge = NULL;
 			if (item-> getListener()->getInventoryType()
 					== LLInventoryType::IT_LANDMARK)
 			{
@@ -808,7 +808,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 				folder_bridge = item->getListener();
 			}
 
-			menu_create_inventory_item(mCurrentSelectedList->getRootFolder(),
+			menu_create_inventory_item(mCurrentSelectedList,
 					dynamic_cast<LLFolderBridge*> (folder_bridge), LLSD(
 							"category"), gInventory.findCategoryUUIDForType(
 							LLFolderType::FT_LANDMARK));
@@ -816,7 +816,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 		else
 		{
 			//in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
-			menu_create_inventory_item(mLandmarksInventoryPanel->getRootFolder(), NULL, LLSD("category"), 
+			menu_create_inventory_item(mLandmarksInventoryPanel, NULL,  LLSD("category"), 
 				gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
 
 			if (mMyLandmarksAccordionTab)
@@ -977,12 +977,12 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 	{
 		if (!root_folder_view) return false;
 
-		std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList();
 
 		// Allow to execute the command only if it can be applied to all selected items.
-		for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
 		{
-			LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+			LLFolderViewItem* item = *iter;
 
 			// If no item is found it might be a folder id.
 			if (!item)
@@ -1049,7 +1049,7 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 	{
 		if (mCurrentSelectedList)
 		{
-			std::set<LLUUID> selection = mCurrentSelectedList->getRootFolder()->getSelectionList();
+			std::set<LLFolderViewItem*> selection =    mCurrentSelectedList->getRootFolder()->getSelectionList();
 			if (!selection.empty())
 			{
 				return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() );
@@ -1105,27 +1105,23 @@ void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)
 	{
 		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
 
-		std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList();
 
 		// Iterate through selected items to find out if any of these items are in Trash
 		// or all the items are in Trash category.
-		for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
 		{
-			LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+			LLFolderViewItem* item = *iter;
 
 			// If no item is found it might be a folder id.
-			if (!item)
-			{
-				item = root_folder_view->getFolderByID(*iter);
-			}
 			if (!item) continue;
 
-			LLFolderViewEventListener* listenerp = item->getListener();
+			LLFolderViewModelItem* listenerp = item->getListener();
 			if(!listenerp) continue;
 
 			// Trash category itself should not be included because it can't be
 			// actually restored from trash.
-			are_all_items_in_trash &= listenerp->isItemInTrash() && *iter != trash_id;
+			are_all_items_in_trash &= listenerp->isItemInTrash() &&    (*iter)->getListener()->getUUID() != trash_id;
 
 			// If there are any selected items in Trash including the Trash category itself
 			// we show "Restore Item" in context menu and hide other irrelevant items.
@@ -1202,7 +1198,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 
 	if (can_be_modified)
 	{
-		LLFolderViewEventListener* listenerp = item->getListener();
+		LLFolderViewModelItemInventory* listenerp = item->getListener();
 
 		if ("cut" == command_name)
 		{
@@ -1263,8 +1259,9 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg
 				LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data);
 				if (item)
 				{
-					LLFolderViewItem* fv_item = (mCurrentSelectedList && mCurrentSelectedList->getRootFolder()) ?
-						mCurrentSelectedList->getRootFolder()->getItemByID(item->getUUID()) : NULL;
+					LLFolderViewItem* fv_item = mCurrentSelectedList
+						? mCurrentSelectedList->getItemByID(item->getUUID())
+						: NULL;
 
 					if (fv_item)
 					{
@@ -1392,7 +1389,7 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
 static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string)
 {
 	// When search is cleared, restore the old folder state.
-	if (!inventory_list->getRootFolder()->getFilterSubString().empty() && string == "")
+	if (!inventory_list->getFilterSubString().empty() && string == "")
 	{
 		inventory_list->setFilterSubString(LLStringUtil::null);
 		// Re-open folders that were open before
@@ -1406,7 +1403,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
 	}
 
 	// save current folder open state if no filter currently applied
-	if (inventory_list->getRootFolder()->getFilterSubString().empty())
+	if (inventory_list->getFilterSubString().empty())
 	{
 		inventory_list->saveFolderState();
 	}
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index c3c62920d3..d50cd3b270 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -53,6 +53,7 @@
 #include "llviewermenu.h"
 #include "llviewertexturelist.h"
 #include "llsidepanelinventory.h"
+#include "llfolderview.h"
 
 const std::string FILTERS_FILENAME("filters.xml");
 
@@ -171,7 +172,10 @@ BOOL LLPanelMainInventory::postBuild()
 			{
 				LLSD recent_items = savedFilterState.get(
 					recent_items_panel->getFilter()->getName());
-				recent_items_panel->getFilter()->fromLLSD(recent_items);
+				LLInventoryFilter::Params p;
+				LLParamSDParser parser;
+				parser.readSD(recent_items, p);
+				recent_items_panel->getFilter()->fromParams(p);
 			}
 		}
 
@@ -212,21 +216,22 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
 		if (filter)
 		{
 			LLSD filterState;
-			filter->toLLSD(filterState);
-			filterRoot[filter->getName()] = filterState;
+			LLInventoryFilter::Params p;
+			filter->toParams(p);
+			if (p.validateBlock(false))
+			{
+				LLParamSDParser().writeSD(filterState, p);
+				filterRoot[filter->getName()] = filterState;
+			}
 		}
 	}
 
-	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
-	if (recent_items_panel)
-	{
-		LLInventoryFilter* filter = recent_items_panel->getFilter();
-		if (filter)
-		{
-			LLSD filterState;
-			filter->toLLSD(filterState);
-			filterRoot[filter->getName()] = filterState;
-		}
+        LLInventoryFilter* filter = getChild<LLInventoryPanel>("Recent   Items")->getFilter();
+	if (filter)	
+        {
+		LLSD filterState;
+		filter->toLLSD(filterState);
+		filterRoot[filter->getName()] = filterState;
 	}
 
 	std::ostringstream filterSaveName;
@@ -306,7 +311,7 @@ void LLPanelMainInventory::newWindow()
 
 void LLPanelMainInventory::doCreate(const LLSD& userdata)
 {
-	menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
+	menu_create_inventory_item(getPanel(), NULL, userdata);
 }
 
 void LLPanelMainInventory::resetFilters()
@@ -417,7 +422,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
 	}
 
 	// save current folder open state if no filter currently applied
-	if (!mActivePanel->getRootFolder()->isFilterModified())
+	if (!mActivePanel->getFilter()->isNotDefault())
 	{
 		mSavedFolderState->setApply(FALSE);
 		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -1110,15 +1115,15 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 		if (root)
 		{
 			can_delete = TRUE;
-			std::set<LLUUID> selection_set = root->getSelectionList();
+			std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
 			if (selection_set.empty()) return FALSE;
-			for (std::set<LLUUID>::iterator iter = selection_set.begin();
+			for (std::set<LLFolderViewItem*>::iterator iter =    selection_set.begin();
 				 iter != selection_set.end();
 				 ++iter)
 			{
 				const LLUUID &item_id = (*iter);
-				LLFolderViewItem *item = root->getItemByID(item_id);
-				const LLFolderViewEventListener *listener = item->getListener();
+				LLFolderViewItem *item = *iter;
+				const LLFolderViewModelItemInventory *listener = item->getListener();
 				llassert(listener);
 				if (!listener) return FALSE;
 				can_delete &= listener->isItemRemovable();
@@ -1148,7 +1153,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	if (command_name == "find_links")
 	{
 		LLFolderView* root = getActivePanel()->getRootFolder();
-		std::set<LLUUID> selection_set = root->getSelectionList();
+		std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
 		if (selection_set.size() != 1) return FALSE;
 		LLFolderViewItem* current_item = root->getCurSelectedItem();
 		if (!current_item) return FALSE;
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 66c9c323cb..6804342106 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -94,7 +94,7 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
 	mInventoryPanel->setShape(inventory_placeholder_rect);
 	
 	// Set the sort order newest to oldest
-	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);	
+	mInventoryPanel->getViewModel()->setSorter(LLInventoryFilter::SO_DATE);
 	mInventoryPanel->getFilter()->markDefault();
 
 	// Set selection callback for proper update of inventory status buttons
@@ -139,12 +139,12 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 
 	if (mInventoryPanel)
 	{
-		const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
+		LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
 		
 		if (inbox_folder)
 		{
-			LLFolderViewFolder::folders_t::const_iterator folders_it = inbox_folder->getFoldersBegin();
-			LLFolderViewFolder::folders_t::const_iterator folders_end = inbox_folder->getFoldersEnd();
+			LLFolderViewFolder::folders_t::iterator folders_it = inbox_folder->getFoldersBegin();
+			LLFolderViewFolder::folders_t::iterator folders_end = inbox_folder->getFoldersEnd();
 
 			for (; folders_it != folders_end; ++folders_it)
 			{
@@ -157,8 +157,8 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 				}
 			}
 
-			LLFolderViewFolder::items_t::const_iterator items_it = inbox_folder->getItemsBegin();
-			LLFolderViewFolder::items_t::const_iterator items_end = inbox_folder->getItemsEnd();
+			LLFolderViewFolder::items_t::iterator items_it = inbox_folder->getItemsBegin();
+			LLFolderViewFolder::items_t::iterator items_end = inbox_folder->getItemsEnd();
 
 			for (; items_it != items_end; ++items_it)
 			{
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 678e4f2843..1d079adfd3 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -29,6 +29,7 @@
 #include "llpanelmarketplaceinboxinventory.h"
 
 #include "llfolderview.h"
+#include "llfolderviewitem.h"
 #include "llfoldervieweventlistener.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
@@ -253,9 +254,9 @@ LLInboxFolderViewItem::LLInboxFolderViewItem(const Params& p)
 #endif
 }
 
-BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
+BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 {
-	BOOL retval = LLFolderViewItem::addToFolder(folder, root);
+	BOOL retval = LLFolderViewItem::addToFolder(folder);
 
 #if SUPPORTING_FRESH_ITEM_COUNT
 	// Compute freshness if our parent is the root folder for the inbox
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index d6b827ee3e..209f3a4098 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -81,8 +81,6 @@ public:
 	bool isFresh() const { return mFresh; }
 	
 protected:
-	void setCreationDate(time_t creation_date_utc);
-
 	bool mFresh;
 };
 
@@ -102,7 +100,7 @@ public:
 
 	LLInboxFolderViewItem(const Params& p);
 
-	BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+	BOOL addToFolder(LLFolderViewFolder* folder);
 	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
 
 	void draw();
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
index ff62cb23db..b5c7c4ca88 100644
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
@@ -28,7 +28,7 @@
 
 #include "llpanelmarketplaceoutboxinventory.h"
 
-#include "llfolderview.h"
+#include "llfolderviewitem.h"
 #include "llfoldervieweventlistener.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 1efd1c3d9c..2789fe0082 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -71,7 +71,7 @@
 /// Class LLTaskInvFVBridge
 ///----------------------------------------------------------------------------
 
-class LLTaskInvFVBridge : public LLFolderViewEventListener
+class LLTaskInvFVBridge : public LLFolderViewModelItemInventory
 {
 protected:
 	LLUUID mUUID;
@@ -102,7 +102,7 @@ public:
 	S32 getPrice();
 	static bool commitBuyItem(const LLSD& notification, const LLSD& response);
 
-	// LLFolderViewEventListener functionality
+	// LLFolderViewModelItemInventory functionality
 	virtual const std::string& getName() const;
 	virtual const std::string& getDisplayName() const;
 	virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
@@ -120,9 +120,9 @@ public:
 	virtual BOOL isItemMovable() const;
 	virtual BOOL isItemRemovable() const;
 	virtual BOOL removeItem();
-	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
-	virtual void move(LLFolderViewEventListener* parent_listener);
-	virtual BOOL isItemCopyable() const;
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
+	virtual void move(LLFolderViewModelItem* parent_listener);	
+        virtual BOOL  isItemCopyable() const;
 	virtual BOOL copyToClipboard() const;
 	virtual void cutToClipboard();
 	virtual BOOL isClipboardPasteable() const;
@@ -467,7 +467,7 @@ BOOL LLTaskInvFVBridge::removeItem()
 	return FALSE;
 }
 
-void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void   LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewModelItem*>&   batch)
 {
 	if (!mPanel)
 	{
@@ -507,7 +507,7 @@ void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>&
 	}
 }
 
-void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
+void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)
 {
 }
 
@@ -1547,7 +1547,8 @@ void LLPanelObjectInventory::reset()
 	p.folder_indentation = -14; // subtract space normally reserved for folder expanders
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
-	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+	RN: make this happen by manipulating filter object directly
+	//mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
 	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
 	if (hasFocus())
@@ -1607,7 +1608,7 @@ void LLPanelObjectInventory::updateInventory()
 	//		<< " panel UUID: " << panel->mTaskUUID << "\n"
 	//		<< " task  UUID: " << object->mID << llendl;
 	// We're still interested in this task's inventory.
-	std::set<LLUUID> selected_items;
+	std::set<LLFolderViewItem*> selected_items;
 	BOOL inventory_has_focus = FALSE;
 	if (mHaveInventory)
 	{
@@ -1645,11 +1646,11 @@ void LLPanelObjectInventory::updateInventory()
 	}
 
 	// restore previous selection
-	std::set<LLUUID>::iterator selection_it;
+	std::set<LLFolderViewItem*>::iterator selection_it;
 	BOOL first_item = TRUE;
 	for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
 	{
-		LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
+		LLFolderViewItem* selected_item = (*selection_it);
 		if (selected_item)
 		{
 			//HACK: "set" first item then "change" each other one to get keyboard focus right
@@ -1751,7 +1752,8 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 				params.tool_tip = params.name;
 				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 			}
-			view->addToFolder(folder, mFolders);
+			view->addToFolder(folder);
+                        addItemID(view->getListener()->getUUID(), view);
 		}
 	}
 
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 35e2e96bab..4abc7fea0e 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -270,7 +270,7 @@ private:
 
 		if (inventory_panel->getVisible())
 		{
-			inventory_panel->setSortOrder(sort_order);
+			inventory_panel->getViewModel()->setSorter(sort_order);
 		}
 		else
 		{
@@ -738,7 +738,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
 	}
 	
 	// save current folder open state if no filter currently applied
-	if (mInventoryItemsPanel->getRootFolder()->getFilterSubString().empty())
+	if (mInventoryItemsPanel->getFilterSubString().empty())
 	{
 		mSavedFolderState->setApply(FALSE);
 		mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -885,13 +885,13 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT
 	{
 		if (mInventoryItemsPanel != NULL && mInventoryItemsPanel->getVisible())
 		{
-			std::set<LLUUID> selected_uuids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+			std::set<LLFolderViewItem*> selected_items =    mInventoryItemsPanel->getRootFolder()->getSelectionList();
 
-			result.second = selected_uuids.size();
+			result.second = selected_items.size();
 
 			if (result.second == 1)
 			{
-				result.first = getWearableTypeByItemUUID(*(selected_uuids.begin()));
+				result.first =    getWearableTypeByItemUUID((*selected_items.begin())->getListener()->getUUID());
 			}
 		}
 		else if (mWearableItemsList != NULL && mWearableItemsList->getVisible())
@@ -1310,7 +1310,7 @@ void LLPanelOutfitEdit::getCurrentItemUUID(LLUUID& selected_id)
 		LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
 		if (!curr_item) return;
 
-		LLFolderViewEventListener* listenerp  = curr_item->getListener();
+		LLFolderViewModelItemInventory* listenerp  = curr_item->getListener();
 		if (!listenerp) return;
 
 		selected_id = listenerp->getUUID();
@@ -1327,9 +1327,13 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)
 	void (uuid_vec_t::* tmp)(LLUUID const &) = &uuid_vec_t::push_back;
 	if (mInventoryItemsPanel->getVisible())
 	{
-		std::set<LLUUID> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList();
-
-		std::for_each(item_set.begin(), item_set.end(), boost::bind( tmp, &uuid_list, _1));
+		std::set<LLFolderViewItem*> item_set =    mInventoryItemsPanel->getRootFolder()->getSelectionList();
+		for (std::set<LLFolderViewItem*>::iterator it = item_set.begin(),    end_it = item_set.end();
+			it != end_it;
+			++it)
+		{
+			uuid_list.push_back((*it)->getListener()->getUUID());
+		}
 	}
 	else if (mWearablesListViewPanel->getVisible())
 	{
@@ -1374,13 +1378,13 @@ void LLPanelOutfitEdit::saveListSelection()
 {
 	if(mWearablesListViewPanel->getVisible())
 	{
-		std::set<LLUUID> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+		std::set<LLFolderViewItem*> selected_ids =    mInventoryItemsPanel->getRootFolder()->getSelectionList();
 
 		if(!selected_ids.size()) return;
 
-		for (std::set<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
+		for (std::set<LLFolderViewItem*>::const_iterator item_id =    selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
 		{
-			mWearableItemsList->selectItemByUUID(*item_id, true);
+			mWearableItemsList->selectItemByUUID((*item_id)->getListener()->getUUID(),    true);
 		}
 		mWearableItemsList->scrollToShowFirstSelectedItem();
 	}
@@ -1398,7 +1402,7 @@ void LLPanelOutfitEdit::saveListSelection()
 
 		for(std::vector<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
 		{
-			LLFolderViewItem* item = root->getItemByID(*item_id);
+			LLFolderViewItem* item = mInventoryItemsPanel->getItemByID(*item_id);
 			if (!item) continue;
 
 			LLFolderViewFolder* parent = item->getParentFolder();
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index fe4cc0f55f..97c5d531d2 100644
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -85,34 +85,33 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 
 void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
+	std::vector<std::string> items;
+	std::vector<std::string> disabled_items;
+
+	LLInventoryPanel* inv_panel = mInventoryPanel.get();
+	bool is_open = false;
+	if (inv_panel)
 	{
-		std::vector<std::string> items;
-		std::vector<std::string> disabled_items;
+		LLFolderViewFolder* folder =  dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));
+		is_open = (NULL != folder) && folder->isOpen();
+	}
 
-		LLInventoryPanel* inv_panel = mInventoryPanel.get();
-		bool is_open = false;
-		if (inv_panel)
-		{
-			LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID));
-			is_open = (NULL != folder) && folder->isOpen();
-		}
+	// collect all items' names
+	fill_items_with_menu_items(items, menu);
 
-		// collect all items' names
-		fill_items_with_menu_items(items, menu);
+	// remove expand or collapse menu item depend on folder state
+	std::string collapse_expand_item_to_hide(is_open ? "expand" :  "collapse");
+	std::vector<std::string>::iterator it = std::find(items.begin(),  items.end(), collapse_expand_item_to_hide);
+	if (it != items.end())	items.erase(it);
 
-		// remove expand or collapse menu item depend on folder state
-		std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse");
-		std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide);
-		if (it != items.end())	items.erase(it);
 
-		// Disabled items are processed via LLLandmarksPanel::isActionEnabled()
-		// they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601 
+	// Disabled items are processed via LLLandmarksPanel::isActionEnabled()
+	// they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601 
 
-		// repeat parent functionality
- 		sSelf = getHandle(); // necessary for "New Folder" functionality
+	// repeat parent functionality
+ 	sSelf = getHandle(); // necessary for "New Folder" functionality
 
-		hide_context_entries(menu, items, disabled_items);
-	}
+	hide_context_entries(menu, items, disabled_items);
 }
 
 //virtual
@@ -140,7 +139,7 @@ LLFolderViewFolder* LLPlacesFolderBridge::getFolder()
 	LLInventoryPanel* inv_panel = mInventoryPanel.get();
 	if (inv_panel)
 	{
-		folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID));
+		folder =    dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));
 	}
 
 	return folder;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index f7823f4fe8..1de26660bc 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -31,6 +31,7 @@
 #include "llplacesinventorypanel.h"
 
 #include "llfoldervieweventlistener.h"
+#include "llfolderview.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 #include "llpanellandmarks.h"
@@ -91,7 +92,7 @@ void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par
 	p.parent_panel = this;
 	p.allow_multiselect = mAllowMultiSelect;
 	p.use_ellipses = true;	// truncate inventory item text so remove horizontal scroller
-	mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
+	mFolderRoot = LLUICtrlFactory::create<LLPlacesFolderView>(p);
 }
 
 
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 853656905c..f069da5869 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -267,7 +267,7 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked()
 		if (inventory_panel)
 		{
 			LLFolderView* root = inventory_panel->getRootFolder();
-			LLFolderViewItem *outfit_folder = root->getItemByID(outfit_link->getLinkedUUID());
+			LLFolderViewItem *outfit_folder =    inventory_panel->getItemByID(outfit_link->getLinkedUUID());
 			if (outfit_folder)
 			{
 				outfit_folder->setOpen(!outfit_folder->isOpen());
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index c8b67cc9ec..a86523d32d 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -36,6 +36,7 @@
 #include "llfirstuse.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfoldertype.h"
+#include "llfolderview.h"
 #include "llhttpclient.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
@@ -653,7 +654,7 @@ U32 LLSidepanelInventory::getSelectedCount()
 {
 	int count = 0;
 
-	std::set<LLUUID> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
+	std::set<LLFolderViewItem*> selection_list =    mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
 	count += selection_list.size();
 
 	if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
@@ -704,9 +705,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
 	updateVerbs();
 }
 
-std::set<LLUUID> LLSidepanelInventory::getInboxSelectionList()
+std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()
 {
-	std::set<LLUUID> inventory_selected_uuids;
+	std::set<LLFolderViewItem*> inventory_selected_uuids;
 	
 	if (mInboxEnabled && (mInventoryPanelInbox != NULL))
 	{
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index a33607f50d..6aa349f0f3 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -63,6 +63,7 @@ public:
 	BOOL isMainInventoryPanelActive() const;
 
 	void clearSelections(bool clearMain, bool clearInbox);
+        std::set<LLFolderViewItem*> getInboxSelectionList();
 	std::set<LLUUID> getInboxSelectionList();
 
 	void showItemInfoPanel();
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 19a944e88e..92970003ef 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -345,7 +345,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
 		{
 			if (!root_folder->getCurSelectedItem())
 			{
-				LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID());
+				LLFolderViewItem* itemp =    mInventoryPanel->getItemByID(gInventory.getRootFolderID());
 				if (itemp)
 				{
 					root_folder->setSelection(itemp, FALSE, FALSE);
@@ -848,7 +848,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
 	else if (mInventoryPanel->getFilterSubString().empty())
 	{
 		// first letter in search term, save existing folder open state
-		if (!mInventoryPanel->getRootFolder()->isFilterModified())
+		if (!mInventoryPanel->getFilter()->isNotDefault())
 		{
 			mSavedFolderState.setApply(FALSE);
 			mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 45ca23cdfe..d827b2b8aa 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1308,7 +1308,7 @@ const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably
 const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
 
 // ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
-void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
+void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
 {
 	std::string type_name = userdata.asString();
 	
@@ -1332,7 +1332,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
 
 		LLUUID category = gInventory.createNewCategory(parent_id, preferred_type, LLStringUtil::null);
 		gInventory.notifyObservers();
-		root->setSelectionByID(category, TRUE);
+		panel->setSelectionByID(category, TRUE);
 	}
 	else if ("lsl" == type_name)
 	{
@@ -1375,7 +1375,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
 			llwarns << "Can't create unrecognized type " << type_name << llendl;
 		}
 	}
-	root->setNeedsAutoRename(TRUE);	
+	panel->getRoot()->->setNeedsAutoRename(TRUE);	
 }
 
 LLAssetType::EType LLViewerInventoryItem::getType() const
@@ -1785,12 +1785,6 @@ void LLViewerInventoryItem::getSLURL()
 	LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID);
 }
 
-const LLPermissions& LLViewerInventoryItem::getPermissions() const
-{
-	// Use the actual permissions of the symlink, not its parent.
-	return LLInventoryItem::getPermissions();	
-}
-
 const LLUUID& LLViewerInventoryItem::getCreatorUUID() const
 {
 	if (const LLViewerInventoryItem *linked_item = getLinkedItem())
@@ -1861,17 +1855,6 @@ LLWearableType::EType LLViewerInventoryItem::getWearableType() const
 	return LLWearableType::EType(getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);
 }
 
-
-time_t LLViewerInventoryItem::getCreationDate() const
-{
-	return LLInventoryItem::getCreationDate();
-}
-
-U32 LLViewerInventoryItem::getCRC32() const
-{
-	return LLInventoryItem::getCRC32();	
-}
-
 // *TODO: mantipov: should be removed with LMSortPrefix patch in llinventorymodel.cpp, EXT-3985
 static char getSeparator() { return '@'; }
 BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName)
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 7822ef4da6..d66362d544 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -34,7 +34,7 @@
 
 #include <boost/signals2.hpp>	// boost::signals2::trackable
 
-class LLFolderView;
+class LLInventoryPanel;
 class LLFolderBridge;
 class LLViewerInventoryCategory;
 
@@ -63,7 +63,6 @@ public:
 	virtual S32 getSortField() const;
 	virtual void setSortField(S32 sortField);
 	virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here.
-	virtual const LLPermissions& getPermissions() const;
 	virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied
 	virtual const LLUUID& getCreatorUUID() const;
 	virtual const std::string& getDescription() const;
@@ -72,8 +71,11 @@ public:
 	virtual bool isWearableType() const;
 	virtual LLWearableType::EType getWearableType() const;
 	virtual U32 getFlags() const;
-	virtual time_t getCreationDate() const;
-	virtual U32 getCRC32() const; // really more of a checksum.
+
+        using LLInventoryItem::getPermissions;
+	using LLInventoryItem::getCreationDate;
+	using LLInventoryItem::setCreationDate;
+	using LLInventoryItem::getCRC32;
 
 	static BOOL extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName);
 
@@ -372,7 +374,7 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
 								  U32 callback_id = 0);
 
 
-void menu_create_inventory_item(LLFolderView* root,
+void menu_create_inventory_item(LLInventoryPanel* root,
 								LLFolderBridge* bridge,
 								const LLSD& userdata,
 								const LLUUID& default_parent_uuid = LLUUID::null);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index cefd9ef91d..23de64ec13 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -726,7 +726,7 @@ static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& item
 		LLFolderView* fv = inventory_panel->getRootFolder();
 		if (fv)
 		{
-			LLFolderViewItem* fv_item = fv->getItemByID(item_id);
+			LLFolderViewItem* fv_item = inventory_panel->getItemByID(item_id);
 			if (fv_item)
 			{
 				LLFolderViewItem* fv_folder = fv_item->getParentFolder();
@@ -814,7 +814,13 @@ private:
 		mSelectedItems.clear();
 		if (LLInventoryPanel::getActiveInventoryPanel())
 		{
-			mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+			std::set<LLFolderViewItem*> selection =    LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+			for (std::set<LLFolderViewItem*>::iterator it = selection.begin(),    end_it = selection.end();
+				it != end_it;
+				++it)
+			{
+				mSelectedItems.insert((*it)->getListener()->getUUID());
+			}
 		}
 		mSelectedItems.erase(mMoveIntoFolderID);
 	}
@@ -849,7 +855,15 @@ private:
 		}
 
 		// get selected items (without destination folder)
-		selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList();
+		selected_items_t selected_items;
+ 		
+ 		std::set<LLFolderViewItem*> selection =    LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+		for (std::set<LLFolderViewItem*>::iterator it = selection.begin(),    end_it = selection.end();
+			it != end_it;
+			++it)
+		{
+			selected_items.insert((*it)->getListener()->getUUID());
+		}
 		selected_items.erase(mMoveIntoFolderID);
 
 		// compare stored & current sets of selected items
-- 
cgit v1.2.3


From 379eec8841212665881569c69804fafd96152387 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 15 Jun 2012 13:35:39 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose continuing fixing
 build errors renamed llfoldervieweventlistener.h to llfolderviewmodel.h

---
 indra/newview/CMakeLists.txt                       |   2 +-
 indra/newview/llavataractions.cpp                  |   4 +-
 indra/newview/llfloateroutbox.cpp                  |   2 +-
 indra/newview/llfolderview.cpp                     |  38 +--
 indra/newview/llfolderview.h                       |   5 +-
 indra/newview/llfoldervieweventlistener.h          | 294 -------------------
 indra/newview/llfolderviewitem.cpp                 | 290 ++++++++-----------
 indra/newview/llfolderviewitem.h                   |  67 ++---
 indra/newview/llfolderviewmodel.h                  | 313 +++++++++++++++++++++
 indra/newview/llinventorybridge.cpp                | 104 +++----
 indra/newview/llinventorybridge.h                  |  30 +-
 indra/newview/llinventoryfilter.cpp                |  31 +-
 indra/newview/llinventoryfilter.h                  |  33 +--
 indra/newview/llinventoryfunctions.cpp             |   2 +-
 indra/newview/llinventorypanel.cpp                 |  50 ++--
 indra/newview/llinventorypanel.h                   |  86 +++---
 indra/newview/llpanellandmarks.cpp                 |  40 +--
 indra/newview/llpanelmaininventory.cpp             |  22 +-
 indra/newview/llpanelmarketplaceinbox.cpp          |   2 +-
 .../newview/llpanelmarketplaceoutboxinventory.cpp  |   2 +-
 indra/newview/llpanelobjectinventory.cpp           |   8 +-
 indra/newview/llpaneloutfitedit.cpp                |   8 +-
 indra/newview/llplacesinventorypanel.cpp           |   4 +-
 indra/newview/llsidepanelappearance.cpp            |   2 +-
 indra/newview/llsidepanelinventory.cpp             |   4 +-
 indra/newview/lltexturectrl.cpp                    |   4 +-
 26 files changed, 688 insertions(+), 759 deletions(-)
 delete mode 100644 indra/newview/llfoldervieweventlistener.h
 create mode 100644 indra/newview/llfolderviewmodel.h

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 785bf4b868..4f447fd35b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -808,7 +808,7 @@ set(viewer_HEADER_FILES
     llfloaterwindowsize.h
     llfloaterworldmap.h
     llfolderview.h
-    llfoldervieweventlistener.h
+    llfolderviewmodel.h
     llfolderviewitem.h
     llfollowcam.h
     llfriendcard.h
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index decfef2ae6..68dc7681cc 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -778,7 +778,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 	const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
 	for (; it != it_end; ++it)
 	{
-		LLViewerInventoryCategory* inv_cat = gInventory.getCategory((*it)->getListener()->getUUID());
+		LLViewerInventoryCategory* inv_cat = gInventory.getCategory((*it)->getItemViewModel()->getUUID());
 		// any category can be offered.
 		if (inv_cat)
 		{
@@ -788,7 +788,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 		// check if inventory item can be given
 		LLFolderViewItem* item = *it;
 		if (!item) return false;
-		LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getListener());
+		LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getViewModelItem());
 		if (bridge && bridge->canShare())
 		{
 			continue;
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index ba0f51b467..04a55b261c 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -251,7 +251,7 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
 	
 	// Set the sort order newest to oldest
 
-	mOutboxInventoryPanel->getViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
+	mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
 	mOutboxInventoryPanel->getFilter()->markDefault();
 	
 	fetchOutboxContents();
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 1f48ef98f6..918e68e444 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -304,7 +304,7 @@ BOOL LLFolderView::canFocusChildren() const
 BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 {
 	// enforce sort order of My Inventory followed by Library
-	if (folder->getListener()->getUUID() == gInventory.getLibraryRootFolderID())
+	if (folder->getViewModelItem()->getUUID() == gInventory.getLibraryRootFolderID())
 	{
 		mFolders.push_back(folder);
 	}
@@ -366,7 +366,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
 
 static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory");
 
-void LLFolderView::filter( LLInventoryFilter& filter )
+void LLFolderView::filter( LLFolderViewFilter& filter )
 {
 	LLFastTimer t2(FTM_FILTER);
 	filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
@@ -667,7 +667,7 @@ BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source)
 		{
 			EDragAndDropType type = DAD_NONE;
 			LLUUID id = LLUUID::null;
-			can_drag = can_drag && (*item_it)->getListener()->startDrag(&type, &id);
+			can_drag = can_drag && (*item_it)->getViewModelItem()->startDrag(&type, &id);
 
 			types.push_back(type);
 			cargo_ids.push_back(id);
@@ -947,7 +947,7 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 
 			for(S32 i = 0; i < count; ++i)
 			{
-				listener = items[i]->getListener();
+				listener = items[i]->getViewModelItem();
 				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItemInventory*>::FAIL))
 				{
 					listeners.put(listener);
@@ -984,7 +984,7 @@ void LLFolderView::openSelectedItems( void )
 				// IT_{OBJECT,ATTACHMENT} creates LLProperties
 				// floaters; others create LLPreviews.  Put
 				// each one in the right type of container.
-				LLFolderViewModelItemInventory* listener = (*item_it)->getListener();
+				LLFolderViewModelItemInventory* listener = (*item_it)->getViewModelItem();
 				bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
 				if (is_prop)
 					LLFloater::setFloaterHost(multi_propertiesp);
@@ -1010,7 +1010,7 @@ void LLFolderView::propertiesSelectedItems( void )
 		{
 			LLFolderViewItem* folder_item = mSelectedItems.front();
 			if(!folder_item) return;
-			folder_item->getListener()->showProperties();
+			folder_item->getViewModelItem()->showProperties();
 		}
 		else
 		{
@@ -1021,7 +1021,7 @@ void LLFolderView::propertiesSelectedItems( void )
 			selected_items_t::iterator item_it;
 			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 			{
-				(*item_it)->getListener()->showProperties();
+				(*item_it)->getViewModelItem()->showProperties();
 			}
 
 			LLFloater::setFloaterHost(NULL);
@@ -1124,7 +1124,7 @@ BOOL LLFolderView::canCopy() const
 	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 	{
 		const LLFolderViewItem* item = *selected_it;
-		if (!item->getListener()->isItemCopyable())
+		if (!item->getViewModelItem()->isItemCopyable())
 		{
 			return FALSE;
 		}
@@ -1144,7 +1144,7 @@ void LLFolderView::copy()
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
-			listener = (*item_it)->getListener();
+			listener = (*item_it)->getViewModelItem();
 			if(listener)
 			{
 				listener->copyToClipboard();
@@ -1164,7 +1164,7 @@ BOOL LLFolderView::canCut() const
 	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 	{
 		const LLFolderViewItem* item = *selected_it;
-		const LLFolderViewModelItemInventory* listener = item->getListener();
+		const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
 
 		if (!listener || !listener->isItemRemovable())
 		{
@@ -1185,7 +1185,7 @@ void LLFolderView::cut()
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
-			listener = (*item_it)->getListener();
+			listener = (*item_it)->getViewModelItem();
 			if(listener)
 			{
 				listener->cutToClipboard();
@@ -1210,11 +1210,11 @@ BOOL LLFolderView::canPaste() const
 		{
 			// *TODO: only check folders and parent folders of items
 			const LLFolderViewItem* item = (*item_it);
-			const LLFolderViewModelItemInventory* listener = item->getListener();
+			const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
 			if(!listener || !listener->isClipboardPasteable())
 			{
 				const LLFolderViewFolder* folderp = item->getParentFolder();
-				listener = folderp->getListener();
+				listener = folderp->getViewModelItem();
 				if (!listener || !listener->isClipboardPasteable())
 				{
 					return FALSE;
@@ -1238,7 +1238,7 @@ void LLFolderView::paste()
 		for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 		{
 			LLFolderViewItem* item = *selected_it;
-			LLFolderViewModelItemInventory* listener = item->getListener();
+			LLFolderViewModelItemInventory* listener = item->getViewModelItem();
 			if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
 			{
 				item = item->getParentFolder();
@@ -1271,8 +1271,8 @@ void LLFolderView::startRenamingSelectedItem( void )
 	{
 		item = mSelectedItems.front();
 	}
-	if(getVisible() && getEnabled() && (count == 1) && item && item->getListener() &&
-	   item->getListener()->isItemRenameable())
+	if(getVisible() && getEnabled() && (count == 1) && item && item->getViewModelItem() &&
+	   item->getViewModelItem()->isItemRenameable())
 	{
 		mRenameItem = item;
 
@@ -1581,7 +1581,7 @@ BOOL LLFolderView::canDoDelete() const
 
 	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 	{
-		if (!(*item_it)->getListener()->isItemRemovable())
+		if (!(*item_it)->getViewModelItem()->isItemRemovable())
 		{
 			return FALSE;
 		}
@@ -1766,7 +1766,7 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	// when drop is not handled by child, it should be handled
 	// by the folder which is the hierarchy root.
 	if (!handled
-		&& getListener()->getUUID().notNull())
+		&& getViewModelItem()->getUUID().notNull())
 		{
 			handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 		}
@@ -1930,7 +1930,7 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
 	{
 		LLFolderViewItem* folder_item = *set_iter;
 		if(!folder_item) continue;
-		LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
+		LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
 		if(!bridge) continue;
 		bridge->performAction(model, action);
 	}
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 37005f080f..9b8a629387 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -111,7 +111,7 @@ public:
 
 	virtual LLFolderView*	getRoot() { return this; }
 
-	LLFolderViewModelInterface* getViewModel() { return mViewModel; }
+	LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; }
 
 	void setFilterPermMask(PermissionMask filter_perm_mask);
 	
@@ -272,8 +272,6 @@ protected:
 
 	void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response);
 
-	LLInventorySort& getSortFunction() { return mSortFunction; }
-
 protected:
 	LLHandle<LLView>					mPopupMenuHandle;
 	
@@ -318,7 +316,6 @@ protected:
 	
 	LLPanel*						mParentPanel;
 	
-	LLInventorySort					mSortFunction;
 	LLFolderViewModelInterface*		mViewModel;
 
 	/**
diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h
deleted file mode 100644
index 76e051d12f..0000000000
--- a/indra/newview/llfoldervieweventlistener.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/** 
- * @file llfoldervieweventlistener.h
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-#ifndef LLFOLDERVIEWEVENTLISTENER_H
-#define LLFOLDERVIEWEVENTLISTENER_H
-
-#include "lldarray.h"	// *TODO: convert to std::vector
-#include "llfoldertype.h"
-#include "llfontgl.h"	// just for StyleFlags enum
-#include "llinventorytype.h"
-#include "llpermissionsflags.h"
-#include "llpointer.h"
-#include "llwearabletype.h"
-#include "lltooldraganddrop.h"
-
-// These are grouping of inventory types.
-// Order matters when sorting system folders to the top.
-enum EInventorySortGroup
-{
-	SG_SYSTEM_FOLDER,
-	SG_TRASH_FOLDER,
-	SG_NORMAL_FOLDER,
-	SG_ITEM
-};
-
-class LLFontGL;
-class LLInventoryModel;
-class LLMenuGL;
-class LLUIImage;
-class LLUUID;
-class LLFolderViewItem;
-class LLFolderViewFolder;
-
-class LLFolderViewFilter
-{
-public:
-	LLFolderViewFilter() {}
-	virtual ~LLFolderViewFilter() {}
-
-	// +-------------------------------------------------------------------+
-	// + Execution And Results
-	// +-------------------------------------------------------------------+
-	virtual bool 				check(const LLFolderViewItem* item) = 0;
-	virtual bool				check(const LLInventoryItem* item) = 0;
-	virtual bool				checkFolder(const LLFolderViewFolder* folder) const = 0;
-	virtual bool				checkFolder(const LLUUID& folder_id) const = 0;
-
-	virtual void 				setEmptyLookupMessage(const std::string& message) = 0;
-	const virtual std::string&	getEmptyLookupMessage() const = 0;
-
-	// +-------------------------------------------------------------------+
-	// + Status
-	// +-------------------------------------------------------------------+
-	virtual bool 				isActive() const = 0;
-	virtual bool 				isModified() const = 0;
-	virtual bool 				isModifiedAndClear() = 0;
-	virtual void 				clearModified() = 0;
-	virtual const std::string& 	getName() const = 0;
-	virtual const std::string& 	getFilterText() = 0;
-	//RN: this is public to allow system to externally force a global refilter
-	virtual void 				setModified(EFilterBehavior behavior = FILTER_RESTART) = 0;
-
-	// +-------------------------------------------------------------------+
-	// + Count
-	// +-------------------------------------------------------------------+
-	virtual void 				setFilterCount(S32 count) = 0;
-	virtual S32 				getFilterCount() const = 0;
-	virtual void 				decrementFilterCount() = 0;
-
-	// +-------------------------------------------------------------------+
-	// + Default
-	// +-------------------------------------------------------------------+
-	virtual BOOL 				isNotDefault() const = 0;
-	virtual void 				markDefault() = 0;
-	virtual void 				resetDefault() = 0;
-
-	// +-------------------------------------------------------------------+
-	// + Generation
-	// +-------------------------------------------------------------------+
-	virtual S32 				getCurrentGeneration() const = 0;
-	virtual S32 				getFirstSuccessGeneration() const = 0;
-	virtual S32 				getFirstRequiredGeneration() const = 0;
-};
-
-struct LLFolderViewModelInterface
-{
-	virtual void requestSortAll() = 0;
-	virtual void requestSort(class LLFolderViewFolder*) = 0;
-
-	virtual void sort(class LLFolderViewFolder*) = 0;
-	virtual void filter(class LLFolderViewFolder*) = 0;
-};
-
-struct LLFolderViewModelCommon : public LLFolderViewModelInterface
-{
-	LLFolderViewModelCommon()
-	:	mTargetSortVersion(0)
-	{}
-
-	virtual void requestSortAll()
-	{
-		// sort everything
-		mTargetSortVersion++;
-	}
-
-	virtual void requestSort(class LLFolderViewFolder* folder)
-	{
-		folder->requestSort();
-	}
-	
-protected:
-	bool needsSort(class LLFolderViewModelItem* item)
-	{
-		return item->getSortVersion() < mTargetSortVersion;
-	}
-
-	S32 mTargetSortVersion;
-};
-
-
-// This is am abstract base class that users of the folderview classes
-// would use to bridge the folder view with the underlying data
-class LLFolderViewModelItem
-{
-public:
-	virtual ~LLFolderViewModelItem( void ) {};
-
-	virtual void update() {}	//called when drawing
-	virtual const std::string& getName() const = 0;
-	virtual const std::string& getDisplayName() const = 0;
-
-	virtual LLPointer<LLUIImage> getIcon() const = 0;
-	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
-
-	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
-	virtual std::string getLabelSuffix() const = 0;
-
-	virtual void openItem( void ) = 0;
-	virtual void closeItem( void ) = 0;
-	virtual void selectItem(void) = 0;
-
-	virtual BOOL isItemRenameable() const = 0;
-	virtual BOOL renameItem(const std::string& new_name) = 0;
-
-	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder
-	virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
-
-	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed
-	virtual BOOL removeItem() = 0;
-	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
-
-	virtual BOOL isItemCopyable() const = 0;
-	virtual BOOL copyToClipboard() const = 0;
-	virtual BOOL cutToClipboard() const = 0;
-
-	virtual BOOL isClipboardPasteable() const = 0;
-	virtual void pasteFromClipboard() = 0;
-	virtual void pasteLinkFromClipboard() = 0;
-
-	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
-	
-	// This method should be called when a drag begins. returns TRUE
-	// if the drag can begin, otherwise FALSE.
-	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
-	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
-	
-	// This method will be called to determine if a drop can be
-	// performed, and will set drop to TRUE if a drop is
-	// requested. Returns TRUE if a drop is possible/happened,
-	// otherwise FALSE.
-	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
-							EDragAndDropType cargo_type,
-							void* cargo_data,
-							std::string& tooltip_msg) = 0;
-
-	virtual void requestSort() = 0;
-	virtual S32 getSortVersion() = 0;
-	virtual void setSortVersion(S32 version) = 0;
-};
-
-class LLFolderViewModelItemCommon : public LLFolderViewModelItem
-{
-public:
-	LLFolderViewModelItemCommon()
-	:	mSortVersion(-1)
-	{}
-
-	void requestSort() { mSortVersion = -1; }
-	S32 getSortVersion() { return mSortVersion; }
-	void setSortVersion(S32 version) { mSortVersion = VERSION;}
-
-protected:
-	S32 mSortVersion;
-};
-
-template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
-class LLFolderViewModel : public LLFolderViewModelCommon
-{
-protected:
-	LLFolderViewModel() {}
-	
-	typedef SORT_TYPE		SortType;
-	typedef ITEM_TYPE		ItemType;
-	typedef FOLDER_TYPE		FolderType;
-	typedef FILTER_TYPE		FilterType;
-	
-	virtual const SortType& getSorter() const 		 { return mSorter; }
-	virtual void setSorter(const SortType& type) 	 { mSorter = sorter; requestSortAll(); }
-	virtual FilterType& getFilter() const 			 { return mFilter; }
-	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
-
-public:
-
-	struct ViewModelCompare()
-	{
-		ViewModelCompare(const SortType& sorter)
-		:	mSorter(sorter)
-		{}
-		
-		int operator () (const LLFolderViewItem* a, const LLFolderViewItem* b)
-		{
-			return mSorter(static_cast<const ItemType*>(a->getListener()), static_cast<const ItemType*>(b->getListener()));
-		}
-
-		int operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b)
-		{
-			return mSorter(static_cast<const ItemType*>(a->getListener()), static_cast<const ItemType*>(b->getListener()));
-		}
-
-		const SortType& mSorter;
-	}
-
-	void sort(LLFolderViewFolder* folder)
-	{
-		if (needsSort(folder))
-		{
-			std::sort(folder->getFoldersBegin(), folder->getFoldersEnd(), ViewModelCompare(getSorter()));
-			std::sort(folder->getItemsBegin(), folder->getItemsEnd(), ViewModelCompare(getSorter()));
-			folder->getListener()->setSortVersion(mTargetSortVersion);
-			folder->requestArrange();
-		}
-	}
-
-	void filter(LLFolderViewFolder* folder)
-	{
-		FilterType& filter = getFilter();
-		for (std::list<LLFolderViewItem*>::iterator it = folder->getItemsBegin(), end_it = folder->getItemsEnd();
-			it != end_it;
-			++it)
-		{
-			LLFolderViewItem* child_item = *it;
-			child_item->setFiltered(filter(static_cast<ItemType*>(child_item->getListener())), filter.getCurrentGeneration())
-		}
-
-		for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
-			it != end_it;
-			++it)
-		{
-			LLFolderViewItem* child_folder = *it;
-			child_folder->setFiltered(filter(static_cast<ItemType*>(child_folder->getListener())), filter.getCurrentGeneration())
-		}
-	}
-
-protected:
-	SortType	mSorter;
-	FilterType	mFilter;
-};
-
-
-
-
-
-#endif
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 13b721fa23..0a3c03e868 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -30,10 +30,9 @@
 // viewer includes
 #include "llfolderview.h"		// Items depend extensively on LLFolderViews
 #include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llviewerfoldertype.h"
 #include "llinventorybridge.h"	// for LLItemBridge in LLInventorySort::operator()
-#include "llinventoryfilter.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodelbackgroundfetch.h"
 #include "llpanel.h"
@@ -120,7 +119,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mItemHeight(p.item_height),
 	mPassedFilter(FALSE),
 	mLastFilterGeneration(-1),
-	mStringMatchOffset(std::string::npos),
+	//TODO RN: create interface for string highlighting
+	//mStringMatchOffset(std::string::npos),
 	mControlLabelRotation(0.f),
 	mDragAndDropTarget(FALSE),
 	mLabel(p.name),
@@ -218,7 +218,7 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
 BOOL LLFolderViewItem::potentiallyVisible()
 {
 	return getFiltered() // we've passed the filter
-		||	getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration()); // or we don't know yet
+		||	getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration(); // or we don't know yet
 }
 
 BOOL LLFolderViewItem::getFiltered() 
@@ -244,45 +244,17 @@ void LLFolderViewItem::setIcon(LLUIImagePtr icon)
 
 void LLFolderViewItem::refresh()
 {
-	if(!getListener()) return;
+	if(!getViewModelItem()) return;
 
-	mLabel = getListener()->getDisplayName();
-	LLFolderType::EType preferred_type = getListener()->getPreferredType();
+	mLabel = getViewModelItem()->getDisplayName();
 
-		// *TODO: to be removed when database supports multi language. This is a
-		// temporary attempt to display the inventory folder in the user locale.
-		// mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
-		//		it uses the same way to find localized string
-
-		// HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
-		// Translation of Accessories folder in Library inventory folder
-		bool accessories = false;
-		if(mLabel == std::string("Accessories"))
-		{
-			//To ensure that Accessories folder is in Library we have to check its parent folder.
-			//Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
-		LLInventoryCategory* cat = gInventory.getCategory(getListener()->getUUID());
-			if(cat)
-			{
-				const LLUUID& parent_folder_id = cat->getParentUUID();
-				accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
-			}
-		}
-
-		//"Accessories" inventory category has folder type FT_NONE. So, this folder
-		//can not be detected as protected with LLFolderType::lookupIsProtectedType
-		if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
-		{
-			LLTrans::findString(mLabel, "InvFolder " + mLabel);
-		};
-
-		setToolTip(mLabel);
-	setIcon(getListener()->getIcon());
-		if (mRoot->useLabelSuffix())
-		{
-		mLabelStyle = getListener()->getLabelStyle();
-		mLabelSuffix = getListener()->getLabelSuffix();
-}
+	setToolTip(mLabel);
+	setIcon(getViewModelItem()->getIcon());
+	if (mRoot->useLabelSuffix())
+	{
+		mLabelStyle = getViewModelItem()->getLabelStyle();
+		mLabelSuffix = getViewModelItem()->getLabelSuffix();
+	}
 
 	std::string searchable_label(mLabel);
 	searchable_label.append(mLabelSuffix);
@@ -381,7 +353,6 @@ BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 		return FALSE;
 	}
 	mParentFolder = folder;
-	root->addItemID(getListener()->getUUID(), this);
 	return folder->addItem(this);
 }
 
@@ -420,7 +391,7 @@ S32 LLFolderViewItem::getItemHeight()
 	return mItemHeight;
 }
 
-void LLFolderViewItem::filter( LLInventoryFilter& filter)
+void LLFolderViewItem::filter( LLFolderViewFilter& filter)
 {
 	const BOOL previous_passed_filter = mPassedFilter;
 	const BOOL passed_filter = filter.check(this);
@@ -435,7 +406,8 @@ void LLFolderViewItem::filter( LLInventoryFilter& filter)
 	}
 
 	setFiltered(passed_filter, filter.getCurrentGeneration());
-	mStringMatchOffset = filter.getStringMatchOffset(this);
+	//TODO RN: create interface for string highlighting
+	//mStringMatchOffset = filter.getStringMatchOffset(this);
 	filter.decrementFilterCount();
 
 	if (getRoot()->getDebugFilters())
@@ -498,9 +470,9 @@ void LLFolderViewItem::selectItem(void)
 {
 	if (mIsSelected == FALSE)
 	{
-		if (getListener())
+		if (getViewModelItem())
 		{
-			getListener()->selectItem();
+			getViewModelItem()->selectItem();
 		}
 		mIsSelected = TRUE;
 	}
@@ -508,9 +480,9 @@ void LLFolderViewItem::selectItem(void)
 
 BOOL LLFolderViewItem::isMovable()
 {
-	if( getListener() )
+	if( getViewModelItem() )
 	{
-		return getListener()->isItemMovable();
+		return getViewModelItem()->isItemMovable();
 	}
 	else
 	{
@@ -520,9 +492,9 @@ BOOL LLFolderViewItem::isMovable()
 
 BOOL LLFolderViewItem::isRemovable()
 {
-	if( getListener() )
+	if( getViewModelItem() )
 	{
-		return getListener()->isItemRemovable();
+		return getViewModelItem()->isItemRemovable();
 	}
 	else
 	{
@@ -548,9 +520,9 @@ BOOL LLFolderViewItem::remove()
 	{
 		return FALSE;
 	}
-	if(getListener())
+	if(getViewModelItem())
 	{
-		return getListener()->removeItem();
+		return getViewModelItem()->removeItem();
 	}
 	return TRUE;
 }
@@ -558,25 +530,17 @@ BOOL LLFolderViewItem::remove()
 // Build an appropriate context menu for the item.
 void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
-	if(getListener())
+	if(getViewModelItem())
 	{
-		getListener()->buildContextMenu(menu, flags);
+		getViewModelItem()->buildContextMenu(menu, flags);
 	}
 }
 
 void LLFolderViewItem::openItem( void )
 {
-	if( getListener() )
+	if( getViewModelItem() )
 	{
-		getListener()->openItem();
-	}
-}
-
-void LLFolderViewItem::preview( void )
-{
-	if (getListener())
-	{
-		getListener()->previewItem();
+		getViewModelItem()->openItem();
 	}
 }
 
@@ -584,9 +548,9 @@ void LLFolderViewItem::rename(const std::string& new_name)
 {
 	if( !new_name.empty() )
 	{
-		if( getListener() )
+		if( getViewModelItem() )
 		{
-			getListener()->renameItem(new_name);
+			getViewModelItem()->renameItem(new_name);
 
 			if(mParentFolder)
 			{
@@ -601,19 +565,13 @@ const std::string& LLFolderViewItem::getSearchableLabel() const
 	return mSearchableLabel;
 }
 
-LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)
-{
-	if (!getListener()) return NULL;
-	return gInventory.getItem(getListener()->getUUID());
-}
-
 const std::string& LLFolderViewItem::getName( void ) const
 {
-	if(getListener())
+	if(getViewModelItem())
 	{
-		return getListener()->getName();
+		return getViewModelItem()->getName();
 	}
-	return z;
+	return LLStringUtil::null;
 }
 
 // LLView functionality
@@ -689,9 +647,9 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 
 				// *TODO: push this into listener and remove
 				// dependency on llagent
-				if (getListener())
+				if (getViewModelItem())
 				{
-					src = getListener()->getDragSource();
+					src = getViewModelItem()->getDragSource();
 				}
 				else
 				{
@@ -701,7 +659,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 				can_drag = root->startDrag(src);
 				if (can_drag)
 				{
-					// if (getListener()) getListener()->startDrag();
+					// if (getViewModelItem()) getViewModelItem()->startDrag();
 					// RN: when starting drag and drop, clear out last auto-open
 					root->autoOpenTest(NULL);
 					root->setShowSelectionContext(TRUE);
@@ -738,7 +696,10 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 
 BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
 {
-	preview();
+	if (getViewModelItem())
+	{
+		getViewModelItem()->openItem();
+	}
 	return TRUE;
 }
 
@@ -790,9 +751,9 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 {
 	BOOL accepted = FALSE;
 	BOOL handled = FALSE;
-	if(getListener())
+	if(getViewModelItem())
 	{
-		accepted = getListener()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+		accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
 		handled = accepted;
 		if (accepted)
 		{
@@ -838,15 +799,12 @@ void LLFolderViewItem::draw()
 	const S32 FOCUS_LEFT = 1;
 	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
-	getListener()->update();
+	getViewModelItem()->update();
 
 	//--------------------------------------------------------------------------------//
 	// Draw open folder arrow
 	//
-	const bool up_to_date = getListener() && getListener()->isUpToDate();
-	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
-										|| (!up_to_date && getListener() && getListener()->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
-	if (possibly_has_children)
+	if (hasVisibleChildren() || getViewModelItem()->hasChildren())
 	{
 		LLUIImage* arrow_image = default_params.folder_arrow_image;
 		gl_draw_scaled_rotated_image(
@@ -943,25 +901,27 @@ void LLFolderViewItem::draw()
 		mDragAndDropTarget = FALSE;
 	}
 
-	const LLViewerInventoryItem *item = getInventoryItem();
-	const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType();
-	//--------------------------------------------------------------------------------//
-	// Draw open icon
-	//
-	const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
-	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
- 	{
-		mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
-	}
-	else if (mIcon)
-	{
- 		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
- 	}
+	//TODO RN: implement this in terms of getIcon() and getIconOverlay()
 
-	if (highlight_link)
-	{
-		mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
-	}
+	//const LLViewerInventoryItem *item = getInventoryItem();
+	//const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType();
+	////--------------------------------------------------------------------------------//
+	//// Draw open icon
+	////
+	//const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
+	//if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
+ //	{
+	//	mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
+	//}
+	//else if (mIcon)
+	//{
+ //		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+ //	}
+
+	//if (highlight_link)
+	//{
+	//	mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+	//}
 
 	//--------------------------------------------------------------------------------//
 	// Exit if no label to draw
@@ -972,8 +932,9 @@ void LLFolderViewItem::draw()
 	}
 
 	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
-	if (highlight_link) color = sLinkColor;
-	if (in_library) color = sLibraryColor;
+	//TODO RN: implement this in terms of getColor()
+	//if (highlight_link) color = sLinkColor;
+	//if (getViewModelItem() && gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
 
 	F32 right_x  = 0;
 	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
@@ -984,7 +945,7 @@ void LLFolderViewItem::draw()
 	//
 	if (getRoot()->getDebugFilters())
 	{
-		if (!getFiltered() && !possibly_has_children)
+		if (!getFiltered() && !getViewModelItem()->hasChildren())
 		{
 			color.mV[VALPHA] *= 0.5f;
 		}
@@ -1016,7 +977,7 @@ void LLFolderViewItem::draw()
 	//--------------------------------------------------------------------------------//
 	// Highlight string match
 	//
-	RN: expose interface for highlighting
+	//TODO RN: expose interface for highlighting
 	//if (mStringMatchOffset != std::string::npos)
 	//{
 	//	// don't draw backgrounds for zero-length strings
@@ -1098,7 +1059,7 @@ static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
 S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 {
 	// sort before laying out contents
-	getRoot->getViewModel()->sort(this);
+	getRoot()->getFolderViewModel()->sort(this);
 
 	LLFastTimer t2(FTM_ARRANGE);
 
@@ -1122,8 +1083,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 			for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
 			{
 				LLFolderViewFolder* folderp = (*fit);
-				found = ( folderp->getListener()
-								&&	(folderp->getFiltered(filter_generation)
+				found = ( (folderp->getFiltered(filter_generation)
 									 ||	(folderp->getFilteredFolder(filter_generation) 
 										 && folderp->hasFilteredDescendants(filter_generation))));
 				if (found)
@@ -1164,10 +1124,9 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 				}
 				else
 				{
-					folderp->setVisible( folderp->getListener()
-										&&	(folderp->getFiltered(filter_generation)
+					folderp->setVisible( folderp->getFiltered(filter_generation)
 											||	(folderp->getFilteredFolder(filter_generation) 
-												&& folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter
+												&& folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
 				}
 
 				if (folderp->getVisible())
@@ -1277,7 +1236,7 @@ BOOL LLFolderViewFolder::needsArrange()
 
 void LLFolderViewFolder::requestSort()
 {
-	getRoot()->getViewModel()->requestSort(this);
+	getRoot()->getFolderViewModel()->requestSort(this);
 }
 
 void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
@@ -1293,7 +1252,7 @@ void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recur
 	}
 }
 
-void LLFolderViewFolder::filter( LLInventoryFilter& filter)
+void LLFolderViewFolder::filter( LLFolderViewFilter& filter)
 {
 	S32 filter_generation = filter.getCurrentGeneration();
 	// if failed to pass filter newer than must_pass_generation
@@ -1301,7 +1260,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 	// check against items that have passed the filter
 	S32 must_pass_generation = filter.getFirstRequiredGeneration();
 	
-	bool autoopen_folders = (filter.hasFilterString());
+	bool autoopen_folders = filter.showAllResults();
 
 	// if we have already been filtered against this generation, skip out
 	if (getCompletedFilterGeneration() >= filter_generation)
@@ -1317,7 +1276,8 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 		{
 			// go ahead and flag this folder as done
 			mLastFilterGeneration = filter_generation;			
-			mStringMatchOffset = std::string::npos;
+			//TODO RN: create interface for string highlighting
+			//mStringMatchOffset = std::string::npos;
 		}
 		else // filter self only on first pass through
 		{
@@ -1351,15 +1311,6 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 		return;
 	}
 
-	// when applying a filter, matching folders get their contents downloaded first
-	if (filter.isNotDefault()
-		&& getFiltered(filter.getFirstSuccessGeneration())
-		&&	(getListener()
-			&& !gInventory.isCategoryComplete(getListener()->getUUID())))
-	{
-		LLInventoryModelBackgroundFetch::instance().start(getListener()->getUUID());
-	}
-
 	// now query children
 	for (folders_t::iterator iter = mFolders.begin();
 		 iter != mFolders.end();
@@ -1449,7 +1400,7 @@ void LLFolderViewFolder::filter( LLInventoryFilter& filter)
 	}
 }
 
-void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter)
+void LLFolderViewFolder::filterFolder(LLFolderViewFilter& filter)
 {
 	const BOOL previous_passed_filter = mPassedFolderFilter;
 	const BOOL passed_filter = filter.checkFolder(this);
@@ -1944,9 +1895,9 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
 
 BOOL LLFolderViewFolder::isMovable()
 {
-	if( getListener() )
+	if( getViewModelItem() )
 	{
-		if( !(getListener()->isItemMovable()) )
+		if( !(getViewModelItem()->isItemMovable()) )
 		{
 			return FALSE;
 		}
@@ -1977,9 +1928,9 @@ BOOL LLFolderViewFolder::isMovable()
 
 BOOL LLFolderViewFolder::isRemovable()
 {
-	if( getListener() )
+	if( getViewModelItem() )
 	{
-		if( !(getListener()->isItemRemovable()) )
+		if( !(getViewModelItem()->isItemRemovable()) )
 		{
 			return FALSE;
 		}
@@ -2023,7 +1974,7 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	requestArrange();
 	requestSort();
 
-	FIXME: RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
+	//TODO RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
 	//// Traverse parent folders and update creation date and resort, if necessary
 	//LLFolderViewFolder* parentp = this;
 	//while (parentp)
@@ -2052,16 +2003,7 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 	// rearrange all descendants too, as our indentation level might have changed
 	folder->requestArrange(TRUE);
 	requestSort();
-	if (getRoot()->getSortFunction().isByDate())
-	{
-	LLFolderViewFolder* parentp = getParentFolder();
-		while(parentp)
-	{
-		// parent folder doesn't have a time stamp yet, so get it from us
-		parentp->requestSort();
-		parentp = parentp->getParentFolder();
-	}
-	}
+
 	return TRUE;
 }
 
@@ -2100,15 +2042,15 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r
 {
 	BOOL was_open = isOpen();
 	mIsOpen = openitem;
-	if (getListener())
+	if (getViewModelItem())
 	{
 		if(!was_open && openitem)
 		{
-			getListener()->openItem();
+			getViewModelItem()->openItem();
 		}
 		else if(was_open && !openitem)
 		{
-			getListener()->closeItem();
+			getViewModelItem()->closeItem();
 		}
 	}
 
@@ -2229,7 +2171,7 @@ BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
 													   EAcceptance* accept,
 													   std::string& tooltip_msg)
 {
-	BOOL accepted = getListener() && getListener()->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
+	BOOL accepted = getViewModelItem() && getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
 	
 	if (accepted) 
 	{
@@ -2253,9 +2195,6 @@ BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
 BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
 {
 	BOOL handled = FALSE;
-	// fetch contents of this folder, as context menu can depend on contents
-	// still, user would have to open context menu again to see the changes
-	gInventory.fetchDescendentsOf(getListener()->getUUID());
 
 	if( isOpen() )
 	{
@@ -2311,11 +2250,11 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
 BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 {
 	/* Disable outfit double click to wear
-	const LLUUID &cat_uuid = getListener()->getUUID();
+	const LLUUID &cat_uuid = getViewModelItem()->getUUID();
 	const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
 	if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
 	{
-		getListener()->performAction(NULL, NULL,"replaceoutfit");
+		getViewModelItem()->performAction(NULL, NULL,"replaceoutfit");
 		return TRUE;
 	}
 	*/
@@ -2594,30 +2533,31 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a,
 {
 	// ignore sort order for landmarks in the Favorites folder.
 	// they should be always sorted as in Favorites bar. See EXT-719
-	if (a->getSortGroup() == SG_ITEM
-		&& b->getSortGroup() == SG_ITEM
-		&& a->getInventoryType() == LLInventoryType::IT_LANDMARK
-		&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
-	{
+	//TODO RN: fix sorting in favorites folder
+	//if (a->getSortGroup() == SG_ITEM
+	//	&& b->getSortGroup() == SG_ITEM
+	//	&& a->getInventoryType() == LLInventoryType::IT_LANDMARK
+	//	&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	//{
 
-		static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	//	static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
 
-		LLUUID a_uuid = a->getParentFolder()->getUUID();
-		LLUUID b_uuid = b->getParentFolder()->getUUID();
+	//	LLUUID a_uuid = a->getParentFolder()->getUUID();
+	//	LLUUID b_uuid = b->getParentFolder()->getUUID();
 
-		if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
-		{
-			// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
-			// or to LLInvFVBridge
-			LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a))->getItem();
-			LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b))->getItem();
-			if (!aitem || !bitem)
-				return false;
-			S32 a_sort = aitem->getSortField();
-			S32 b_sort = bitem->getSortField();
-			return a_sort < b_sort;
-		}
-	}
+	//	if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
+	//	{
+	//		// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
+	//		// or to LLInvFVBridge
+	//		LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a))->getItem();
+	//		LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b))->getItem();
+	//		if (!aitem || !bitem)
+	//			return false;
+	//		S32 a_sort = aitem->getSortField();
+	//		S32 b_sort = bitem->getSortField();
+	//		return a_sort < b_sort;
+	//	}
+	//}
 
 	// We sort by name if we aren't sorting by date
 	// OR if these are folders and we are sorting folders by name.
@@ -2645,7 +2585,7 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a,
 
 	if (by_name)
 	{
-		S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel());
+		S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
 		if (0 == compare)
 		{
 			return (a->getCreationDate() > b->getCreationDate());
@@ -2661,7 +2601,7 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a,
 		time_t second_create = b->getCreationDate();
 		if (first_create == second_create)
 		{
-			return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0);
+			return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0);
 		}
 		else
 		{
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index b7588223da..7bcc9dd0a2 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -31,11 +31,10 @@
 #include "lluiimage.h"
 
 class LLFolderView;
-class LLFolderViewModelItemInventory;
+class LLFolderViewModelItem;
 class LLFolderViewFolder;
 class LLFolderViewFunctor;
-class LLInventoryFilter;
-class LLViewerInventoryItem;
+class LLFolderViewFilter;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLFolderViewItem
@@ -57,8 +56,8 @@ public:
 													icon_overlay,  // for links
 													folder_arrow_image,
 													selection_image;
-		Optional<LLFolderView*>					root;
-		Mandatory<LLFolderViewModelItemInventory*>	listener;
+		Optional<LLFolderView*>						root;
+		Mandatory<LLFolderViewModelItem*>			listener;
 
 		Optional<S32>								folder_indentation, // pixels
 													item_height,
@@ -98,7 +97,7 @@ protected:
 	S32							mLabelWidth;
 	bool						mLabelWidthDirty;
 	LLFolderViewFolder*			mParentFolder;
-	LLFolderViewModelItemInventory*	mListener;
+	LLFolderViewModelItem*		mListener;
 	BOOL						mIsCurSelection;
 	BOOL						mSelectPending;
 	LLFontGL::StyleFlags		mLabelStyle;
@@ -112,7 +111,8 @@ protected:
 	S32							mItemHeight;
 	BOOL						mPassedFilter;
 	S32							mLastFilterGeneration;
-	std::string::size_type		mStringMatchOffset;
+	//TODO RN: create interface for string highlighting
+	//std::string::size_type		mStringMatchOffset;
 	F32							mControlLabelRotation;
 	LLFolderView*				mRoot;
 	BOOL						mDragAndDropTarget;
@@ -159,8 +159,8 @@ public:
 	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
 	virtual S32 getItemHeight();
 
-	// applies filters to control visibility of inventory items
-	virtual void filter( LLInventoryFilter& filter);
+	// applies filters to control visibility of items
+	virtual void filter( LLFolderViewFilter& filter);
 
 	// updates filter serial number and optionally propagated value up to root
 	S32		getLastFilterGeneration() { return mLastFilterGeneration; }
@@ -230,8 +230,8 @@ public:
 	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
 	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
 
-	const LLFolderViewModelItemInventory* getListener( void ) const { return mListener; }
-	LLFolderViewModelItemInventory* getListener( void ) { return mListener; }
+	const LLFolderViewModelItem* getViewModelItem( void ) const { return mListener; }
+	LLFolderViewModelItem* getViewModelItem( void ) { return mListener; }
 
 	// just rename the object.
 	void rename(const std::string& new_name);
@@ -277,41 +277,10 @@ public:
 		EAcceptance* accept,
 		std::string& tooltip_msg);
 
-	// Gets the inventory item if it exists (null otherwise)
-	LLViewerInventoryItem * getInventoryItem(void);
-	// open
-	virtual void preview(void);
-
 private:
 	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
 };
 
-class LLInventorySort
-{
-public:
-	LLInventorySort(U32 order)
-	:	mSortOrder(0),
-		mByDate(false),
-		mSystemToTop(false),
-		mFoldersByName(false)
-	{
-		mSortOrder = order;
-		mByDate = (order & LLInventoryFilter::SO_DATE);
-		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
-		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
-	}
-
-	bool isByDate() { return mByDate; }
-	U32 getSortOrder() { return mSortOrder; }
-
-	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b);
-private:
-	U32  mSortOrder;
-	bool mByDate;
-	bool mSystemToTop;
-	bool mFoldersByName;
-};
-
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLFolderViewFolder
 //
@@ -379,8 +348,8 @@ public:
 	BOOL hasFilteredDescendants(S32 filter_generation);
 	BOOL hasFilteredDescendants();
 
-	// applies filters to control visibility of inventory items
-	virtual void filter( LLInventoryFilter& filter);
+	// applies filters to control visibility of items
+	virtual void filter( LLFolderViewFilter& filter);
 	virtual void setFiltered(BOOL filtered, S32 filter_generation);
 	virtual BOOL getFiltered();
 	virtual BOOL getFiltered(S32 filter_generation);
@@ -388,7 +357,7 @@ public:
 	virtual void dirtyFilter();
 	
 	// folder-specific filtering (filter status propagates top down instead of bottom up)
-	void filterFolder(LLInventoryFilter& filter);
+	void filterFolder(LLFolderViewFilter& filter);
 	void setFilteredFolder(bool filtered, S32 filter_generation);
 	bool getFilteredFolder(S32 filter_generation);
 
@@ -496,12 +465,12 @@ public:
 	virtual void draw();
 
 
-	folders_t::iterator getFoldersBegin() const { return mFolders.begin(); }
-	folders_t::iterator getFoldersEnd() const { return mFolders.end(); }
+	folders_t::iterator getFoldersBegin() { return mFolders.begin(); }
+	folders_t::iterator getFoldersEnd() { return mFolders.end(); }
 	folders_t::size_type getFoldersCount() const { return mFolders.size(); }
 
-	items_t::iterator getItemsBegin() const { return mItems.begin(); }
-	items_t::iterator getItemsEnd() const { return mItems.end(); }
+	items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
+	items_t::const_iterator getItemsEnd() const { return mItems.end(); }
 	items_t::size_type getItemsCount() const { return mItems.size(); }
 
 	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
new file mode 100644
index 0000000000..b81a81f837
--- /dev/null
+++ b/indra/newview/llfolderviewmodel.h
@@ -0,0 +1,313 @@
+/** 
+ * @file llfolderviewmodel.h
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#ifndef LLFOLDERVIEWEVENTLISTENER_H
+#define LLFOLDERVIEWEVENTLISTENER_H
+
+#include "lldarray.h"	// *TODO: convert to std::vector
+#include "llfoldertype.h"
+#include "llfontgl.h"	// just for StyleFlags enum
+#include "llfolderviewitem.h"
+#include "llinventorytype.h"
+#include "llpermissionsflags.h"
+#include "llpointer.h"
+#include "llwearabletype.h"
+#include "lltooldraganddrop.h"
+
+// These are grouping of inventory types.
+// Order matters when sorting system folders to the top.
+enum EInventorySortGroup
+{
+	SG_SYSTEM_FOLDER,
+	SG_TRASH_FOLDER,
+	SG_NORMAL_FOLDER,
+	SG_ITEM
+};
+
+class LLFontGL;
+class LLInventoryModel;
+class LLMenuGL;
+class LLUIImage;
+class LLUUID;
+class LLFolderViewItem;
+class LLFolderViewFolder;
+
+class LLFolderViewFilter
+{
+public:
+	enum EFilterBehavior
+	{
+		FILTER_NONE,				// nothing to do, already filtered
+		FILTER_RESTART,				// restart filtering from scratch
+		FILTER_LESS_RESTRICTIVE,	// existing filtered items will certainly pass this filter
+		FILTER_MORE_RESTRICTIVE		// if you didn't pass the previous filter, you definitely won't pass this one
+	};
+
+public:
+
+	LLFolderViewFilter() {}
+	virtual ~LLFolderViewFilter() {}
+
+	// +-------------------------------------------------------------------+
+	// + Execution And Results
+	// +-------------------------------------------------------------------+
+	virtual bool 				check(const LLFolderViewItem* item) = 0;
+	virtual bool				check(const LLInventoryItem* item) = 0;
+	virtual bool				checkFolder(const LLFolderViewFolder* folder) const = 0;
+	virtual bool				checkFolder(const LLUUID& folder_id) const = 0;
+
+	virtual void 				setEmptyLookupMessage(const std::string& message) = 0;
+	const virtual std::string&	getEmptyLookupMessage() const = 0;
+
+	virtual bool				showAllResults() const = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Status
+	// +-------------------------------------------------------------------+
+	virtual bool 				isActive() const = 0;
+	virtual bool 				isModified() const = 0;
+	virtual bool 				isModifiedAndClear() = 0;
+	virtual void 				clearModified() = 0;
+	virtual const std::string& 	getName() const = 0;
+	virtual const std::string& 	getFilterText() = 0;
+	//RN: this is public to allow system to externally force a global refilter
+	virtual void 				setModified(EFilterBehavior behavior = FILTER_RESTART) = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Count
+	// +-------------------------------------------------------------------+
+	virtual void 				setFilterCount(S32 count) = 0;
+	virtual S32 				getFilterCount() const = 0;
+	virtual void 				decrementFilterCount() = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Default
+	// +-------------------------------------------------------------------+
+	virtual bool 				isDefault() const = 0;
+	virtual bool 				isNotDefault() const = 0;
+	virtual void 				markDefault() = 0;
+	virtual void 				resetDefault() = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Generation
+	// +-------------------------------------------------------------------+
+	virtual S32 				getCurrentGeneration() const = 0;
+	virtual S32 				getFirstSuccessGeneration() const = 0;
+	virtual S32 				getFirstRequiredGeneration() const = 0;
+};
+
+class LLFolderViewModelInterface
+{
+public:
+	virtual void requestSortAll() = 0;
+	virtual void requestSort(class LLFolderViewFolder*) = 0;
+
+	virtual void sort(class LLFolderViewFolder*) = 0;
+	virtual void filter(class LLFolderViewFolder*) = 0;
+};
+
+struct LLFolderViewModelCommon : public LLFolderViewModelInterface
+{
+	LLFolderViewModelCommon()
+	:	mTargetSortVersion(0)
+	{}
+
+	virtual void requestSortAll()
+	{
+		// sort everything
+		mTargetSortVersion++;
+	}
+
+	virtual void requestSort(class LLFolderViewFolder* folder)
+	{
+		folder->requestSort();
+	}
+	
+protected:
+	bool needsSort(class LLFolderViewModelItem* item);
+
+	S32 mTargetSortVersion;
+};
+
+// This is am abstract base class that users of the folderview classes
+// would use to bridge the folder view with the underlying data
+class LLFolderViewModelItem
+{
+public:
+	virtual ~LLFolderViewModelItem( void ) {};
+
+	virtual void update() {}	//called when drawing
+	virtual const std::string& getName() const = 0;
+	virtual const std::string& getDisplayName() const = 0;
+
+	virtual LLPointer<LLUIImage> getIcon() const = 0;
+	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
+
+	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
+	virtual std::string getLabelSuffix() const = 0;
+
+	virtual void openItem( void ) = 0;
+	virtual void closeItem( void ) = 0;
+	virtual void selectItem(void) = 0;
+
+	virtual BOOL isItemRenameable() const = 0;
+	virtual BOOL renameItem(const std::string& new_name) = 0;
+
+	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder
+	virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
+
+	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed
+	virtual BOOL removeItem() = 0;
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
+
+	virtual BOOL isItemCopyable() const = 0;
+	virtual BOOL copyToClipboard() const = 0;
+	virtual BOOL cutToClipboard() const = 0;
+
+	virtual BOOL isClipboardPasteable() const = 0;
+	virtual void pasteFromClipboard() = 0;
+	virtual void pasteLinkFromClipboard() = 0;
+
+	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
+	
+	// This method should be called when a drag begins. returns TRUE
+	// if the drag can begin, otherwise FALSE.
+	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
+	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
+	
+	virtual bool hasChildren() const = 0;
+
+	// This method will be called to determine if a drop can be
+	// performed, and will set drop to TRUE if a drop is
+	// requested. Returns TRUE if a drop is possible/happened,
+	// otherwise FALSE.
+	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+							EDragAndDropType cargo_type,
+							void* cargo_data,
+							std::string& tooltip_msg) = 0;
+
+	virtual void requestSort() = 0;
+	virtual S32 getSortVersion() = 0;
+	virtual void setSortVersion(S32 version) = 0;
+};
+
+class LLFolderViewModelItemCommon : public LLFolderViewModelItem
+{
+public:
+	LLFolderViewModelItemCommon()
+	:	mSortVersion(-1)
+	{}
+
+	void requestSort() { mSortVersion = -1; }
+	S32 getSortVersion() { return mSortVersion; }
+	void setSortVersion(S32 version) { mSortVersion = version;}
+
+protected:
+	S32 mSortVersion;
+};
+
+template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
+class LLFolderViewModel : public LLFolderViewModelCommon
+{
+protected:
+	LLFolderViewModel() {}
+	virtual ~LLFolderViewModel() {}
+	
+	typedef SORT_TYPE		SortType;
+	typedef ITEM_TYPE		ItemType;
+	typedef FOLDER_TYPE		FolderType;
+	typedef FILTER_TYPE		FilterType;
+	
+	virtual const SortType& getSorter() const 		 { return mSorter; }
+	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
+	virtual FilterType& getFilter()					 { return mFilter; }
+	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
+
+public:
+
+	struct ViewModelCompare
+	{
+		ViewModelCompare(const SortType& sorter)
+		:	mSorter(sorter)
+		{}
+		
+		int operator () (const LLFolderViewItem* a, const LLFolderViewItem* b)
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		int operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b)
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		const SortType& mSorter;
+	};
+
+	void sort(LLFolderViewFolder* folder)
+	{
+		if (needsSort(folder->getViewModelItem()))
+		{
+			std::sort(folder->getFoldersBegin(), folder->getFoldersEnd(), ViewModelCompare(getSorter()));
+			std::sort(folder->getItemsBegin(), folder->getItemsEnd(), ViewModelCompare(getSorter()));
+			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
+			folder->requestArrange();
+		}
+	}
+
+	//TODO RN: fix this
+	void filter(LLFolderViewFolder* folder)
+	{
+		/*FilterType& filter = getFilter();
+		for (std::list<LLFolderViewItem*>::const_iterator it = folder->getItemsBegin(), end_it = folder->getItemsEnd();
+			it != end_it;
+			++it)
+		{
+			LLFolderViewItem* child_item = *it;
+			child_item->setFiltered(filter.checkFolder(static_cast<ItemType*>(child_item->getViewModelItem())), filter.getCurrentGeneration());
+		}
+
+		for (std::list<LLFolderViewFolder*>::const_iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
+			it != end_it;
+			++it)
+		{
+			LLFolderViewItem* child_folder = *it;
+			child_folder->setFiltered(filter.check(static_cast<ItemType*>(child_folder->getViewModelItem())), filter.getCurrentGeneration());
+		}*/
+	}
+
+protected:
+	SortType	mSorter;
+	FilterType	mFilter;
+};
+
+
+bool LLFolderViewModelCommon::needsSort(class LLFolderViewModelItem* item)
+{
+	return item->getSortVersion() < mTargetSortVersion;
+}
+
+
+
+#endif
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d0d2215361..b51bbf7bfe 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -208,7 +208,11 @@ const std::string& LLInvFVBridge::getName() const
 
 const std::string& LLInvFVBridge::getDisplayName() const
 {
-	return getName();
+	if(mDisplayName.empty())
+	{
+		buildDisplayName();
+	}
+	return mDisplayName;
 }
 
 // Folders have full perms
@@ -1292,7 +1296,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 				void * cargo_data = (void *) obj;
 				std::string tooltip_msg;
 				
-				can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+				can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
 			}
 		}
 	}
@@ -1407,7 +1411,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		LLFolderViewItem* folder_view_itemp =   mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
 		if (!folder_view_itemp) return;
 
-		folder_view_itemp->getListener()->pasteFromClipboard();
+		folder_view_itemp->getViewModelItem()->pasteFromClipboard();
 		return;
 	}
 	else if ("paste_link" == action)
@@ -1419,7 +1423,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		LLFolderViewItem* folder_view_itemp =   mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
 		if (!folder_view_itemp) return;
 
-		folder_view_itemp->getListener()->pasteLinkFromClipboard();
+		folder_view_itemp->getViewModelItem()->pasteLinkFromClipboard();
 		return;
 	}
 	else if (isMarketplaceCopyAction(action))
@@ -1530,24 +1534,15 @@ PermissionMask LLItemBridge::getPermissionMask() const
 	return perm_mask;
 }
 
-const std::string& LLItemBridge::getDisplayName() const
+void LLItemBridge::buildDisplayName()
 {
-	if(mDisplayName.empty())
+	if(getItem())
 	{
-		buildDisplayName(getItem(), mDisplayName);
-	}
-	return mDisplayName;
-}
-
-void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name)
-{
-	if(item)
-	{
-		name.assign(item->getName());
+		mDisplayName.assign(getItem()->getName());
 	}
 	else
 	{
-		name.assign(LLStringUtil::null);
+		mDisplayName.assign(LLStringUtil::null);
 	}
 }
 
@@ -1665,11 +1660,11 @@ BOOL LLItemBridge::renameItem(const std::string& new_name)
 	{
 		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 		new_item->rename(new_name);
-		buildDisplayName(new_item, mDisplayName);
 		new_item->updateServer(FALSE);
 		model->updateItem(new_item);
 
 		model->notifyObservers();
+		buildDisplayName();
 	}
 	// return FALSE because we either notified observers (& therefore
 	// rebuilt) or we didn't update.
@@ -1821,9 +1816,37 @@ void LLFolderBridge::selectItem()
 	// Have no fear: the first thing start() does is to test if everything for that folder has been fetched...
 	LLInventoryModelBackgroundFetch::instance().start(getUUID(), true);
 }
-std::string& LLFolderBridge::getDisplayName() const
+
+void LLFolderBridge::buildDisplayName()
 {
-	return mDisplayName;
+	LLFolderType::EType preferred_type = getPreferredType();
+
+	// *TODO: to be removed when database supports multi language. This is a
+	// temporary attempt to display the inventory folder in the user locale.
+	// mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
+	//		it uses the same way to find localized string
+
+	// HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
+	// Translation of Accessories folder in Library inventory folder
+	bool accessories = false;
+	if(getName() == "Accessories")
+	{
+		//To ensure that Accessories folder is in Library we have to check its parent folder.
+		//Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
+		LLInventoryCategory* cat = gInventory.getCategory(getUUID());
+		if(cat)
+		{
+			const LLUUID& parent_folder_id = cat->getParentUUID();
+			accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
+		}
+	}
+
+	//"Accessories" inventory category has folder type FT_NONE. So, this folder
+	//can not be detected as protected with LLFolderType::lookupIsProtectedType
+	if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
+	{
+		LLTrans::findString(mDisplayName, "InvFolder " + getName());
+	};
 }
 
 
@@ -1884,11 +1907,11 @@ public:
 	LLIsItemRemovable() : mPassed(TRUE) {}
 	virtual void doFolder(LLFolderViewFolder* folder)
 	{
-		mPassed &= folder->getListener()->isItemRemovable();
+		mPassed &= folder->getViewModelItem()->isItemRemovable();
 	}
 	virtual void doItem(LLFolderViewItem* item)
 	{
-		mPassed &= item->getListener()->isItemRemovable();
+		mPassed &= item->getViewModelItem()->isItemRemovable();
 	}
 	BOOL mPassed;
 };
@@ -3084,7 +3107,7 @@ void LLFolderBridge::pasteFromClipboard()
 						void * cargo_data = (void *) item;
 						std::string tooltip_msg;
 
-						can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+						can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
 					}
 				}
 
@@ -3494,6 +3517,11 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
 	sSelf.markDead();
 
+	// fetch contents of this folder, as context menu can depend on contents
+	// still, user would have to open context menu again to see the changes
+	gInventory.fetchDescendentsOf(getUUID());
+
+
 	menuentry_vec_t items;
 	menuentry_vec_t disabled_items;
 
@@ -3510,7 +3538,7 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	menu.arrangeAndClear();
 }
 
-BOOL LLFolderBridge::hasChildren() const
+bool LLFolderBridge::hasChildren() const
 {
 	LLInventoryModel* model = getInventoryModel();
 	if(!model) return FALSE;
@@ -3802,9 +3830,9 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
 	LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
 	LLInventoryPanel* panel = mInventoryPanel.get();
 	LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
-	if (drag_over_item && drag_over_item->getListener())
+	if (drag_over_item && drag_over_item->getViewModelItem())
 	{
-		cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID());
+		cb.get()->setTargetLandmarkId(drag_over_item->getViewModelItem()->getUUID());
 	}
 
 	copy_inventory_item(
@@ -4004,7 +4032,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 				if (itemp)
 				{
 					LLUUID srcItemId = inv_item->getUUID();
-					LLUUID destItemId = itemp->getListener()->getUUID();
+					LLUUID destItemId = itemp->getViewModelItem()->getUUID();
 					gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId);
 				}
 			}
@@ -4394,15 +4422,6 @@ void LLSoundBridge::openItem()
 	}
 }
 
-void LLSoundBridge::previewItem()
-{
-	LLViewerInventoryItem* item = getItem();
-	if(item)
-	{
-		send_sound_trigger(item->getAssetUUID(), 1.0);
-	}
-}
-
 void LLSoundBridge::openSoundPreview(void* which)
 {
 	LLSoundBridge *me = (LLSoundBridge *)which;
@@ -5409,11 +5428,10 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name)
 	{
 		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 		new_item->rename(new_name);
-		buildDisplayName(new_item, mDisplayName);
 		new_item->updateServer(FALSE);
 		model->updateItem(new_item);
-
 		model->notifyObservers();
+		buildDisplayName();
 
 		if (isAgentAvatarValid())
 		{
@@ -6013,16 +6031,6 @@ void LLMeshBridge::openItem()
 	}
 }
 
-void LLMeshBridge::previewItem()
-{
-	LLViewerInventoryItem* item = getItem();
-	if(item)
-	{
-		// preview mesh
-	}
-}
-
-
 void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
 	lldebugs << "LLMeshBridge::buildContextMenu()" << llendl;
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 114144c8a4..bc5ac24c70 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -29,7 +29,7 @@
 
 #include "llcallingcard.h"
 #include "llfloaterproperties.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
 #include "llinventorypanel.h"
@@ -96,7 +96,6 @@ public:
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
 	virtual void openItem() {}
 	virtual void closeItem() {}
-	virtual void previewItem() {openItem();}
 	virtual void showProperties();
 	virtual BOOL isItemRenameable() const { return TRUE; }
 	//virtual BOOL renameItem(const std::string& new_name) {}
@@ -126,6 +125,8 @@ public:
 	virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
 	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
         EInventorySortGroup getSortGroup()  const { return SG_ITEM; }
+	virtual LLInventoryObject* getInventoryObject() const;
+
 
 	//--------------------------------------------------------------------
 	// Convenience functions for adding various common menu options.
@@ -142,7 +143,6 @@ protected:
 protected:
 	LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
 
-	LLInventoryObject* getInventoryObject() const;
 	LLInventoryModel* getInventoryModel() const;
 	LLInventoryFilter* getInventoryFilter() const;
 	
@@ -167,13 +167,16 @@ protected:
 									 BOOL restamp);
 	void removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch);
 protected:
-	LLHandle<LLInventoryPanel> mInventoryPanel;
-	LLFolderView* mRoot;
-	const LLUUID mUUID;	// item id
-	LLInventoryType::EType mInvType;
+	LLHandle<LLInventoryPanel>	mInventoryPanel;
+	LLFolderView*				mRoot;
+	const LLUUID				mUUID;	// item id
+	LLInventoryType::EType		mInvType;
 	bool						mIsLink;
 	LLTimer						mTimeSinceRequestStart;
+	mutable std::string			mDisplayName;
+
 	void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
+	virtual void buildDisplayName();
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -209,7 +212,6 @@ public:
 	virtual void restoreToWorld();
 	virtual void gotoItem();
 	virtual LLUIImagePtr getIcon() const;
-	virtual const std::string& getDisplayName() const;
 	virtual std::string getLabelSuffix() const;
 	virtual LLFontGL::StyleFlags getLabelStyle() const;
 	virtual PermissionMask getPermissionMask() const;
@@ -218,7 +220,7 @@ public:
 	virtual BOOL renameItem(const std::string& new_name);
 	virtual BOOL removeItem();
 	virtual BOOL isItemCopyable() const;
-	virtual BOOL hasChildren() const { return FALSE; }
+	virtual bool hasChildren() const { return FALSE; }
 	virtual BOOL isUpToDate() const { return TRUE; }
 
 	/*virtual*/ void clearDisplayName() { mDisplayName.clear(); }
@@ -228,9 +230,8 @@ public:
 protected:
 	BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
 	virtual BOOL isItemPermissive() const;
-	static void buildDisplayName(LLInventoryItem* item, std::string& name);
+	virtual void buildDisplayName();
 
-	mutable std::string mDisplayName;
 };
 
 class LLFolderBridge : public LLInvFVBridge
@@ -248,7 +249,7 @@ public:
 	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);
 	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg);
 
-        const std::string& getDisplayName() const;
+    virtual void buildDisplayName();
 
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual void openItem();
@@ -271,7 +272,7 @@ public:
 	virtual void pasteFromClipboard();
 	virtual void pasteLinkFromClipboard();
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-	virtual BOOL hasChildren() const;
+	virtual bool hasChildren() const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
 							void* cargo_data,
@@ -331,6 +332,7 @@ public:
 	static void staticFolderOptionsMenu();
 
 private:
+
 	bool							mCallingCards;
 	bool							mWearables;
 	bool							mIsLoading;
@@ -365,7 +367,6 @@ public:
 				  const LLUUID& uuid) :
 		LLItemBridge(inventory, root, uuid) {}
 	virtual void openItem();
-	virtual void previewItem();
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 	static void openSoundPreview(void*);
 };
@@ -555,7 +556,6 @@ class LLMeshBridge : public LLItemBridge
 public:
 	virtual LLUIImagePtr getIcon() const;
 	virtual void openItem();
-	virtual void previewItem();
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 
 protected:
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 5de3f0cb4e..1d25a7a1f9 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -29,7 +29,7 @@
 #include "llinventoryfilter.h"
 
 // viewer includes
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llfolderviewitem.h"
 #include "llinventorymodel.h"
 #include "llinventorymodelbackgroundfetch.h"
@@ -92,7 +92,7 @@ LLInventoryFilter::~LLInventoryFilter()
 BOOL LLInventoryFilter::check(const LLFolderViewItem* item) 
 {
 	// Clipboard cut items are *always* filtered so we need this value upfront
-	const LLFolderViewEventListener* listener = item->getListener();
+	const LLFolderViewEventListener* listener = item->getViewModelItem();
 	const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
 
 	// If it's a folder and we're showing all folders, return automatically.
@@ -140,7 +140,7 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
 		return false;
 	}
 
-	const LLFolderViewModelItemInventory* listener = folder->getListener();
+	const LLFolderViewModelItemInventory* listener = folder->getViewModelItem();
 	if (!listener)
 	{
 		llwarns << "Folder view event listener not found." << llendl;
@@ -155,6 +155,13 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
 
 bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 {
+	// when applying a filter, matching folders get their contents downloaded first
+	if (isNotDefault()
+		&& !gInventory.isCategoryComplete(getUUID())))
+	{
+		LLInventoryModelBackgroundFetch::instance().start(getViewModelItem()->getUUID());
+	}
+
 	// Always check against the clipboard
 	const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
 	
@@ -181,7 +188,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 
 BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
 {
-	const LLFolderViewModelItemInventory* listener = item->getListener();
+	const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
 	if (!listener) return FALSE;
 
 	LLInventoryType::EType object_type = listener->getInventoryType();
@@ -349,11 +356,11 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
 
 BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
 {
-	const LLFolderViewModelItemInventory* listener = item->getListener();
+	const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
 	if (!listener) return FALSE;
 
 	PermissionMask perm = listener->getPermissionMask();
-	const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getListener());
+	const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getViewModelItem());
 	if (bridge && bridge->isLink())
 	{
 		const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID());
@@ -377,7 +384,7 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) con
 
 BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
 {
-	const LLFolderViewModelItemInventory* listener = item->getListener();
+	const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
 	if (!listener) return TRUE;
 
 	const LLUUID object_id = listener->getUUID();
@@ -408,9 +415,9 @@ BOOL LLInventoryFilter::isDefault() const
 }
 
 // has user modified default filter params?
-BOOL LLInventoryFilter::isNotDefault() const
+bool LLInventoryFilter::isNotDefault() const
 {
-	BOOL not_default = FALSE;
+	bool not_default = FALSE;
 
 	not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
 	not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
@@ -1125,6 +1132,12 @@ LLInventoryFilter& LLInventoryFilter::operator=( const  LLInventoryFilter&  othe
 	fromParams(other.toParams());
 }
 
+bool LLInventoryFilter::showAllResults() const
+{
+	return hasFilterString();
+}
+
+
 
 bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool   emit_errors /*= true*/ )
 {
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 4434008958..746e9a2820 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -29,6 +29,7 @@
 
 #include "llinventorytype.h"
 #include "llpermissionsflags.h"
+#include "llfolderviewmodel.h"
 
 class LLFolderViewItem;
 class LLFolderViewFolder;
@@ -44,14 +45,6 @@ public:
 		SHOW_NO_FOLDERS
 	};
 
-	enum EFilterBehavior
-	{
-		FILTER_NONE,				// nothing to do, already filtered
-		FILTER_RESTART,				// restart filtering from scratch
-		FILTER_LESS_RESTRICTIVE,	// existing filtered items will certainly pass this filter
-		FILTER_MORE_RESTRICTIVE		// if you didn't pass the previous filter, you definitely won't pass this one
-	};
-
 	enum EFilterType	{
 		FILTERTYPE_NONE = 0,
 		FILTERTYPE_OBJECT = 0x1 << 0,	// normal default search-by-object-type
@@ -89,7 +82,7 @@ public:
 				max_date("max_date", time_max())
 			{}
 
-			bool validateBlock(bool emit_errors = true);
+			bool validateBlock(bool emit_errors = true) const;
 		};
 
 		struct Params : public LLInitParam::Block<Params>
@@ -200,6 +193,9 @@ public:
 	bool 				checkAgainstFilterLinks(const LLFolderViewItem* item) const;
 	bool				checkAgainstClipboard(const LLUUID& object_id) const;
 
+	bool				showAllResults() const;
+
+
 	std::string::size_type getStringMatchOffset() const;
 
 	std::string::size_type getStringMatchOffset(LLFolderViewItem* item)   const;
@@ -262,24 +258,6 @@ public:
 private:
 	bool				areDateLimitsSet();
 
-	struct FilterOps
-	{
-		FilterOps();
-		U32 			mFilterTypes;
-
-		U64				mFilterObjectTypes; // For _OBJECT
-		U64				mFilterWearableTypes;
-		U64				mFilterCategoryTypes; // For _CATEGORY
-		LLUUID      	mFilterUUID; // for UUID
-
-		time_t			mMinDate;
-		time_t			mMaxDate;
-		U32				mHoursAgo;
-		EFolderShow		mShowFolderState;
-		PermissionMask	mPermissions;
-		U64				mFilterLinks;
-	};
-
 	U32						mOrder;
 	U32 					mLastLogoff;
 
@@ -287,7 +265,6 @@ private:
 	FilterOps				mFilterOps;
 	FilterOps				mDefaultFilterOps;
 
-	std::string::size_type	mSubStringMatchOffset;
 	std::string				mFilterSubString;
 	std::string				mFilterSubStringOrig;
 	const std::string		mName;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index ab5b082915..1e494c3ef1 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -948,7 +948,7 @@ void LLSaveFolderState::setApply(BOOL apply)
 void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
 {
 	LLMemType mt(LLMemType::MTYPE_INVENTORY_DO_FOLDER);
-	LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
+	LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getViewModelItem();
 	if(!bridge) return;
 	
 	if(mApply)
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index d60b819da8..401daf6353 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -59,7 +59,7 @@ static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
 //
 // class LLFolderViewModelInventory
 //
-void LLFolderViewModelInventory::requestSort(class LLFolderViewFolder*   folder)
+void LLFolderViewModelInventory::requestSort(class LLFolderViewFolder* folder)
 {
 	base_t::requestSort(folder);
 	if (getSorter().isByDate())
@@ -78,7 +78,7 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 
 	if (!needsSort(folder)) return;
 
-	LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(folder->getListener());
+	LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem());
 	if (modelp->getUUID().isNull()) return;
 
 	for (std::list<LLFolderViewFolder*>::iterator it =   folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
@@ -91,8 +91,8 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 		if (child_folderp->getFoldersCount() > 0)
 		{
 			time_t most_recent_folder_time =
-				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getFoldersBegin()->getListener())->getCreationDate();
-			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getListener());
+				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getFoldersBegin()->getViewModelItem())->getCreationDate();
+			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
 			if (most_recent_folder_time > modelp->getCreationDate())
 			{
 				modelp->setCreationDate(most_recent_folder_time);
@@ -101,9 +101,9 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 		if (child_folderp->getItemsCount() > 0)			
 		{
 			time_t most_recent_item_time =
-				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getItemsBegin()->getListener())->getCreationDate();
+				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getItemsBegin()->getViewModelItem())->getCreationDate();
 
-			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getListener());
+			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
 			if (most_recent_item_time > modelp->getCreationDate())
 			{
 				modelp->setCreationDate(most_recent_item_time);
@@ -474,7 +474,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			if (view_item)
 			{
 				// Request refresh on this item (also flags for filtering)
-				LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getListener();
+				LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getViewModelItem();
 				if(bridge)
 				{	// Clear the display name first, so it gets properly re-built during refresh()
 					bridge->clearDisplayName();
@@ -493,7 +493,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			if (model_item && view_item)
 			{
 				view_item->destroyView();
-                                removeItemID(view_item->getListener()->getUUID());
+                                removeItemID(view_item->getViewModelItem()->getUUID());
 			}
 			view_item = buildNewViews(item_id);
 			view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
@@ -563,14 +563,14 @@ void LLInventoryPanel::modelChanged(U32 mask)
 							// Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
 							view_item->getParentFolder()->extractItem(view_item);
 							view_item->addToFolder(new_parent);
-							addItemID(view_item->getListener()->getUUID(), view_item);
+							addItemID(view_item->getViewModelItem()->getUUID(), view_item);
 						}
 						else 
 						{
 							// Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that 
 							// doesn't include trash).  Just remove the item's UI.
 							view_item->destroyView();
-                                                        removeItemID(view_item->getListener()->getUUID());
+                                                        removeItemID(view_item->getViewModelItem()->getUUID());
 						}
 					}
 				}
@@ -583,7 +583,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			{
 				// Remove the item's UI.
 				view_item->destroyView();
-                                removeItemID(view_item->getListener()->getUUID());
+                                removeItemID(view_item->getViewModelItem()->getUUID());
 			}
 		}
 	}
@@ -615,7 +615,7 @@ void LLInventoryPanel::onIdle(void *userdata)
 
 const LLUUID& LLInventoryPanel::getRootFolderID() const
 {
-	return mFolderRoot->getListener()->getUUID();
+	return mFolderRoot->getViewModelItem()->getUUID();
 }
 
 void LLInventoryPanel::initializeViews()
@@ -654,7 +654,7 @@ LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
 	if (old_view)
 	{
 		old_view->destroyView();
-                removeItemID(old_view->getListener()->getUUID());
+                removeItemID(old_view->getViewModelItem()->getUUID());
 	}
 
 	return buildNewViews(id);
@@ -727,7 +727,7 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
 LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 {
  	LLInventoryObject const* objectp = gInventory.getObject(id);
- 	LLUUID root_id = mFolderRoot->getListener()->getUUID();
+ 	LLUUID root_id = mFolderRoot->getViewModelItem()->getUUID();
  	LLFolderViewFolder* parent_folder = NULL;
 	LLFolderViewItem* itemp = NULL;
 	
@@ -786,7 +786,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   			if (itemp)
   			{
   				itemp->addToFolder(parent_folder);
-				addItemID(itemp->getListener()->getUUID(), itemp);
+				addItemID(itemp->getViewModelItem()->getUUID(), itemp);
    			}
 		}
 	}
@@ -836,8 +836,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
 	{
 		LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
 		if (fchild
-			&& fchild->getListener()
-				&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())
+			&& fchild->getViewModelItem()
+				&& fchild->getViewModelItem()->getUUID() == gInventory.getRootFolderID())
 		{
 			fchild->setOpen(TRUE);
 			break;
@@ -854,7 +854,7 @@ void LLInventoryPanel::openSelected()
 {
 	LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem();
 	if(!folder_item) return;
-	LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
+	LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
 	if(!bridge) return;
 	bridge->openItem();
 }
@@ -980,7 +980,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 	mCompletionObserver->reset();
 	for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it)
 	{
-		LLUUID id = (*it)->getListener()->getUUID();
+		LLUUID id = (*it)->getViewModelItem()->getUUID();
 		LLViewerInventoryItem* inv_item = mInventory->getItem(id);
 
 		if (inv_item && !inv_item->isFinished())
@@ -1028,11 +1028,11 @@ bool LLInventoryPanel::beginIMSession()
 			
 		if(folder_item) 
 		{
-			LLFolderViewEventListener* fve_listener = folder_item->getListener();
+			LLFolderViewEventListener* fve_listener = folder_item->getViewModelItem();
 			if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
 			{
 
-				LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener();
+				LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem();
 				if(!bridge) return true;
 				LLViewerInventoryCategory* cat = bridge->getCategory();
 				if(!cat) return true;
@@ -1066,7 +1066,7 @@ bool LLInventoryPanel::beginIMSession()
 			}
 			else
 			{
-				LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener();
+				LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getViewModelItem();
 
 				if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
 				{
@@ -1113,7 +1113,7 @@ bool LLInventoryPanel::attachObject(const LLSD& userdata)
 		 set_iter != selected_items.end(); 
 		 ++set_iter)
 	{
-		items.push_back((*set_iter)->getListener()->getUUID());
+		items.push_back((*set_iter)->getItemViewModel()->getUUID());
 	}
 
 	// Attach selected items.
@@ -1292,7 +1292,7 @@ LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
 LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id)
 {
 	LLFastTimer _(FTM_GET_ITEM_BY_ID);
-	if (id == mFolderRoot->getListener()->getUUID())
+	if (id == mFolderRoot->getViewModelItem()->getUUID())
 	{
 		return mFolderRoot;
 	}
@@ -1317,7 +1317,7 @@ LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)
 void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL    take_keyboard_focus )
 {
 	LLFolderViewItem* itemp = getItemByID(obj_id);
-	if(itemp && itemp->getListener())
+	if(itemp && itemp->getViewModelItem())
 	{
 		itemp->arrangeAndSet(TRUE, take_keyboard_focus);
 		mSelectThisID.setNull();
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 7cf82bf268..467c508aa0 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -39,25 +39,58 @@
 #include "lluictrlfactory.h"
 #include <set>
 
-class LLFolderView;
-class LLFolderViewFolder;
-class LLFolderViewItem;
-class LLInventoryFilter;
-class LLInventoryModel;
 class LLInvFVBridge;
 class LLInventoryFVBridgeBuilder;
-class LLMenuBarGL;
-class LLCheckBoxCtrl;
-class LLSpinCtrl;
-class LLTextBox;
-class LLIconCtrl;
-class LLSaveFolderState;
-class LLFilterEditor;
-class LLTabContainer;
 class LLInvPanelComplObserver;
 
+class LLFolderViewModelItemInventory
+	:	public LLFolderViewModelItemCommon
+{
+public:
+	virtual const LLUUID& getUUID() const = 0;
+	virtual time_t getCreationDate() const = 0;	// UTC seconds
+	virtual void setCreationDate(time_t creation_date_utc) = 0;
+	virtual PermissionMask getPermissionMask() const = 0;
+	virtual LLFolderType::EType getPreferredType() const = 0;
+	virtual void showProperties(void) = 0;
+	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual.
+	virtual BOOL isUpToDate() const = 0;
+	virtual bool hasChildren() const = 0;
+	virtual LLInventoryType::EType getInventoryType() const = 0;
+	virtual void performAction(LLInventoryModel* model, std::string action)   = 0;
+	virtual LLWearableType::EType getWearableType() const = 0;
+	virtual EInventorySortGroup getSortGroup() const = 0;
+	virtual LLInventoryObject* getInventoryObject() const = 0;
+};
+
+class LLInventorySort
+{
+public:
+	LLInventorySort(U32 order)
+		:	mSortOrder(0),
+		mByDate(false),
+		mSystemToTop(false),
+		mFoldersByName(false)
+	{
+		mSortOrder = order;
+		mByDate = (order & LLInventoryFilter::SO_DATE);
+		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+	}
+
+	bool isByDate() { return mByDate; }
+	U32 getSortOrder() { return mSortOrder; }
+
+	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b);
+private:
+	U32  mSortOrder;
+	bool mByDate;
+	bool mSystemToTop;
+	bool mFoldersByName;
+};
+
 class LLFolderViewModelInventory
-:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter>
+	:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter>
 {
 	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t;
 
@@ -200,8 +233,8 @@ public:
 	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
 	void updateSelection();
 	 	
-	LLFolderViewModelInventory* getViewModel() { return &mViewModel; }
-	const LLFolderViewModelInventory* getViewModel() const { return   &mViewModel; }
+	LLFolderViewModelInventory* getFolderViewModel() { return &mViewModel; }
+	const LLFolderViewModelInventory* getFolderViewModel() const { return   &mViewModel; }
 
 protected:
 	void openStartFolderOrMyInventory(); // open the first level of inventory
@@ -276,25 +309,4 @@ private:
 	LLUUID				mStartFolderID;
 };
 
-class LLFolderViewModelItemInventory
-	:	public LLFolderViewModelItemCommon
-{
-public:
-	virtual const LLUUID& getUUID() const = 0;
-	virtual time_t getCreationDate() const = 0;	// UTC seconds
-	virtual void setCreationDate(time_t creation_date_utc) = 0;
-	virtual PermissionMask getPermissionMask() const = 0;
-	virtual LLFolderType::EType getPreferredType() const = 0;
-	virtual void previewItem( void ) = 0;
-	virtual void showProperties(void) = 0;
-	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual.
-	virtual BOOL isUpToDate() const = 0;
-	virtual BOOL hasChildren() const = 0;
-	virtual LLInventoryType::EType getInventoryType() const = 0;
-	virtual void performAction(LLInventoryModel* model, std::string action)   = 0;
-	virtual LLWearableType::EType getWearableType() const = 0;
-	virtual EInventorySortGroup getSortGroup() const;
-	virtual void requestSort(const LLInventorySort& sorter);
-};
-
 #endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 234fa7590d..54ad2bcb76 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -102,7 +102,7 @@ void LLCheckFolderState::doFolder(LLFolderViewFolder* folder)
 	// Counting only folders that pass the filter.
 	// The listener check allow us to avoid counting the folder view
 	// object itself because it has no listener assigned.
-	if (folder->hasFilteredDescendants() && folder->getListener())
+	if (folder->hasFilteredDescendants() && folder->getViewModelItem())
 	{
 		if (folder->isOpen())
 		{
@@ -138,7 +138,7 @@ private:
 // virtual
 void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)
 {
-	if (folder->getListener() && folder->getListener()->getUUID() == mFolderID)
+	if (folder->getViewModelItem() && folder->getViewModelItem()->getUUID() == mFolderID)
 	{
 		if (!folder->isOpen())
 		{
@@ -286,7 +286,7 @@ void LLLandmarksPanel::onShowProfile()
 	if(!cur_item)
 		return;
 
-	cur_item->getListener()->performAction(mCurrentSelectedList->getModel(),"about");
+	cur_item->getViewModelItem()->performAction(mCurrentSelectedList->getModel(),"about");
 }
 
 // virtual
@@ -299,7 +299,7 @@ void LLLandmarksPanel::onTeleport()
 		return;
 	}
 
-	LLFolderViewModelItem* listenerp = current_item->getListener();
+	LLFolderViewModelItem* listenerp = current_item->getViewModelItem();
 	if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		listenerp->openItem();
@@ -360,7 +360,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()
 	LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
 	if (!cur_item) return;
 
-	LLFolderViewModelItem* listenerp = cur_item->getListener();
+	LLFolderViewModelItem* listenerp = cur_item->getViewModelItem();
 	if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		LLSD key;
@@ -418,7 +418,7 @@ void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_
 bool LLLandmarksPanel::isLandmarkSelected() const 
 {
 	LLFolderViewItem* current_item = getCurSelectedItem();
-	if(current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	if(current_item && current_item->getViewModelItem()->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		return true;
 	}
@@ -441,9 +441,9 @@ bool LLLandmarksPanel::isReceivedFolderSelected() const
 void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
 {
 	LLFolderViewItem* cur_item = getCurSelectedItem();
-	if(cur_item && cur_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	if(cur_item && cur_item->getViewModelItem()->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{ 
-		LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getListener()->getUUID(), cb);
+		LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getViewModelItem()->getUUID(), cb);
 		if (landmark)
 		{
 			cb(landmark);
@@ -510,7 +510,7 @@ void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)
 	{
 		LLFolderViewItem* cur_item = getCurSelectedItem();
 		if (!cur_item) return;
-		LLUUID id = cur_item->getListener()->getUUID();
+		LLUUID id = cur_item->getViewModelItem()->getUUID();
 		LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
 		doActionOnCurSelectedLandmark(boost::bind(
 				&LLLandmarksPanel::doProcessParcelInfo, this, _1, cur_item, inv_item, parcel_data));
@@ -738,7 +738,7 @@ void LLLandmarksPanel::onActionsButtonClick()
 		if(!cur_item)
 			return;
 
-		LLFolderViewModelItem* listenerp = cur_item->getListener();
+		LLFolderViewModelItem* listenerp = cur_item->getViewModelItem();
 		if(!listenerp)
 			return;
 
@@ -795,17 +795,17 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 		if (item && mCurrentSelectedList == mLandmarksInventoryPanel)
 		{
 			LLFolderViewModelItem* folder_bridge = NULL;
-			if (item-> getListener()->getInventoryType()
+			if (item-> getViewModelItem()->getInventoryType()
 					== LLInventoryType::IT_LANDMARK)
 			{
 				// for a landmark get parent folder bridge
-				folder_bridge = item->getParentFolder()->getListener();
+				folder_bridge = item->getParentFolder()->getViewModelItem();
 			}
-			else if (item-> getListener()->getInventoryType()
+			else if (item-> getViewModelItem()->getInventoryType()
 					== LLInventoryType::IT_CATEGORY)
 			{
 				// for a folder get its own bridge
-				folder_bridge = item->getListener();
+				folder_bridge = item->getViewModelItem();
 			}
 
 			menu_create_inventory_item(mCurrentSelectedList,
@@ -836,7 +836,7 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
 	{
     	LLFolderViewItem* cur_item = getCurSelectedItem();
 		if(cur_item)
-			LLLandmarkActions::copySLURLtoClipboard(cur_item->getListener()->getUUID());
+			LLLandmarkActions::copySLURLtoClipboard(cur_item->getViewModelItem()->getUUID());
 	}
 	else if ( "paste" == command_name)
 	{
@@ -1015,7 +1015,7 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 			LLFolderViewItem* cur_item = root_folder_view->getCurSelectedItem();
 			if (!cur_item) return false;
 
-			LLViewerInventoryItem* inv_item = cur_item->getInventoryItem();
+			LLViewerInventoryItem* inv_item = static_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem())->getInventoryObject());
 			if (!inv_item) return false;
 
 			LLUUID asset_uuid = inv_item->getAssetUUID();
@@ -1116,12 +1116,12 @@ void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)
 			// If no item is found it might be a folder id.
 			if (!item) continue;
 
-			LLFolderViewModelItem* listenerp = item->getListener();
+			LLFolderViewModelItem* listenerp = item->getViewModelItem();
 			if(!listenerp) continue;
 
 			// Trash category itself should not be included because it can't be
 			// actually restored from trash.
-			are_all_items_in_trash &= listenerp->isItemInTrash() &&    (*iter)->getListener()->getUUID() != trash_id;
+			are_all_items_in_trash &= listenerp->isItemInTrash() &&    (*iter)->getItemViewModel()->getUUID() != trash_id;
 
 			// If there are any selected items in Trash including the Trash category itself
 			// we show "Restore Item" in context menu and hide other irrelevant items.
@@ -1160,7 +1160,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 	bool can_be_modified = false;
 
 	// landmarks can be modified in any other accordion...
-	if (item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	if (item->getViewModelItem()->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		can_be_modified = true;
 
@@ -1198,7 +1198,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 
 	if (can_be_modified)
 	{
-		LLFolderViewModelItemInventory* listenerp = item->getListener();
+		LLFolderViewModelItemInventory* listenerp = item->getViewModelItem();
 
 		if ("cut" == command_name)
 		{
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index a7970bde24..fbdbce61bd 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -977,7 +977,7 @@ void LLPanelMainInventory::saveTexture(const LLSD& userdata)
 		return;
 	}
 	
-	const LLUUID& item_id = current_item->getListener()->getUUID();
+	const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
 	LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
 	if (preview_texture)
 	{
@@ -1050,7 +1050,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		const LLUUID item_id = current_item->getListener()->getUUID();
+		const LLUUID item_id = current_item->getViewModelItem()->getUUID();
 		LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item)
 		{
@@ -1065,7 +1065,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		current_item->getListener()->performAction(getActivePanel()->getModel(), "goto");
+		current_item->getViewModelItem()->performAction(getActivePanel()->getModel(), "goto");
 	}
 
 	if (command_name == "find_links")
@@ -1075,8 +1075,8 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		const LLUUID& item_id = current_item->getListener()->getUUID();
-		const std::string &item_name = current_item->getListener()->getName();
+		const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
+		const std::string &item_name = current_item->getViewModelItem()->getName();
 		mFilterSubString = item_name;
 		LLInventoryFilter *filter = mActivePanel->getFilter();
 		filter->setFilterSubString(item_name);
@@ -1094,11 +1094,11 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
 	LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
 	if (current_item) 
 	{
-		LLViewerInventoryItem *inv_item = current_item->getInventoryItem();
+		LLViewerInventoryItem *inv_item = dynamic_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryObject());
 		if(inv_item)
 		{
 			bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
-			LLInventoryType::EType curr_type = current_item->getListener()->getInventoryType();
+			LLInventoryType::EType curr_type = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryType();
 			return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
 		}
 	}
@@ -1123,7 +1123,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 			{
 				const LLUUID &item_id = (*iter);
 				LLFolderViewItem *item = *iter;
-				const LLFolderViewModelItemInventory *listener = item->getListener();
+				const LLFolderViewModelItemInventory *listener = item->getViewModelItem();
 				llassert(listener);
 				if (!listener) return FALSE;
 				can_delete &= listener->isItemRemovable();
@@ -1141,7 +1141,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	{
 		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
 		const LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item && item->getIsLinkType() && !item->getIsBrokenLink())
 		{
@@ -1157,7 +1157,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 		if (selection_set.size() != 1) return FALSE;
 		LLFolderViewItem* current_item = root->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
 		const LLInventoryObject *obj = gInventory.getObject(item_id);
 		if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
 		{
@@ -1170,7 +1170,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	{
 		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
 		const LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item && item->getIsBrokenLink())
 		{
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 6804342106..8a07d6d516 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -94,7 +94,7 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
 	mInventoryPanel->setShape(inventory_placeholder_rect);
 	
 	// Set the sort order newest to oldest
-	mInventoryPanel->getViewModel()->setSorter(LLInventoryFilter::SO_DATE);
+	mInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_DATE);
 	mInventoryPanel->getFilter()->markDefault();
 
 	// Set selection callback for proper update of inventory status buttons
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
index b5c7c4ca88..7db01d9059 100644
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
@@ -29,7 +29,7 @@
 #include "llpanelmarketplaceoutboxinventory.h"
 
 #include "llfolderviewitem.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 #include "llpanellandmarks.h"
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 3d7d9d573e..240c5b2da4 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -113,7 +113,6 @@ public:
 	virtual void openItem();
 	virtual BOOL canOpenItem() const { return FALSE; }
 	virtual void closeItem() {}
-	virtual void previewItem();
 	virtual void selectItem() {}
 	virtual BOOL isItemRenameable() const;
 	virtual BOOL renameItem(const std::string& new_name);
@@ -352,11 +351,6 @@ void LLTaskInvFVBridge::openItem()
 	lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
 }
 
-void LLTaskInvFVBridge::previewItem()
-{
-	openItem();
-}
-
 BOOL LLTaskInvFVBridge::isItemRenameable() const
 {
 	if(gAgent.isGodlike()) return TRUE;
@@ -1754,7 +1748,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 			}
 			view->addToFolder(folder);
-                        addItemID(view->getListener()->getUUID(), view);
+                        addItemID(view->getViewModelItem()->getUUID(), view);
 		}
 	}
 
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 4abc7fea0e..a95d27f992 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -270,7 +270,7 @@ private:
 
 		if (inventory_panel->getVisible())
 		{
-			inventory_panel->getViewModel()->setSorter(sort_order);
+			inventory_panel->getFolderViewModel()->setSorter(sort_order);
 		}
 		else
 		{
@@ -1310,7 +1310,7 @@ void LLPanelOutfitEdit::getCurrentItemUUID(LLUUID& selected_id)
 		LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
 		if (!curr_item) return;
 
-		LLFolderViewModelItemInventory* listenerp  = curr_item->getListener();
+		LLFolderViewModelItemInventory* listenerp  = curr_item->getViewModelItem();
 		if (!listenerp) return;
 
 		selected_id = listenerp->getUUID();
@@ -1332,7 +1332,7 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)
 			it != end_it;
 			++it)
 		{
-			uuid_list.push_back((*it)->getListener()->getUUID());
+			uuid_list.push_back((*it)->getItemViewModel()->getUUID());
 		}
 	}
 	else if (mWearablesListViewPanel->getVisible())
@@ -1384,7 +1384,7 @@ void LLPanelOutfitEdit::saveListSelection()
 
 		for (std::set<LLFolderViewItem*>::const_iterator item_id =    selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
 		{
-			mWearableItemsList->selectItemByUUID((*item_id)->getListener()->getUUID(),    true);
+			mWearableItemsList->selectItemByUUID((*item_id)->getItemViewModel()->getUUID(),    true);
 		}
 		mWearableItemsList->scrollToShowFirstSelectedItem();
 	}
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 1de26660bc..da5ce7d4b7 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -30,7 +30,7 @@
 
 #include "llplacesinventorypanel.h"
 
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llfolderview.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
@@ -162,7 +162,7 @@ BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	// then determine its type and set necessary menu handle
 	if (getCurSelectedItem())
 	{
-		LLInventoryType::EType inventory_type = getCurSelectedItem()->getListener()->getInventoryType();
+		LLInventoryType::EType inventory_type = getCurSelectedItem()->getViewModelItem()->getInventoryType();
 		inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
 
 		if (it_handle != mMenuHandlesByInventoryType.end())
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index f069da5869..194aa7f71b 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -38,7 +38,7 @@
 #include "llfiltereditor.h"
 #include "llfloaterreg.h"
 #include "llfloaterworldmap.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "lloutfitobserver.h"
 #include "llpaneleditwearable.h"
 #include "llpaneloutfitsinventory.h"
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index cc578b5799..f3d32e7a67 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -473,7 +473,7 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
 		}
 	}
 
-	current_item->getListener()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
+	current_item->getViewModelItem()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
 }
 
 void LLSidepanelInventory::onWearButtonClicked()
@@ -663,7 +663,7 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
 			return NULL;
 		}
 	}
-	const LLUUID &item_id = current_item->getListener()->getUUID();
+	const LLUUID &item_id = current_item->getViewModelItem()->getUUID();
 	LLInventoryItem *item = gInventory.getItem(item_id);
 	return item;
 }
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index ad2db966bd..a995f07df7 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -39,7 +39,7 @@
 #include "llfocusmgr.h"
 #include "llviewertexture.h"
 #include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llinventory.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodelbackgroundfetch.h"
@@ -800,7 +800,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
 	if (items.size())
 	{
 		LLFolderViewItem* first_item = items.front();
-		LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID());
+		LLInventoryItem* itemp = gInventory.getItem(first_item->getViewModelItem()->getUUID());
 		mNoCopyTextureSelected = FALSE;
 		if (itemp)
 		{
-- 
cgit v1.2.3


From b64fc84707a0ab4c11e84cf5caec32bbc267f313 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 18 Jun 2012 08:21:42 -0700
Subject: CHUI-145 : WIP Always open the message pane when clicking on a
 conversation in the list

---
 indra/llui/llmultifloater.cpp          | 2 +-
 indra/newview/llimfloatercontainer.cpp | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index 540ac74aee..6f0e691f10 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -173,7 +173,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
 	else if (floaterp->getHost())
 	{
 		// floaterp is hosted by somebody else and
-		// this is adding it, so remove it from it's old host
+		// this is adding it, so remove it from its old host
 		floaterp->getHost()->removeFloater(floaterp);
 	}
 	else if (floaterp->getParent() == gFloaterView)
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index af5d587f20..e8eae331a1 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -431,6 +431,8 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
 // Virtual action callbacks
 void LLConversationItem::selectItem(void)
 {
+    // Always expand the message pane in that case
+    mContainer->collapseMessagesPane(false);
     // Switch to the conversation floater that is being selected
     mContainer->selectFloater(mFloater);
 }
-- 
cgit v1.2.3


From bc5e0eda1b1b9c289734bebe6a533565aadfd3a2 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 18 Jun 2012 21:11:56 +0300
Subject: CHUI-119 fixed bug with creating multiply instances of the nearby
 chat;

---
 indra/newview/llimfloatercontainer.cpp | 3 +--
 indra/newview/llnearbychat.cpp         | 6 +-----
 indra/newview/llviewerwindow.cpp       | 2 +-
 3 files changed, 3 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index af5d587f20..8493a0e7b8 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -96,8 +96,7 @@ void LLIMFloaterContainer::onOpen(const LLSD& key)
 		// If there's *no* conversation open so far, we force the opening of the nearby chat conversation
 		// *TODO: find a way to move this to XML as a default panel or something like that
 		LLSD name("chat_bar");
-		LLSD key("");
-		LLFloaterReg::toggleInstanceOrBringToFront(name,key);
+		LLFloaterReg::toggleInstanceOrBringToFront(name);
 	}
 	/*
 	if (key.isDefined())
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index fbaf451412..e4b891889c 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -130,6 +130,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key)
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
 {
+	mKey = LLSD();
 	mIsNearbyChat = true;
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
 }
@@ -382,11 +383,6 @@ LLNearbyChat* LLNearbyChat::getInstance()
 	return LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar");
 }
 
-//static
-//LLNearbyChat* LLNearbyChat::findInstance()
-//{
-//	return LLFloaterReg::findTypedInstance<LLNearbyChat>("chat_bar");
-//}
 
 void LLNearbyChat::showHistory()
 {
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 7f14e021fd..016da1d994 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2555,7 +2555,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
-		LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar")->getChatBox();
+		LLLineEditor* chat_editor = LLNearbyChat::getInstance()->getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
-- 
cgit v1.2.3


From 7edcbb1613d30f9fecf3ccbe342d45b7761f5b56 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 18 Jun 2012 23:20:17 +0300
Subject: CHUI-100 WIP Fix translate chat checkbox showing

---
 indra/newview/llimconversation.cpp | 7 +++++++
 indra/newview/llimconversation.h   | 3 +++
 indra/newview/llnearbychat.cpp     | 4 ----
 indra/newview/llnearbychat.h       | 1 -
 4 files changed, 10 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 3e2b208874..ead87e3ed5 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -236,6 +236,13 @@ void LLIMConversation::updateHeaderAndToolbar()
 	mCloseBtn->setVisible(is_hosted);
 
 	enableDisableCallBtn();
+
+	showTranslationCheckbox();
+}
+
+void LLIMConversation::showTranslationCheckbox(BOOL show)
+{
+	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE);
 }
 
 // static
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index d31ae0808a..66401b9a3c 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -56,6 +56,9 @@ public:
 	 */
 	static bool isChatMultiTab();
 
+	// show/hide the translation check box
+	void showTranslationCheckbox(const BOOL visible = FALSE);
+
 	// LLFloater overrides
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index e4b891889c..1b2d9b6801 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -393,10 +393,6 @@ void LLNearbyChat::showHistory()
 	storeRectControl();
 }
 
-void LLNearbyChat::showTranslationCheckbox(BOOL show)
-{
-	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(show);
-}
 
 BOOL LLNearbyChat::tick()
 {
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index bc0e54de15..3dc94ce0da 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -87,7 +87,6 @@ public:
 	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
 
 	void showHistory();
-	void showTranslationCheckbox(BOOL show);
 
 protected:
 	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
-- 
cgit v1.2.3


From 06f142e974854854c91988b6a8bc5c6005a40731 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 18 Jun 2012 18:12:38 -0700
Subject: CHUI-145 : Select on list focus on relevant panel, torn off or not;
 torn off im stay in list; closed im suppressed from lits in all situations

---
 indra/newview/llimfloater.cpp          |  10 +++
 indra/newview/llimfloatercontainer.cpp | 117 +++++++++++++++++++--------------
 indra/newview/llimfloatercontainer.h   |   6 +-
 3 files changed, 81 insertions(+), 52 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 30a9c29ec6..14fcd602fc 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -139,6 +139,16 @@ void LLIMFloater::onClose(bool app_quitting)
 	// Last change:
 	// EXT-3516 X Button should end IM session, _ button should hide
 	gIMMgr->leaveSession(mSessionID);
+    
+	// Suppress the IM from the conversations list
+	if (LLIMConversation::isChatMultiTab())
+	{
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
+		if (im_box)
+		{
+            im_box->removeConversationListItem(mSessionID);
+        }
+    }
 }
 
 /* static */
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index e8eae331a1..bedf3315e8 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -129,24 +129,8 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 
 	LLUUID session_id = floaterp->getKey();
 
-	// CHUI-137 : Temporary implementation of conversations list
-	// Create a conversation item
-	LLConversationItem* item = new LLConversationItem(floaterp->getTitle(),session_id, floaterp, this);
-	mConversationsItems[session_id] = item;
-	// Create a widget from it
-	LLFolderViewItem* widget = createConversationItemWidget(item);
-	mConversationsWidgets[session_id] = widget;
-	// Add it to the UI
-	widget->setVisible(TRUE);
-	mConversationsListPanel->addChild(widget);
-	LLRect panel_rect = mConversationsListPanel->getRect();
-	S32 item_height = 16;
-	S32 index = mConversationsWidgets.size() - 1;
-	widget->setRect(LLRect(0,
-						   panel_rect.getHeight() - item_height*index,
-						   panel_rect.getWidth(),
-						   panel_rect.getHeight() - item_height*(index+1)));
-	// CHUI-137 : end
+	// Add a conversation list item in the left pane
+	addConversationListItem(floaterp->getTitle(), session_id, floaterp, this);
 	
 	LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
 
@@ -184,35 +168,6 @@ void LLIMFloaterContainer::removeFloater(LLFloater* floaterp)
 {
 	LLMultiFloater::removeFloater(floaterp);
 
-    // CHUI-137 : Temporary implementation of conversations list
-	// Clean up the conversations list
- 	LLUUID session_id = floaterp->getKey();
-    // Delete the widget and the associated conversation item
-    // Note : since the mConversationsItems is also the listener to the widget, deleting 
-    // the widget will also delete its listener
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(session_id);
-	if (widget_it != mConversationsWidgets.end())
-    {
-        LLFolderViewItem* widget = widget_it->second;
-        delete widget;
-    }
-    // Suppress the conversation items and widgets from their respective maps
-	mConversationsItems.erase(session_id);
-	mConversationsWidgets.erase(session_id);
-    // Reposition the leftover conversation items
-	LLRect panel_rect = mConversationsListPanel->getRect();
-	S32 item_height = 16;
-    int index = 0;
-    for (widget_it = mConversationsWidgets.begin(); widget_it != mConversationsWidgets.end(); ++widget_it, ++index)
-    {
-        LLFolderViewItem* widget = widget_it->second;
-        widget->setRect(LLRect(0,
-                               panel_rect.getHeight() - item_height*index,
-                               panel_rect.getWidth(),
-                               panel_rect.getHeight() - item_height*(index+1)));
-    }
-    // CHUI-137 : end
-   
 	LLRect contents_rect = floaterp->getRect();
 
 	// reduce the floater contents height by header height
@@ -399,6 +354,60 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
 }
 
 // CHUI-137 : Temporary implementation of conversations list
+void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp)
+{
+	// Create a conversation item
+	LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, containerp);
+	mConversationsItems[uuid] = item;
+
+	// Create a widget from it
+	LLFolderViewItem* widget = createConversationItemWidget(item);
+	mConversationsWidgets[uuid] = widget;
+
+	// Add it to the UI
+	widget->setVisible(TRUE);
+	mConversationsListPanel->addChild(widget);
+	LLRect panel_rect = mConversationsListPanel->getRect();
+	S32 item_height = 16;
+	S32 index = mConversationsWidgets.size() - 1;
+	widget->setRect(LLRect(0,
+						   panel_rect.getHeight() - item_height*index,
+						   panel_rect.getWidth(),
+						   panel_rect.getHeight() - item_height*(index+1)));
+	return;
+}
+
+void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id)
+{
+	// Delete the widget and the associated conversation item
+	// Note : since the mConversationsItems is also the listener to the widget, deleting 
+	// the widget will also delete its listener
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(session_id);
+	if (widget_it != mConversationsWidgets.end())
+	{
+		LLFolderViewItem* widget = widget_it->second;
+		delete widget;
+	}
+
+	// Suppress the conversation items and widgets from their respective maps
+	mConversationsItems.erase(session_id);
+	mConversationsWidgets.erase(session_id);
+
+	// Reposition the leftover conversation items
+	LLRect panel_rect = mConversationsListPanel->getRect();
+	S32 item_height = 16;
+	int index = 0;
+	for (widget_it = mConversationsWidgets.begin(); widget_it != mConversationsWidgets.end(); ++widget_it, ++index)
+	{
+		LLFolderViewItem* widget = widget_it->second;
+		widget->setRect(LLRect(0,
+							   panel_rect.getHeight() - item_height*index,
+							   panel_rect.getWidth(),
+							   panel_rect.getHeight() - item_height*(index+1)));
+	}
+	return;
+}
+
 LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
 {
 	LLFolderViewItem::Params params;
@@ -431,10 +440,16 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
 // Virtual action callbacks
 void LLConversationItem::selectItem(void)
 {
-    // Always expand the message pane in that case
-    mContainer->collapseMessagesPane(false);
-    // Switch to the conversation floater that is being selected
-    mContainer->selectFloater(mFloater);
+	LLMultiFloater* host_floater = mFloater->getHost();
+	if (host_floater == mContainer)
+	{
+		// Always expand the message pane if the panel is hosted by the container
+		mContainer->collapseMessagesPane(false);
+		// Switch to the conversation floater that is being selected
+		mContainer->selectFloater(mFloater);
+	}
+	// Set the focus on the selected floater
+	mFloater->setFocus(TRUE);    
 }
 
 void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index b5b60615b3..10268a5d79 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -142,7 +142,6 @@ public:
 
 	void collapseMessagesPane(bool collapse);
 	
-	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
@@ -168,6 +167,11 @@ private:
 	LLLayoutStack* mConversationsStack;
 	
 	// CHUI-137 : Temporary implementation of conversations list
+public:
+	void removeConversationListItem(const LLUUID& session_id);
+private:
+	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
+	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 	// Conversation list data
 	LLPanel* mConversationsListPanel;	// This is the widget we add items to (i.e. clickable title for each conversation)
 	conversations_items_map mConversationsItems;
-- 
cgit v1.2.3


From 59987bb051ed39146ec9b3831eec81434779a73f Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 18 Jun 2012 19:01:59 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose continuing fixing
 build errors general cleanup

---
 indra/newview/llfolderview.cpp           | 158 +++++++++++++--------------
 indra/newview/llfolderview.h             |  61 +++++++++++
 indra/newview/llfolderviewitem.cpp       |   2 +-
 indra/newview/llfolderviewitem.h         |   5 +
 indra/newview/llfolderviewmodel.h        |  25 +++--
 indra/newview/llinventorybridge.cpp      |   6 +-
 indra/newview/llinventoryfilter.cpp      | 157 ++++++++++++++-------------
 indra/newview/llinventoryfilter.h        |  20 ++--
 indra/newview/llinventoryfunctions.h     |  58 ----------
 indra/newview/llinventorypanel.cpp       | 181 ++++++++++++++-----------------
 indra/newview/llinventorypanel.h         |  20 ++--
 indra/newview/llpanelobjectinventory.cpp |   2 +-
 indra/newview/llsidepanelinventory.h     |   3 +-
 13 files changed, 342 insertions(+), 356 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 918e68e444..f0edbb638a 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -32,12 +32,8 @@
 #include "llcallbacklist.h"
 #include "llinventorybridge.h"
 #include "llclipboard.h" // *TODO: remove this once hack below gone.
-#include "llinventoryfilter.h"
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
 #include "llinventorypanel.h"
 #include "llfoldertype.h"
-#include "llfloaterinventory.h"// hacked in for the bonus context menu items.
 #include "llkeyboard.h"
 #include "lllineeditor.h"
 #include "llmenugl.h"
@@ -65,7 +61,6 @@
 #include "llfontgl.h"
 #include "llgl.h" 
 #include "llrender.h"
-#include "llinventory.h"
 
 // Third-party library includes
 #include <algorithm>
@@ -141,7 +136,7 @@ const LLRect LLFolderViewScrollContainer::getScrolledViewRect() const
 		LLFolderView* folder_view = dynamic_cast<LLFolderView*>(mScrolledView);
 		if (folder_view)
 		{
-			S32 height = folder_view->mRunningHeight;
+			S32 height = folder_view->getRect().getHeight();
 
 			rect = mScrolledView->getRect();
 			rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), height);
@@ -188,7 +183,7 @@ LLFolderView::LLFolderView(const Params& p)
 	mNeedsAutoRename(FALSE),
 	mDebugFilters(FALSE),
 	mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME),	// This gets overridden by a pref immediately
-	mFilter( new LLInventoryFilter(p.title) ),
+	mFilter(),
 	mShowSelectionContext(FALSE),
 	mShowSingleSelection(FALSE),
 	mArrangeGeneration(0),
@@ -304,7 +299,7 @@ BOOL LLFolderView::canFocusChildren() const
 BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 {
 	// enforce sort order of My Inventory followed by Library
-	if (folder->getViewModelItem()->getUUID() == gInventory.getLibraryRootFolderID())
+	if (((LLFolderViewModelItemInventory*)folder->getViewModelItem())->getUUID() == gInventory.getLibraryRootFolderID())
 	{
 		mFolders.push_back(folder);
 	}
@@ -364,7 +359,7 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
 	return llround(mTargetHeight);
 }
 
-static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory");
+static LLFastTimer::DeclareTimer FTM_FILTER("Filter Folder View");
 
 void LLFolderView::filter( LLFolderViewFilter& filter )
 {
@@ -392,7 +387,7 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
 		scroll_rect = mScrollContainer->getContentWindowRect();
 	}
 	width = llmax(mMinWidth, scroll_rect.getWidth());
-	height = llmax(mCurHeight, scroll_rect.getHeight());
+	height = llmax(llround(mCurHeight), scroll_rect.getHeight());
 
 	// Restrict width within scroll container's width
 	if (mUseEllipses && mScrollContainer)
@@ -645,7 +640,6 @@ void LLFolderView::clearSelection()
 	}
 
 	mSelectedItems.clear();
-	mSelectThisID.setNull();
 }
 
 std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const
@@ -735,9 +729,9 @@ void LLFolderView::draw()
 	}
 	else if (mShowEmptyMessage)
 	{
-		if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getFirstSuccessGeneration())
+		if (!mViewModel->contentsReady() || mCompletedFilterGeneration < mFilter->getFirstSuccessGeneration())
 		{
-			RN: Get this from filter
+			// TODO RN: Get this from filter
 			mStatusText = LLTrans::getString("Searching");
 		}
 		else
@@ -921,7 +915,7 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 		else if (count > 1)
 		{
 			LLDynamicArray<LLFolderViewModelItem*> listeners;
-			LLFolderViewModelItemInventory* listener;
+			LLFolderViewModelItem* listener;
 			LLFolderViewItem* last_item = items[count - 1];
 			LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
 			while(new_selection && new_selection->isSelected())
@@ -948,12 +942,12 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 			for(S32 i = 0; i < count; ++i)
 			{
 				listener = items[i]->getViewModelItem();
-				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItemInventory*>::FAIL))
+				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItem*>::FAIL))
 				{
 					listeners.put(listener);
 				}
 			}
-			listener = static_cast<LLFolderViewModelItemInventory*>(listeners.get(0));
+			listener = static_cast<LLFolderViewModelItem*>(listeners.get(0));
 			if(listener)
 			{
 				listener->removeBatch(listeners);
@@ -969,36 +963,37 @@ void LLFolderView::openSelectedItems( void )
 {
 	if(getVisible() && getEnabled())
 	{
-		if (mSelectedItems.size() == 1)
-		{
-			mSelectedItems.front()->openItem();
-		}
-		else
-		{
-			LLMultiPreview* multi_previewp = new LLMultiPreview();
-			LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-			selected_items_t::iterator item_it;
-			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-			{
-				// IT_{OBJECT,ATTACHMENT} creates LLProperties
-				// floaters; others create LLPreviews.  Put
-				// each one in the right type of container.
-				LLFolderViewModelItemInventory* listener = (*item_it)->getViewModelItem();
-				bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
-				if (is_prop)
-					LLFloater::setFloaterHost(multi_propertiesp);
-				else
-					LLFloater::setFloaterHost(multi_previewp);
-				(*item_it)->openItem();
-			}
-
-			LLFloater::setFloaterHost(NULL);
-			// *NOTE: LLMulti* will safely auto-delete when open'd
-			// without any children.
-			multi_previewp->openFloater(LLSD());
-			multi_propertiesp->openFloater(LLSD());
-		}
+		// TODO RN: move to LLFolderViewModelInventory
+		//if (mSelectedItems.size() == 1)
+		//{
+		//	mSelectedItems.front()->openItem();
+		//}
+		//else
+		//{
+		//	LLMultiPreview* multi_previewp = new LLMultiPreview();
+		//	LLMultiProperties* multi_propertiesp = new LLMultiProperties();
+
+		//	selected_items_t::iterator item_it;
+		//	for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+		//	{
+		//		// IT_{OBJECT,ATTACHMENT} creates LLProperties
+		//		// floaters; others create LLPreviews.  Put
+		//		// each one in the right type of container.
+		//		LLFolderViewModelItemInventory* listener = (*item_it)->getViewModelItem();
+		//		bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
+		//		if (is_prop)
+		//			LLFloater::setFloaterHost(multi_propertiesp);
+		//		else
+		//			LLFloater::setFloaterHost(multi_previewp);
+		//		(*item_it)->openItem();
+		//	}
+
+		//	LLFloater::setFloaterHost(NULL);
+		//	// *NOTE: LLMulti* will safely auto-delete when open'd
+		//	// without any children.
+		//	multi_previewp->openFloater(LLSD());
+		//	multi_propertiesp->openFloater(LLSD());
+		//}
 	}
 }
 
@@ -1006,27 +1001,28 @@ void LLFolderView::propertiesSelectedItems( void )
 {
 	if(getVisible() && getEnabled())
 	{
-		if (mSelectedItems.size() == 1)
-		{
-			LLFolderViewItem* folder_item = mSelectedItems.front();
-			if(!folder_item) return;
-			folder_item->getViewModelItem()->showProperties();
-		}
-		else
-		{
-			LLMultiProperties* multi_propertiesp = new LLMultiProperties();
+		// TODO RN: move to LLFolderViewModelInventory
+		//if (mSelectedItems.size() == 1)
+		//{
+		//	LLFolderViewItem* folder_item = mSelectedItems.front();
+		//	if(!folder_item) return;
+		//	folder_item->getViewModelItem()->showProperties();
+		//}
+		//else
+		//{
+		//	LLMultiProperties* multi_propertiesp = new LLMultiProperties();
 
-			LLFloater::setFloaterHost(multi_propertiesp);
+		//	LLFloater::setFloaterHost(multi_propertiesp);
 
-			selected_items_t::iterator item_it;
-			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-			{
-				(*item_it)->getViewModelItem()->showProperties();
-			}
+		//	selected_items_t::iterator item_it;
+		//	for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+		//	{
+		//		(*item_it)->getViewModelItem()->showProperties();
+		//	}
 
-			LLFloater::setFloaterHost(NULL);
-			multi_propertiesp->openFloater(LLSD());
-		}
+		//	LLFloater::setFloaterHost(NULL);
+		//	multi_propertiesp->openFloater(LLSD());
+		//}
 	}
 }
 
@@ -1140,7 +1136,7 @@ void LLFolderView::copy()
 	S32 count = mSelectedItems.size();
 	if(getVisible() && getEnabled() && (count > 0))
 	{
-		LLFolderViewModelItemInventory* listener = NULL;
+		LLFolderViewModelItem* listener = NULL;
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
@@ -1164,7 +1160,7 @@ BOOL LLFolderView::canCut() const
 	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 	{
 		const LLFolderViewItem* item = *selected_it;
-		const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
+		const LLFolderViewModelItem* listener = item->getViewModelItem();
 
 		if (!listener || !listener->isItemRemovable())
 		{
@@ -1181,7 +1177,7 @@ void LLFolderView::cut()
 	S32 count = mSelectedItems.size();
 	if(getVisible() && getEnabled() && (count > 0))
 	{
-		LLFolderViewModelItemInventory* listener = NULL;
+		LLFolderViewModelItem* listener = NULL;
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
@@ -1210,7 +1206,7 @@ BOOL LLFolderView::canPaste() const
 		{
 			// *TODO: only check folders and parent folders of items
 			const LLFolderViewItem* item = (*item_it);
-			const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
+			const LLFolderViewModelItem* listener = item->getViewModelItem();
 			if(!listener || !listener->isClipboardPasteable())
 			{
 				const LLFolderViewFolder* folderp = item->getParentFolder();
@@ -1232,24 +1228,24 @@ void LLFolderView::paste()
 	if(getVisible() && getEnabled())
 	{
 		// find set of unique folders to paste into
-		std::set<LLFolderViewItem*> folder_set;
+		std::set<LLFolderViewFolder*> folder_set;
 
 		selected_items_t::iterator selected_it;
 		for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 		{
 			LLFolderViewItem* item = *selected_it;
-			LLFolderViewModelItemInventory* listener = item->getViewModelItem();
-			if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
+			LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(item);
+			if (folder == NULL)
 			{
 				item = item->getParentFolder();
 			}
-			folder_set.insert(item);
+			folder_set.insert(folder);
 		}
 
-		std::set<LLFolderViewItem*>::iterator set_iter;
+		std::set<LLFolderViewFolder*>::iterator set_iter;
 		for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)
 		{
-			LLFolderViewModelItemInventory* listener = (*set_iter)->getListener();
+			LLFolderViewModelItem* listener = (*set_iter)->getViewModelItem();
 			if(listener && listener->isClipboardPasteable())
 			{
 				listener->pasteFromClipboard();
@@ -1765,15 +1761,9 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 
 	// when drop is not handled by child, it should be handled
 	// by the folder which is the hierarchy root.
-	if (!handled
-		&& getViewModelItem()->getUUID().notNull())
-		{
-			handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-		}
-
-	if (handled)
+	if (!handled)
 	{
-		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderView" << llendl;
+		handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 	}
 
 	return handled;
@@ -1996,7 +1986,7 @@ void LLFolderView::doIdle()
 
 		// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
 		// Used by LLPlacesFolderView.
-		if (mAutoSelectOverride && !mFilter->getFilterSubString().empty())
+		if (mAutoSelectOverride && mFilter->showAllResults())
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
@@ -2008,7 +1998,7 @@ void LLFolderView::doIdle()
 	}
 
 	BOOL filter_finished = mCompletedFilterGeneration >= mFilter->getCurrentGeneration() 
-						&& !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
+						&& mViewModel->contentsReady();
 	if (filter_finished 
 		|| gFocusMgr.childHasKeyboardFocus(inventory_panel) 
 		|| gFocusMgr.childHasMouseCapture(inventory_panel))
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 9b8a629387..813b4d130f 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -337,6 +337,67 @@ public:
 
 };
 
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewFunctor
+//
+// Simple abstract base class for applying a functor to folders and
+// items in a folder view hierarchy. This is suboptimal for algorithms
+// that only work folders or only work on items, but I'll worry about
+// that later when it's determined to be too slow.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLFolderViewFunctor
+{
+public:
+	virtual ~LLFolderViewFunctor() {}
+	virtual void doFolder(LLFolderViewFolder* folder) = 0;
+	virtual void doItem(LLFolderViewItem* item) = 0;
+};
+
+class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+{
+public:
+	LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
+	virtual ~LLSelectFirstFilteredItem() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+	BOOL wasItemSelected() { return mItemSelected; }
+protected:
+	BOOL mItemSelected;
+};
+
+class LLOpenFilteredFolders : public LLFolderViewFunctor
+{
+public:
+	LLOpenFilteredFolders()  {}
+	virtual ~LLOpenFilteredFolders() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+};
+
+class LLSaveFolderState : public LLFolderViewFunctor
+{
+public:
+	LLSaveFolderState() : mApply(FALSE) {}
+	virtual ~LLSaveFolderState() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item) {}
+	void setApply(BOOL apply);
+	void clearOpenFolders() { mOpenFolders.clear(); }
+protected:
+	std::set<LLUUID> mOpenFolders;
+	BOOL mApply;
+};
+
+class LLOpenFoldersWithSelection : public LLFolderViewFunctor
+{
+public:
+	LLOpenFoldersWithSelection() {}
+	virtual ~LLOpenFoldersWithSelection() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+};
+
 // Flags for buildContextMenu()
 const U32 SUPPRESS_OPEN_ITEM = 0x1;
 const U32 FIRST_SELECTED_ITEM = 0x2;
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 0a3c03e868..6e60ec5e1a 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -2529,7 +2529,7 @@ LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* it
 	return result;
 }
 
-bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b)
+bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
 {
 	// ignore sort order for landmarks in the Favorites folder.
 	// they should be always sorted as in Favorites bar. See EXT-719
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 7bcc9dd0a2..9e024d7eea 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -475,6 +475,11 @@ public:
 
 	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
 	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);
+
+public:
+	//WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
+	template<typename SORT_FUNC> void sortFolders(SORT_FUNC& func) { mFolders.sort(func); }
+	template<typename SORT_FUNC> void sortItems(SORT_FUNC& func) { mItems.sort(func); }
 };
 
 
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index b81a81f837..9bbd7f48cf 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -56,7 +56,7 @@ class LLFolderViewFolder;
 class LLFolderViewFilter
 {
 public:
-	enum EFilterBehavior
+	enum EFilterModified
 	{
 		FILTER_NONE,				// nothing to do, already filtered
 		FILTER_RESTART,				// restart filtering from scratch
@@ -78,7 +78,7 @@ public:
 	virtual bool				checkFolder(const LLUUID& folder_id) const = 0;
 
 	virtual void 				setEmptyLookupMessage(const std::string& message) = 0;
-	const virtual std::string&	getEmptyLookupMessage() const = 0;
+	virtual std::string			getEmptyLookupMessage() const = 0;
 
 	virtual bool				showAllResults() const = 0;
 
@@ -87,12 +87,11 @@ public:
 	// +-------------------------------------------------------------------+
 	virtual bool 				isActive() const = 0;
 	virtual bool 				isModified() const = 0;
-	virtual bool 				isModifiedAndClear() = 0;
 	virtual void 				clearModified() = 0;
 	virtual const std::string& 	getName() const = 0;
 	virtual const std::string& 	getFilterText() = 0;
 	//RN: this is public to allow system to externally force a global refilter
-	virtual void 				setModified(EFilterBehavior behavior = FILTER_RESTART) = 0;
+	virtual void 				setModified(EFilterModified behavior = FILTER_RESTART) = 0;
 
 	// +-------------------------------------------------------------------+
 	// + Count
@@ -125,6 +124,8 @@ public:
 
 	virtual void sort(class LLFolderViewFolder*) = 0;
 	virtual void filter(class LLFolderViewFolder*) = 0;
+
+	virtual bool contentsReady() = 0;
 };
 
 struct LLFolderViewModelCommon : public LLFolderViewModelInterface
@@ -230,7 +231,7 @@ protected:
 template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
 class LLFolderViewModel : public LLFolderViewModelCommon
 {
-protected:
+public:
 	LLFolderViewModel() {}
 	virtual ~LLFolderViewModel() {}
 	
@@ -239,12 +240,14 @@ protected:
 	typedef FOLDER_TYPE		FolderType;
 	typedef FILTER_TYPE		FilterType;
 	
+	virtual SortType& getSorter()					 { return mSorter; }
 	virtual const SortType& getSorter() const 		 { return mSorter; }
 	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
-	virtual FilterType& getFilter()					 { return mFilter; }
+	virtual FilterType& getFilter() 				 { return mFilter; }
+	virtual const FilterType& getFilter() const		 { return mFilter; }
 	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
 
-public:
+	virtual bool contentsReady()					{ return true; }
 
 	struct ViewModelCompare
 	{
@@ -252,12 +255,12 @@ public:
 		:	mSorter(sorter)
 		{}
 		
-		int operator () (const LLFolderViewItem* a, const LLFolderViewItem* b)
+		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b)
 		{
 			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
 		}
 
-		int operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b)
+		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b)
 		{
 			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
 		}
@@ -269,8 +272,8 @@ public:
 	{
 		if (needsSort(folder->getViewModelItem()))
 		{
-			std::sort(folder->getFoldersBegin(), folder->getFoldersEnd(), ViewModelCompare(getSorter()));
-			std::sort(folder->getItemsBegin(), folder->getItemsEnd(), ViewModelCompare(getSorter()));
+			folder->sortFolders(ViewModelCompare(getSorter()));
+			folder->sortItems(ViewModelCompare(getSorter()));
 			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
 			folder->requestArrange();
 		}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index b51bbf7bfe..312b7314a1 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -423,7 +423,7 @@ void  LLInvFVBridge::removeBatchNoCheck(std::vector<LLFolderViewModelItem*>&  ba
 
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
 		if(cat)
@@ -1275,7 +1275,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 
 		if (can_list)
 		{
-			LLFolderViewFolder * object_folderp =   mInventoryPanel->getFolderByID(object_id);
+			LLFolderViewFolder * object_folderp =   mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(object_id) : NULL;
 			if (object_folderp)
 			{
 				can_list = !object_folderp->isLoading();
@@ -1286,7 +1286,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 		{
 			// Get outbox id
 			const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
-			LLFolderViewItem * outbox_itemp =   mInventoryPanel->getItemByID(outbox_id);
+			LLFolderViewItem * outbox_itemp =   mInventoryPanel.get() ? mInventoryPanel.get()->getItemByID(outbox_id) : NULL;
 
 			if (outbox_itemp)
 			{
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 1d25a7a1f9..9c9b04d03d 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -42,6 +42,8 @@
 #include "llclipboard.h"
 #include "lltrans.h"
 
+//TODO RN: fix use of static cast as much as possible
+
 LLFastTimer::DeclareTimer FT_FILTER_CLIPBOARD("Filter Clipboard");
 
 LLInventoryFilter::FilterOps::FilterOps(const Params& p)
@@ -62,37 +64,27 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
 ///----------------------------------------------------------------------------
 /// Class LLInventoryFilter
 ///----------------------------------------------------------------------------
-LLInventoryFilter::LLInventoryFilter(const std::string& name, const   Params& p)
-:	mName(name),
-	mModified(FALSE),
-	mNeedTextRebuild(TRUE),
+LLInventoryFilter::LLInventoryFilter(const Params& p)
+:	mFilterModified(FILTER_NONE),
 	mEmptyLookupMessage("InventoryNoMatchingItems"),
-        mFilterOps(p.filter_ops)
+    mFilterOps(p.filter_ops),
+	mOrder(p.sort_order),
+	mFilterSubString(p.substring),
+	mLastSuccessGeneration(0),
+	mLastFailGeneration(S32_MAX),
+	mFirstSuccessGeneration(0),
+	mFilterCount(0)
 {
-	mOrder = p.sort_order; // This gets overridden by a pref immediately
-
-	mFilterSubString(p.substring);
-	mLastSuccessGeneration = 0;
-	mLastFailGeneration = S32_MAX;
-	getFirstSuccessGeneration = 0;
-	mFilterCount = 0;
 	mNextFilterGeneration = mLastSuccessGeneration + 1;
 
-	mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
-	mFilterBehavior = FILTER_NONE;
-
 	// copy mFilterOps into mDefaultFilterOps
 	markDefault();
 }
 
-LLInventoryFilter::~LLInventoryFilter()
-{
-}
-
-BOOL LLInventoryFilter::check(const LLFolderViewItem* item) 
+bool LLInventoryFilter::check(const LLFolderViewItem* item) 
 {
 	// Clipboard cut items are *always* filtered so we need this value upfront
-	const LLFolderViewEventListener* listener = item->getViewModelItem();
+	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 	const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
 
 	// If it's a folder and we're showing all folders, return automatically.
@@ -140,7 +132,7 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
 		return false;
 	}
 
-	const LLFolderViewModelItemInventory* listener = folder->getViewModelItem();
+	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(folder->getViewModelItem());
 	if (!listener)
 	{
 		llwarns << "Folder view event listener not found." << llendl;
@@ -157,9 +149,9 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 {
 	// when applying a filter, matching folders get their contents downloaded first
 	if (isNotDefault()
-		&& !gInventory.isCategoryComplete(getUUID())))
+		&& !gInventory.isCategoryComplete(folder_id))
 	{
-		LLInventoryModelBackgroundFetch::instance().start(getViewModelItem()->getUUID());
+		LLInventoryModelBackgroundFetch::instance().start(folder_id);
 	}
 
 	// Always check against the clipboard
@@ -186,9 +178,9 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 	return passed_clipboard;
 }
 
-BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
 {
-	const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
+	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 	if (!listener) return FALSE;
 
 	LLInventoryType::EType object_type = listener->getInventoryType();
@@ -354,9 +346,9 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
 	return true;
 }
 
-BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
 {
-	const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
+	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 	if (!listener) return FALSE;
 
 	PermissionMask perm = listener->getPermissionMask();
@@ -382,9 +374,9 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) con
 	return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
 }
 
-BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
 {
-	const LLFolderViewModelItemInventory* listener = item->getViewModelItem();
+	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 	if (!listener) return TRUE;
 
 	const LLUUID object_id = listener->getUUID();
@@ -409,7 +401,7 @@ std::string::size_type   LLInventoryFilter::getStringMatchOffset(LLFolderViewIte
 	return mFilterSubString.size() ? item->getName().find(mFilterSubString)   : std::string::npos;
 }
 
-BOOL LLInventoryFilter::isDefault() const
+bool LLInventoryFilter::isDefault() const
 {
 	return !isNotDefault();
 }
@@ -417,7 +409,7 @@ BOOL LLInventoryFilter::isDefault() const
 // has user modified default filter params?
 bool LLInventoryFilter::isNotDefault() const
 {
-	bool not_default = FALSE;
+	S32 not_default = 0;
 
 	not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
 	not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
@@ -430,10 +422,10 @@ bool LLInventoryFilter::isNotDefault() const
 	not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
 	not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
 
-	return not_default;
+	return not_default != 0;
 }
 
-BOOL LLInventoryFilter::isActive() const
+bool LLInventoryFilter::isActive() const
 {
 	return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL
 		|| mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL
@@ -447,16 +439,9 @@ BOOL LLInventoryFilter::isActive() const
 		|| mFilterOps.mHoursAgo != 0;
 }
 
-BOOL LLInventoryFilter::isModified() const
-{
-	return mModified;
-}
-
-BOOL LLInventoryFilter::isModifiedAndClear()
+bool LLInventoryFilter::isModified() const
 {
-	BOOL ret = mModified;
-	mModified = FALSE;
-	return ret;
+	return mFilterModified != FILTER_NONE;
 }
 
 void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
@@ -620,9 +605,10 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
 
 void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
 {
+	static LLCachedControl<U32> s_last_logoff(gSavedSettings, "LastLogoff", 0);
 	if (sl && !isSinceLogoff())
 	{
-		setDateRange(mLastLogoff, time_max());
+		setDateRange(s_last_logoff(), time_max());
 		setModified();
 	}
 	if (!sl && isSinceLogoff())
@@ -641,17 +627,18 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
 	}
 }
 
-BOOL LLInventoryFilter::isSinceLogoff() const
+bool LLInventoryFilter::isSinceLogoff() const
 {
-	return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
+	static LLCachedControl<U32> s_last_logoff(gSavedSettings, "LastLogoff", 0);
+
+	return (mFilterOps.mMinDate == (time_t)s_last_logoff()) &&
 		(mFilterOps.mMaxDate == time_max()) &&
 		(mFilterOps.mFilterTypes & FILTERTYPE_DATE);
 }
 
 void LLInventoryFilter::clearModified()
 {
-	mModified = FALSE; 
-	mFilterBehavior = FILTER_NONE;
+	mFilterModified = FILTER_NONE;
 }
 
 void LLInventoryFilter::setHoursAgo(U32 hours)
@@ -749,27 +736,26 @@ void LLInventoryFilter::resetDefault()
 	setModified();
 }
 
-void LLInventoryFilter::setModified(EFilterBehavior behavior)
+void LLInventoryFilter::setModified(EFilterModified behavior)
 {
-	mModified = TRUE;
-	mNeedTextRebuild = TRUE;
+	mFilterText.clear();
 	mLastSuccessGeneration = mNextFilterGeneration++;
 
-	if (mFilterBehavior == FILTER_NONE)
+	if (mFilterModified == FILTER_NONE)
 	{
-		mFilterBehavior = behavior;
+		mFilterModified = behavior;
 	}
-	else if (mFilterBehavior != behavior)
+	else if (mFilterModified != behavior)
 	{
 		// trying to do both less restrictive and more restrictive filter
 		// basically means restart from scratch
-		mFilterBehavior = FILTER_RESTART;
+		mFilterModified = FILTER_RESTART;
 	}
 
 	if (isNotDefault())
 	{
 		// if not keeping current filter results, update last valid as well
-		switch(mFilterBehavior)
+		switch(mFilterModified)
 		{
 			case FILTER_RESTART:
 				mLastFailGeneration = mLastSuccessGeneration;
@@ -791,29 +777,29 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)
 	else
 	{
 		// shortcut disabled filters to show everything immediately
-		mMinRequiredGeneration = 0;
-		mMustPassGeneration = S32_MAX;
+		mLastFailGeneration = 0;
+		mFirstSuccessGeneration = S32_MAX;
 	}
 }
 
-BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
+bool LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
 {
 	return mFilterOps.mFilterObjectTypes & (1LL << t);
 }
 
 const std::string& LLInventoryFilter::getFilterText()
 {
-	if (!mNeedTextRebuild)
+	if (!mFilterText.empty())
 	{
 		return mFilterText;
 	}
 
-	mNeedTextRebuild = FALSE;
 	std::string filtered_types;
 	std::string not_filtered_types;
 	BOOL filtered_by_type = FALSE;
 	BOOL filtered_by_all_types = TRUE;
 	S32 num_filter_types = 0;
+
 	mFilterText.clear();
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION))
@@ -998,9 +984,26 @@ const std::string& LLInventoryFilter::getFilterText()
 	return mFilterText;
 }
 
+
+LLInventoryFilter& LLInventoryFilter::operator=( const  LLInventoryFilter&  other )
+{
+	setFilterObjectTypes(other.getFilterObjectTypes());
+	setDateRange(other.getMinDate(), other.getMaxDate());
+	setHoursAgo(other.getHoursAgo());
+	setShowFolderState(other.getShowFolderState());
+	setFilterPermissions(other.getFilterPermissions());
+	setFilterSubString(other.getFilterSubString());
+	setSortOrder(other.getSortOrder());
+	setDateRangeLastLogoff(other.isSinceLogoff());
+	return *this;
+}
+
+
 void LLInventoryFilter::toParams(Params& params) const
-	{
+{
 	params.filter_ops.types = getFilterObjectTypes();
+	params.filter_ops.category_types = getFilterCategoryTypes();
+	params.filter_ops.wearable_types = getFilterWearableTypes();
 	params.filter_ops.date_range.min_date = getMinDate();
 	params.filter_ops.date_range.max_date = getMaxDate();
 	params.filter_ops.hours_ago = getHoursAgo();
@@ -1009,16 +1012,18 @@ void LLInventoryFilter::toParams(Params& params) const
 	params.substring = getFilterSubString();
 	params.sort_order = getSortOrder();
 	params.since_logoff = isSinceLogoff();
-	}
+}
 
-void LLInventoryFilter::fromParams(const Params& data)
-	{
+void LLInventoryFilter::fromParams(const Params& params)
+{
 	if (!params.validateBlock())
 	{
 		return;
 	}
 
 	setFilterObjectTypes(params.filter_ops.types);
+	setFilterCategoryTypes(params.filter_ops.category_types);
+	setFilterWearableTypes(params.filter_ops.wearable_types);
 	setDateRange(params.filter_ops.date_range.min_date,   params.filter_ops.date_range.max_date);
 	setHoursAgo(params.filter_ops.hours_ago);
 	setShowFolderState(params.filter_ops.show_folder_state);
@@ -1038,7 +1043,12 @@ U64 LLInventoryFilter::getFilterCategoryTypes() const
 	return mFilterOps.mFilterCategoryTypes;
 }
 
-BOOL LLInventoryFilter::hasFilterString() const
+U64 LLInventoryFilter::getFilterWearableTypes() const
+{
+	return mFilterOps.mFilterWearableTypes;
+}
+
+bool LLInventoryFilter::hasFilterString() const
 {
 	return mFilterSubString.size() > 0;
 }
@@ -1073,10 +1083,6 @@ U32 LLInventoryFilter::getSortOrder() const
 { 
 	return mOrder; 
 }
-const std::string& LLInventoryFilter::getName() const 
-{ 
-	return mName; 
-}
 
 void LLInventoryFilter::setFilterCount(S32 count) 
 { 
@@ -1110,8 +1116,8 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
 	mEmptyLookupMessage = message;
 }
 
-RN: turn this into a param
-const std::string& LLInventoryFilter::getEmptyLookupMessage() const
+// TODO RN: turn this into a param and move to llfolderviewmodelinterface
+std::string LLInventoryFilter::getEmptyLookupMessage() const
 {
 	LLStringUtil::format_map_t args;
 	args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
@@ -1127,11 +1133,6 @@ bool LLInventoryFilter::areDateLimitsSet()
 			|| mFilterOps.mHoursAgo != 0;
 }
 
-LLInventoryFilter& LLInventoryFilter::operator=( const  LLInventoryFilter&  other )
-{
-	fromParams(other.toParams());
-}
-
 bool LLInventoryFilter::showAllResults() const
 {
 	return hasFilterString();
@@ -1139,7 +1140,7 @@ bool LLInventoryFilter::showAllResults() const
 
 
 
-bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool   emit_errors /*= true*/ )
+bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool   emit_errors /*= true*/ ) const
 {
 	bool valid = LLInitParam::Block<DateRange>::validateBlock(emit_errors);
 	if (valid)
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 746e9a2820..e0c3d7141b 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -144,16 +144,18 @@ public:
 		{}
 	};
 									
-	LLInventoryFilter(const std::string& name, const Params& p);
-	virtual ~LLInventoryFilter();
+	LLInventoryFilter(const Params& p = Params());
+	LLInventoryFilter(const LLInventoryFilter& other) { *this = other; }
+	virtual ~LLInventoryFilter() {}
 
 	// +-------------------------------------------------------------------+
 	// + Parameters
 	// +-------------------------------------------------------------------+
-	void 				setFilterObjectTypes(U64 types);
 	U64 				getFilterObjectTypes() const;
 	U64					getFilterCategoryTypes() const;
+	U64					getFilterWearableTypes() const;
 	bool 				isFilterObjectTypesWith(LLInventoryType::EType t) const;
+	void 				setFilterObjectTypes(U64 types);
 	void 				setFilterCategoryTypes(U64 types);
 	void 				setFilterUUID(const LLUUID &object_id);
 	void				setFilterWearableTypes(U64 types);
@@ -209,20 +211,19 @@ public:
 	U32 				getSortOrder() const;
 
 	void 				setEmptyLookupMessage(const std::string& message);
-	const std::string&	getEmptyLookupMessage() const;
+	std::string			getEmptyLookupMessage() const;
 
 	// +-------------------------------------------------------------------+
 	// + Status
 	// +-------------------------------------------------------------------+
 	bool 				isActive() const;
 	bool 				isModified() const;
-	bool 				isModifiedAndClear();
 	bool 				isSinceLogoff() const;
 	void 				clearModified();
 	const std::string& 	getName() const;
 	const std::string& 	getFilterText();
 	//RN: this is public to allow system to externally force a global refilter
-	void 				setModified(EFilterBehavior behavior = FILTER_RESTART);
+	void 				setModified(EFilterModified behavior = FILTER_RESTART);
 
 	// +-------------------------------------------------------------------+
 	// + Count
@@ -259,15 +260,12 @@ private:
 	bool				areDateLimitsSet();
 
 	U32						mOrder;
-	U32 					mLastLogoff;
 
-	std::string::size_type	mSubStringMatchOffset;
 	FilterOps				mFilterOps;
 	FilterOps				mDefaultFilterOps;
 
 	std::string				mFilterSubString;
 	std::string				mFilterSubStringOrig;
-	const std::string		mName;
 
 	S32						mLastSuccessGeneration;
 	S32						mLastFailGeneration;
@@ -275,10 +273,8 @@ private:
 	S32						mNextFilterGeneration;
 
 	S32						mFilterCount;
-	EFilterBehavior 		mFilterBehavior;
+	EFilterModified 		mFilterModified;
 
-	BOOL 					mModified;
-	BOOL 					mNeedTextRebuild;
 	std::string 			mFilterText;
 	std::string 			mEmptyLookupMessage;
 };
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 5cf9c528b0..c6b1da0417 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -418,21 +418,6 @@ public:
 class LLFolderViewItem;
 class LLFolderViewFolder;
 
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFunctor
-//
-// Simple abstract base class for applying a functor to folders and
-// items in a folder view hierarchy. This is suboptimal for algorithms
-// that only work folders or only work on items, but I'll worry about
-// that later when it's determined to be too slow.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLFolderViewFunctor
-{
-public:
-	virtual ~LLFolderViewFunctor() {}
-	virtual void doFolder(LLFolderViewFolder* folder) = 0;
-	virtual void doItem(LLFolderViewItem* item) = 0;
-};
 
 class LLInventoryState
 {
@@ -442,49 +427,6 @@ public:
 	static LLUUID sWearNewClothingTransactionID;	// wear all clothing in this transaction	
 };
 
-class LLSelectFirstFilteredItem : public LLFolderViewFunctor
-{
-public:
-	LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
-	virtual ~LLSelectFirstFilteredItem() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-	BOOL wasItemSelected() { return mItemSelected; }
-protected:
-	BOOL mItemSelected;
-};
-
-class LLOpenFilteredFolders : public LLFolderViewFunctor
-{
-public:
-	LLOpenFilteredFolders()  {}
-	virtual ~LLOpenFilteredFolders() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-};
-
-class LLSaveFolderState : public LLFolderViewFunctor
-{
-public:
-	LLSaveFolderState() : mApply(FALSE) {}
-	virtual ~LLSaveFolderState() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item) {}
-	void setApply(BOOL apply);
-	void clearOpenFolders() { mOpenFolders.clear(); }
-protected:
-	std::set<LLUUID> mOpenFolders;
-	BOOL mApply;
-};
-
-class LLOpenFoldersWithSelection : public LLFolderViewFunctor
-{
-public:
-	LLOpenFoldersWithSelection() {}
-	virtual ~LLOpenFoldersWithSelection() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-};
 
 #endif // LL_LLINVENTORYFUNCTIONS_H
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 401daf6353..e739694fe0 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -76,7 +76,7 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 {
 	LLFastTimer _(FTM_INVENTORY_SORT);
 
-	if (!needsSort(folder)) return;
+	if (!needsSort(folder->getViewModelItem())) return;
 
 	LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem());
 	if (modelp->getUUID().isNull()) return;
@@ -91,7 +91,7 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 		if (child_folderp->getFoldersCount() > 0)
 		{
 			time_t most_recent_folder_time =
-				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getFoldersBegin()->getViewModelItem())->getCreationDate();
+				static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate();
 			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
 			if (most_recent_folder_time > modelp->getCreationDate())
 			{
@@ -101,7 +101,7 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 		if (child_folderp->getItemsCount() > 0)			
 		{
 			time_t most_recent_item_time =
-				static_cast<LLFolderViewModelItemInventory*>(child_folderp->getItemsBegin()->getViewModelItem())->getCreationDate();
+				static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate();
 
 			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
 			if (most_recent_item_time > modelp->getCreationDate())
@@ -113,6 +113,12 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 	base_t::sort(folder);
 }
 
+bool LLFolderViewModelInventory::contentsReady()
+{
+	return !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
+}
+
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInventoryPanelObserver
 //
@@ -243,6 +249,7 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
 																	root_id);
 	
 	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
+	addItemID(root_id, mFolderRoot);
 }
 
 void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
@@ -314,11 +321,11 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 
 LLInventoryPanel::~LLInventoryPanel()
 {
-        U32 sort_order = getViewModel()->getSortOrder();
-		if (mSortOrderSetting != INHERIT_SORT_ORDER)
-		{
-			gSavedSettings.setU32(mSortOrderSetting, sort_order);
-		}
+	U32 sort_order = getFolderViewModel()->getSorter().getSortOrder();
+	if (mSortOrderSetting != INHERIT_SORT_ORDER)
+	{
+		gSavedSettings.setU32(mSortOrderSetting, sort_order);
+	}
 
 	gIdleCallbacks.deleteFunction(onIdle, this);
 
@@ -346,14 +353,9 @@ void LLInventoryPanel::draw()
 	LLPanel::draw();
 }
 
-LLInventoryFilter* LLInventoryPanel::getFilter()
-{
-	return getViewModel()->getFilter();
-}
-
 const LLInventoryFilter* LLInventoryPanel::getFilter() const
 {
-	return getViewModel()->getFilter();
+	return &getFolderViewModel()->getFilter();
 }
 
 void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
@@ -400,9 +402,9 @@ void LLInventoryPanel::setSortOrder(U32 order)
 {
         LLInventorySort sorter(order);
 	getFilter()->setSortOrder(order);
-	if (order != getViewModel()->getSortOrder())
+	if (order != getFolderViewModel()->getSorter().getSortOrder())
 	{
-		getViewModel()->setSorter(LLInventorySort(order));
+		getFolderViewModel()->setSorter(LLInventorySort(order));
 		// try to keep selection onscreen, even if it wasn't to start with
 		mFolderRoot->scrollToShowSelection();
 	}
@@ -410,7 +412,7 @@ void LLInventoryPanel::setSortOrder(U32 order)
 
 U32 LLInventoryPanel::getSortOrder() const 
 { 
-	return getViewModel()->getSortOrder();
+	return getFolderViewModel()->getSorter().getSortOrder();
 }
 
 void LLInventoryPanel::setSinceLogoff(BOOL sl)
@@ -460,6 +462,8 @@ void LLInventoryPanel::modelChanged(U32 mask)
 		const LLUUID& item_id = (*items_iter);
 		const LLInventoryObject* model_item = model->getObject(item_id);
 		LLFolderViewItem* view_item = getItemByID(item_id);
+		LLFolderViewModelItemInventory* viewmodel_item = 
+			static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
 
 		// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
 		// to folder is the fast way to get a folder without searching through folders tree.
@@ -493,9 +497,11 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			if (model_item && view_item)
 			{
 				view_item->destroyView();
-                                removeItemID(view_item->getViewModelItem()->getUUID());
+				removeItemID(viewmodel_item->getUUID());
 			}
 			view_item = buildNewViews(item_id);
+			viewmodel_item = 
+				static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
 			view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
 		}
 
@@ -563,14 +569,14 @@ void LLInventoryPanel::modelChanged(U32 mask)
 							// Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
 							view_item->getParentFolder()->extractItem(view_item);
 							view_item->addToFolder(new_parent);
-							addItemID(view_item->getViewModelItem()->getUUID(), view_item);
+							addItemID(viewmodel_item->getUUID(), view_item);
 						}
 						else 
 						{
 							// Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that 
 							// doesn't include trash).  Just remove the item's UI.
 							view_item->destroyView();
-                                                        removeItemID(view_item->getViewModelItem()->getUUID());
+                            removeItemID(viewmodel_item->getUUID());
 						}
 					}
 				}
@@ -583,7 +589,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			{
 				// Remove the item's UI.
 				view_item->destroyView();
-                                removeItemID(view_item->getViewModelItem()->getUUID());
+                removeItemID(viewmodel_item->getUUID());
 			}
 		}
 	}
@@ -613,16 +619,11 @@ void LLInventoryPanel::onIdle(void *userdata)
 	}
 }
 
-const LLUUID& LLInventoryPanel::getRootFolderID() const
-{
-	return mFolderRoot->getViewModelItem()->getUUID();
-}
-
 void LLInventoryPanel::initializeViews()
 {
 	if (!gInventory.isInventoryUsable()) return;
 
-	rebuildViewsFor(getRootFolderID());
+	rebuildViewsFor(gInventory.getRootFolderID());
 
 	mViewsInitialized = true;
 	
@@ -654,7 +655,7 @@ LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
 	if (old_view)
 	{
 		old_view->destroyView();
-                removeItemID(old_view->getViewModelItem()->getUUID());
+		removeItemID(static_cast<LLFolderViewModelItemInventory*>(old_view->getViewModelItem())->getUUID());
 	}
 
 	return buildNewViews(id);
@@ -727,75 +728,65 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
 LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 {
  	LLInventoryObject const* objectp = gInventory.getObject(id);
- 	LLUUID root_id = mFolderRoot->getViewModelItem()->getUUID();
- 	LLFolderViewFolder* parent_folder = NULL;
-	LLFolderViewItem* itemp = NULL;
 	
- 	if (id == root_id)
- 	{
- 		parent_folder = mFolderRoot;
- 	}
- 	else if (objectp)
- 	{
- 		const LLUUID &parent_id = objectp->getParentUUID();
- 		parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
-  		
-  		if (parent_folder)
+	if (!objectp) return NULL;
+
+	LLFolderViewItem* folder_view_item = getItemByID(id);
+	LLFolderViewFolder* parent_folder = folder_view_item->getParentFolder();
+	 
+ 	if (!folder_view_item && parent_folder)
+  	{
+  		if (objectp->getType() <= LLAssetType::AT_NONE ||
+  			objectp->getType() >= LLAssetType::AT_COUNT)
   		{
-  			if (objectp->getType() <= LLAssetType::AT_NONE ||
-  				objectp->getType() >= LLAssetType::AT_COUNT)
-  			{
-  				llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
-  						<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
-  						<< llendl;
-  				return NULL;
-  			}
+  			llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
+  					<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
+  					<< llendl;
+  			return NULL;
+  		}
   		
-  			if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
-  				(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
+  		if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
+  			(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
+  		{
+  			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
+  																			objectp->getType(),
+  																			LLInventoryType::IT_CATEGORY,
+  																			this,
+  																			mFolderRoot,
+  																			objectp->getUUID());
+  			if (new_listener)
   			{
-  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
-  																				objectp->getType(),
-  																				LLInventoryType::IT_CATEGORY,
-  																				this,
-  																				mFolderRoot,
-  																				objectp->getUUID());
-  				if (new_listener)
-  				{
-					itemp = createFolderViewFolder(new_listener);
-  				}
+				folder_view_item = createFolderViewFolder(new_listener);
   			}
-  			else
-  			{
-  				// Build new view for item.
-  				LLInventoryItem* item = (LLInventoryItem*)objectp;
-  				LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
-  																				item->getActualType(),
-  																				item->getInventoryType(),
-  																				this,
-  																				mFolderRoot,
-  																				item->getUUID(),
-  																				item->getFlags());
+  		}
+  		else
+  		{
+  			// Build new view for item.
+  			LLInventoryItem* item = (LLInventoryItem*)objectp;
+  			LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
+  																			item->getActualType(),
+  																			item->getInventoryType(),
+  																			this,
+  																			mFolderRoot,
+  																			item->getUUID(),
+  																			item->getFlags());
  
-  				if (new_listener)
-  				{
-					itemp = createFolderViewItem(new_listener);
-  				}
+  			if (new_listener)
+  			{
+				folder_view_item = createFolderViewItem(new_listener);
   			}
+  		}
  
-  			if (itemp)
-  			{
-  				itemp->addToFolder(parent_folder);
-				addItemID(itemp->getViewModelItem()->getUUID(), itemp);
-   			}
-		}
+  		if (folder_view_item)
+  		{
+  			folder_view_item->addToFolder(parent_folder);
+			addItemID(id, folder_view_item);
+   		}
 	}
 
 	// If this is a folder, add the children of the folder and recursively add any 
 	// child folders.
-	if (id.isNull()
-		||	(objectp
-			&& objectp->getType() == LLAssetType::AT_CATEGORY))
+	if (folder_view_item && objectp->getType() == LLAssetType::AT_CATEGORY)
 	{
 		LLViewerInventoryCategory::cat_array_t* categories;
 		LLViewerInventoryItem::item_array_t* items;
@@ -812,7 +803,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 			}
 		}
 		
-		if(items && parent_folder)
+		if(items)
 		{
 			for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
 				 item_iter != items->end();
@@ -825,7 +816,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 		mInventory->unlockDirectDescendentArrays(id);
 	}
 	
-	return itemp;
+	return folder_view_item;
 }
 
 // bit of a hack to make sure the inventory is open.
@@ -837,7 +828,7 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
 		LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
 		if (fchild
 			&& fchild->getViewModelItem()
-				&& fchild->getViewModelItem()->getUUID() == gInventory.getRootFolderID())
+			&& fchild->getViewModelItem()->getName() == "My Inventory")
 		{
 			fchild->setOpen(TRUE);
 			break;
@@ -980,7 +971,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 	mCompletionObserver->reset();
 	for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it)
 	{
-		LLUUID id = (*it)->getViewModelItem()->getUUID();
+		LLUUID id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
 		LLViewerInventoryItem* inv_item = mInventory->getItem(id);
 
 		if (inv_item && !inv_item->isFinished())
@@ -1028,7 +1019,7 @@ bool LLInventoryPanel::beginIMSession()
 			
 		if(folder_item) 
 		{
-			LLFolderViewEventListener* fve_listener = folder_item->getViewModelItem();
+			LLFolderViewModelItemInventory* fve_listener = static_cast<LLFolderViewModelItemInventory*>(folder_item->getViewModelItem());
 			if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
 			{
 
@@ -1107,13 +1098,13 @@ bool LLInventoryPanel::beginIMSession()
 bool LLInventoryPanel::attachObject(const LLSD& userdata)
 {
 	// Copy selected item UUIDs to a vector.
-	std::set<LLFolderViewItem*> selected_items =   mFolderRoot->getSelectionList();
+	std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
 	uuid_vec_t items;
-	for (std::set<LLFolderViewItem*>::const_iterator set_iter =   selected_items.begin();
+	for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin();
 		 set_iter != selected_items.end(); 
 		 ++set_iter)
 	{
-		items.push_back((*set_iter)->getItemViewModel()->getUUID());
+		items.push_back(static_cast<LLFolderViewModelItemInventory*>((*set_iter)->getViewModelItem())->getUUID());
 	}
 
 	// Attach selected items.
@@ -1292,10 +1283,6 @@ LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
 LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id)
 {
 	LLFastTimer _(FTM_GET_ITEM_BY_ID);
-	if (id == mFolderRoot->getViewModelItem()->getUUID())
-	{
-		return mFolderRoot;
-	}
 
 	std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
 	map_it = mItemMap.find(id);
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 467c508aa0..cd32b18779 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -66,22 +66,21 @@ public:
 class LLInventorySort
 {
 public:
-	LLInventorySort(U32 order)
-		:	mSortOrder(0),
+	LLInventorySort(U32 order = 0)
+	:	mSortOrder(order),
 		mByDate(false),
 		mSystemToTop(false),
 		mFoldersByName(false)
 	{
-		mSortOrder = order;
 		mByDate = (order & LLInventoryFilter::SO_DATE);
 		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
 		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
 	}
 
-	bool isByDate() { return mByDate; }
-	U32 getSortOrder() { return mSortOrder; }
+	bool isByDate() const { return mByDate; }
+	U32 getSortOrder() const { return mSortOrder; }
 
-	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b);
+	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
 private:
 	U32  mSortOrder;
 	bool mByDate;
@@ -92,12 +91,16 @@ private:
 class LLFolderViewModelInventory
 	:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter>
 {
+public:
 	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t;
 
 	virtual ~LLFolderViewModelInventory() {}
 
 	void sort(LLFolderViewFolder* folder);
 	void requestSort(LLFolderViewFolder* folder);
+
+	bool contentsReady();
+
 };
 
 
@@ -234,7 +237,7 @@ public:
 	void updateSelection();
 	 	
 	LLFolderViewModelInventory* getFolderViewModel() { return &mViewModel; }
-	const LLFolderViewModelInventory* getFolderViewModel() const { return   &mViewModel; }
+	const LLFolderViewModelInventory* getFolderViewModel() const { return &mViewModel; }
 
 protected:
 	void openStartFolderOrMyInventory(); // open the first level of inventory
@@ -287,8 +290,7 @@ public:
 	void addHideFolderType(LLFolderType::EType folder_type);
 
 public:
-	BOOL 				getIsViewsInitialized() const { return mViewsInitialized; }
-	const LLUUID&		getRootFolderID() const;
+	BOOL getIsViewsInitialized() const { return mViewsInitialized; }
 protected:
 	// Builds the UI.  Call this once the inventory is usable.
 	void 				initializeViews();
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 240c5b2da4..ae68b5ce95 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1542,7 +1542,7 @@ void LLPanelObjectInventory::reset()
 	p.folder_indentation = -14; // subtract space normally reserved for folder expanders
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
-	RN: make this happen by manipulating filter object directly
+	//TODO RN: make this happen by manipulating filter object directly
 	//mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
 	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index 6aa349f0f3..e8b2808d4f 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -63,8 +63,7 @@ public:
 	BOOL isMainInventoryPanelActive() const;
 
 	void clearSelections(bool clearMain, bool clearInbox);
-        std::set<LLFolderViewItem*> getInboxSelectionList();
-	std::set<LLUUID> getInboxSelectionList();
+    std::set<LLFolderViewItem*> getInboxSelectionList();
 
 	void showItemInfoPanel();
 	void showTaskInfoPanel();
-- 
cgit v1.2.3


From b882fe3b8dde9338c092922672015f975ca09587 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 18 Jun 2012 22:51:33 -0700
Subject: CHUI-146 : Refocus on the first conversation when closing another
 conversation, don't let focus falls out

---
 indra/newview/llimfloatercontainer.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index bedf3315e8..04fb2f3b9a 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -405,6 +405,15 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id)
 							   panel_rect.getWidth(),
 							   panel_rect.getHeight() - item_height*(index+1)));
 	}
+	
+	// Don't let the focus fall IW, select and refocus on the first conversation in the list
+	setFocus(TRUE);
+	conversations_items_map::iterator item_it = mConversationsItems.begin();
+	if (item_it != mConversationsItems.end())
+	{
+		LLConversationItem* item = item_it->second;
+		item->selectItem();
+	}
 	return;
 }
 
-- 
cgit v1.2.3


From 18aabdfd3d2efc1b5507e2fe001cfc36ee84b710 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 19 Jun 2012 09:44:40 +0300
Subject: CHUI-127 FIXED (Make chat field auto resizable)

- Replaced LLLineEditor with newly created LLChatEntry
- Moved some functionality (such as setting label) to the LLTextBase as it can be useful to the other derived classes
---
 indra/llui/CMakeLists.txt                          |   2 +
 indra/llui/llaccordionctrltab.cpp                  |   2 +-
 indra/llui/llchatentry.cpp                         | 198 +++++++++++++++++++++
 indra/llui/llchatentry.h                           |  98 ++++++++++
 indra/llui/lltextbase.cpp                          | 122 +++++++++++--
 indra/llui/lltextbase.h                            |  52 +++++-
 indra/llui/lltexteditor.cpp                        |  32 ++--
 indra/llui/lltexteditor.h                          |   9 +-
 indra/newview/llexpandabletextbox.cpp              |   4 +-
 indra/newview/llgrouplist.cpp                      |   2 +-
 indra/newview/llimfloater.cpp                      |  34 ++--
 indra/newview/llimfloater.h                        |  17 +-
 indra/newview/llpaneltopinfobar.cpp                |   2 +-
 indra/newview/lltoastgroupnotifypanel.cpp          |   2 +-
 indra/newview/lltoastpanel.cpp                     |   2 +-
 indra/newview/lltoastscripttextbox.cpp             |   2 +-
 .../skins/default/xui/en/floater_im_session.xml    |   9 +-
 .../newview/skins/default/xui/en/widgets/text.xml  |   1 +
 18 files changed, 529 insertions(+), 61 deletions(-)
 create mode 100644 indra/llui/llchatentry.cpp
 create mode 100644 indra/llui/llchatentry.h

(limited to 'indra')

diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 772f173f17..b50ed2342d 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -34,6 +34,7 @@ set(llui_SOURCE_FILES
     llbadgeholder.cpp
     llbadgeowner.cpp
     llbutton.cpp
+    llchatentry.cpp
     llcheckboxctrl.cpp
     llclipboard.cpp
     llcombobox.cpp
@@ -133,6 +134,7 @@ set(llui_HEADER_FILES
     llbadgeowner.h
     llbutton.h
     llcallbackmap.h
+    llchatentry.h
     llcheckboxctrl.h
     llclipboard.h
     llcombobox.h
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index c025cd7939..43462bd244 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -184,7 +184,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleFontStyle(std::string
 	if (mHeaderTextbox)
 	{
 		std::string text = mHeaderTextbox->getText();
-		mStyleParams.font(mHeaderTextbox->getDefaultFont());
+		mStyleParams.font(mHeaderTextbox->getFont());
 		mStyleParams.font.style(style);
 		mHeaderTextbox->setText(text, mStyleParams);
 	}
diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
new file mode 100644
index 0000000000..6f51705b90
--- /dev/null
+++ b/indra/llui/llchatentry.cpp
@@ -0,0 +1,198 @@
+/**
+ * @file llchatentry.cpp
+ * @brief LLChatEntry implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llchatentry.h"
+
+static LLDefaultChildRegistry::Register<LLChatEntry> r("text_editor");
+
+LLChatEntry::LLChatEntry::Params::Params()
+:	has_history("has_history", true),
+ 	is_expandable("is_expandable", false),
+ 	expand_lines_count("expand_lines_count", 1)
+{}
+
+LLChatEntry::LLChatEntry(const Params& p)
+:	LLTextEditor(p),
+ 	mTextExpandedSignal(NULL),
+ 	mHasHistory(p.has_history),
+ 	mIsExpandable(p.is_expandable),
+ 	mExpandLinesCount(p.expand_lines_count),
+ 	mPrevLinesCount(0)
+{
+	// Initialize current history line iterator
+	mCurrentHistoryLine = mLineHistory.begin();
+
+	mAutoIndent = false;
+}
+
+LLChatEntry::~LLChatEntry()
+{
+	delete mTextExpandedSignal;
+}
+
+void LLChatEntry::draw()
+{
+	LLTextEditor::draw();
+
+	if(mIsExpandable)
+	{
+		expandText();
+	}
+}
+
+void LLChatEntry::onCommit()
+{
+	updateHistory();
+	LLTextEditor::onCommit();
+}
+
+boost::signals2::connection LLChatEntry::setTextExpandedCallback(const commit_signal_t::slot_type& cb)
+{
+	if (!mTextExpandedSignal)
+	{
+		mTextExpandedSignal = new commit_signal_t();
+	}
+	return mTextExpandedSignal->connect(cb);
+}
+
+void LLChatEntry::expandText()
+{
+	int visible_lines_count = llabs(getVisibleLines(true).first - getVisibleLines(true).second);
+	bool can_expand = getLineCount() <= mExpandLinesCount;
+
+	// true if pasted text has more lines than expand height limit and expand limit is not reached yet
+	bool text_pasted = (getLineCount() > mExpandLinesCount) && (visible_lines_count < mExpandLinesCount);
+
+	if (mIsExpandable && (can_expand || text_pasted) && getLineCount() != mPrevLinesCount)
+	{
+		int lines_height = 0;
+		if (text_pasted)
+		{
+			// text is pasted and now mLineInfoList.size() > mExpandLineCounts and mLineInfoList is not empty,
+			// so lines_height is the sum of the last 'mExpandLinesCount' lines height
+			lines_height = (mLineInfoList.end() - mExpandLinesCount)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+		}
+		else
+		{
+			lines_height = mLineInfoList.begin()->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+		}
+
+		int height = mVPad * 2 +  lines_height;
+
+		LLRect doc_rect = getRect();
+		doc_rect.setOriginAndSize(doc_rect.mLeft, doc_rect.mBottom, doc_rect.getWidth(), height);
+		setShape(doc_rect);
+
+		mPrevLinesCount = getLineCount();
+
+		if (mTextExpandedSignal)
+		{
+			(*mTextExpandedSignal)(this, LLSD() );
+		}
+	}
+}
+
+// line history support
+void LLChatEntry::updateHistory()
+{
+	// On history enabled, remember committed line and
+	// reset current history line number.
+	// Be sure only to remember lines that are not empty and that are
+	// different from the last on the list.
+	if (mHasHistory && getLength())
+	{
+		// Add text to history, ignoring duplicates
+		if (mLineHistory.empty() || getText() != mLineHistory.back())
+		{
+			mLineHistory.push_back(getText());
+		}
+
+		mCurrentHistoryLine = mLineHistory.end();
+	}
+}
+
+BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
+{
+	BOOL handled = FALSE;
+
+	LLTextEditor::handleSpecialKey(key, mask);
+
+	switch(key)
+	{
+	case KEY_RETURN:
+		if (MASK_NONE == mask)
+		{
+			needsReflow();
+		}
+		break;
+
+	case KEY_UP:
+		if (mHasHistory && MASK_CONTROL == mask)
+		{
+			if (!mLineHistory.empty() && mCurrentHistoryLine > mLineHistory.begin())
+			{
+				setText(*(--mCurrentHistoryLine));
+				endOfDoc();
+			}
+			else
+			{
+				LLUI::reportBadKeystroke();
+			}
+			handled = TRUE;
+		}
+		break;
+
+	case KEY_DOWN:
+		if (mHasHistory && MASK_CONTROL == mask)
+		{
+			if (!mLineHistory.empty() && ++mCurrentHistoryLine < mLineHistory.end())
+			{
+				setText(*mCurrentHistoryLine);
+				endOfDoc();
+			}
+			else if (!mLineHistory.empty() && mCurrentHistoryLine == mLineHistory.end())
+			{
+				std::string empty("");
+				setText(empty);
+				needsReflow();
+				endOfDoc();
+			}
+			else
+			{
+				LLUI::reportBadKeystroke();
+			}
+			handled = TRUE;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return handled;
+}
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
new file mode 100644
index 0000000000..10a4594e83
--- /dev/null
+++ b/indra/llui/llchatentry.h
@@ -0,0 +1,98 @@
+/**
+ * @file llchatentry.h
+ * @author Paul Guslisty
+ * @brief Text editor widget which is used for user input
+ *
+ * Features:
+ *			Optional line history so previous entries can be recalled by CTRL UP/DOWN
+ *			Optional auto-resize behavior on input chat field
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLCHATENTRY_H_
+#define LLCHATENTRY_H_
+
+#include "lltexteditor.h"
+
+class LLChatEntry : public LLTextEditor
+{
+public:
+
+	struct Params : public LLInitParam::Block<Params, LLTextEditor::Params>
+	{
+		Optional<bool>		has_history,
+							is_expandable;
+
+		Optional<int>		expand_lines_count;
+
+		Params();
+	};
+
+	virtual ~LLChatEntry();
+
+protected:
+
+	friend class LLUICtrlFactory;
+	LLChatEntry(const Params& p);
+
+public:
+
+	virtual void	draw();
+	virtual	void	onCommit();
+
+	boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
+
+private:
+
+	/**
+	 * Implements auto-resize behavior.
+	 * When user's typing reaches the right edge of the chat field
+	 * the chat field expands vertically by one line. The bottom of
+	 * the chat field remains bottom-justified. The chat field does
+	 * not expand beyond mExpandLinesCount.
+	 */
+	void	expandText();
+
+	/**
+	 * Implements line history so previous entries can be recalled by CTRL UP/DOWN
+	 */
+	void	updateHistory();
+
+	BOOL	handleSpecialKey(const KEY key, const MASK mask);
+
+
+	// Fired when text height expanded to mExpandLinesCount
+	commit_signal_t*			mTextExpandedSignal;
+
+	// line history support:
+	typedef std::vector<std::string>	line_history_t;
+	line_history_t::iterator			mCurrentHistoryLine;	// currently browsed history line
+	line_history_t						mLineHistory;			// line history storage
+	bool								mHasHistory;			// flag for enabled/disabled line history
+	bool								mIsExpandable;
+
+	int									mExpandLinesCount;
+	int									mPrevLinesCount;
+};
+
+#endif /* LLCHATENTRY_H_ */
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7aeeae298f..c112a7e477 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -144,6 +144,7 @@ LLTextBase::Params::Params()
 :	cursor_color("cursor_color"),
 	text_color("text_color"),
 	text_readonly_color("text_readonly_color"),
+	text_tentative_color("text_tentative_color"),
 	bg_visible("bg_visible", false),
 	border_visible("border_visible", false),
 	bg_readonly_color("bg_readonly_color"),
@@ -177,7 +178,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 :	LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
 	mURLClickSignal(NULL),
 	mMaxTextByteLength( p.max_text_length ),
-	mDefaultFont(p.font),
+	mFont(p.font),
 	mFontShadow(p.font_shadow),
 	mPopupMenu(NULL),
 	mReadOnly(p.read_only),
@@ -185,6 +186,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 	mFgColor(p.text_color),
 	mBorderVisible( p.border_visible ),
 	mReadOnlyFgColor(p.text_readonly_color),
+	mTentativeFgColor(p.text_tentative_color()),
 	mWriteableBgColor(p.bg_writeable_color),
 	mReadOnlyBgColor(p.bg_readonly_color),
 	mFocusBgColor(p.bg_focus_color),
@@ -297,21 +299,21 @@ bool LLTextBase::truncate()
 	return did_truncate;
 }
 
-const LLStyle::Params& LLTextBase::getDefaultStyleParams()
+const LLStyle::Params& LLTextBase::getStyleParams()
 {
 	//FIXME: convert mDefaultStyle to a flyweight http://www.boost.org/doc/libs/1_40_0/libs/flyweight/doc/index.html
 	//and eliminate color member values
 	if (mStyleDirty)
 	{
-		  mDefaultStyle
+		  mStyle
 				  .color(LLUIColor(&mFgColor))						// pass linked color instead of copy of mFGColor
 				  .readonly_color(LLUIColor(&mReadOnlyFgColor))
 				  .selected_color(LLUIColor(&mTextSelectedColor))
-				  .font(mDefaultFont)
+				  .font(mFont)
 				  .drop_shadow(mFontShadow);
 		  mStyleDirty = false;
 	}
-	return mDefaultStyle;
+	return mStyle;
 }
 
 void LLTextBase::onValueChange(S32 start, S32 end)
@@ -500,11 +502,17 @@ void LLTextBase::drawCursor()
 
 void LLTextBase::drawText()
 {
-	const S32 text_len = getLength();
-	if( text_len <= 0 )
+	S32 text_len = getLength();
+
+	if (text_len <= 0 && mLabel.empty())
 	{
 		return;
 	}
+	else if (text_len <= 0 && !mLabel.empty())
+	{
+		text_len = mLabel.length();
+	}
+
 	S32 selection_left = -1;
 	S32 selection_right = -1;
 	// Draw selection even if we don't have keyboard focus for search/replace
@@ -624,7 +632,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
 	else
 	{
 		// create default editable segment to hold new text
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		default_segment = new LLNormalTextSegment( sp, pos, pos + insert_len, *this);
 	}
 
@@ -749,7 +757,7 @@ void LLTextBase::createDefaultSegment()
 	// ensures that there is always at least one segment
 	if (mSegments.empty())
 	{
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
 		mSegments.insert(default_segment);
 		default_segment->linkToDocument(this);
@@ -1103,6 +1111,22 @@ void LLTextBase::deselect()
 	mIsSelecting = FALSE;
 }
 
+void LLTextBase::onFocusReceived()
+{
+	if (!getLength() && !mLabel.empty())
+	{
+		// delete label which is LLLabelTextSegment
+		clearSegments();
+	}
+}
+
+void LLTextBase::onFocusLost()
+{
+	if (!getLength() && !mLabel.empty())
+	{
+		resetLabel();
+	}
+}
 
 // Sets the scrollbar from the cursor position
 void LLTextBase::updateScrollFromCursor()
@@ -1688,7 +1712,7 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
 void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
 {
 	LLStyle::Params style_params(input_params);
-	style_params.fillFrom(getDefaultStyleParams());
+	style_params.fillFrom(getStyleParams());
 
 	S32 part = (S32)LLTextParser::WHOLE;
 	if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
@@ -1770,6 +1794,39 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
 	appendTextImpl(new_text,input_params);
 }
 
+void LLTextBase::setLabel(const LLStringExplicit& label)
+{
+	mLabel = label;
+	resetLabel();
+}
+
+BOOL LLTextBase::setLabelArg(const std::string& key, const LLStringExplicit& text )
+{
+	mLabel.setArg(key, text);
+	return TRUE;
+}
+
+void LLTextBase::resetLabel()
+{
+	if (!getLength() && !mLabel.empty() && !hasFocus())
+	{
+		clearSegments();
+
+		LLStyle* style = new LLStyle(getStyleParams());
+		style->setColor(mTentativeFgColor);
+		LLStyleConstSP sp(style);
+
+		LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, getLabel().length() + 1, *this);
+		insertSegment(label);
+	}
+}
+
+void LLTextBase::setFont(const LLFontGL* font)
+{
+	mFont = font;
+	mStyleDirty = true;
+}
+
 void LLTextBase::needsReflow(S32 index)
 {
 	lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl;
@@ -2160,7 +2217,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
 	{ 
 		// return default height rect in upper left
 		local_rect = content_window_rect;
-		local_rect.mBottom = local_rect.mTop - mDefaultFont->getLineHeight();
+		local_rect.mBottom = local_rect.mTop - mFont->getLineHeight();
 		return local_rect;
 	}
 
@@ -2665,7 +2722,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
 {
 	F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
 
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 
 	F32 right_x = rect.mLeft;
 	if (!mStyle->isVisible())
@@ -2828,7 +2885,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
 	if (num_chars > 0)
 	{
 		height = mFontHeight;
-		const LLWString &text = mEditor.getWText();
+		const LLWString &text = getWText();
 		// if last character is a newline, then return true, forcing line break
 		width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
 	}
@@ -2837,7 +2894,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
 
 S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
 {
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 	return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
 											   (F32)segment_local_x_coord,
 											   F32_MAX,
@@ -2847,7 +2904,7 @@ S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset,
 
 S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
 {
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 
 	LLUIImagePtr image = mStyle->getImage();
 	if( image.notNull())
@@ -2883,7 +2940,7 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 	S32 last_char_in_run = mStart + segment_offset + num_chars;
 	// check length first to avoid indexing off end of string
 	if (last_char_in_run < mEnd 
-		&& (last_char_in_run >= mEditor.getLength() ))
+		&& (last_char_in_run >= getLength()))
 	{
 		num_chars++;
 	}
@@ -2901,6 +2958,39 @@ void LLNormalTextSegment::dump() const
 		llendl;
 }
 
+/*virtual*/
+const LLWString& LLNormalTextSegment::getWText()	const
+{
+	return mEditor.getWText();
+}
+
+/*virtual*/
+const S32 LLNormalTextSegment::getLength() const
+{
+	return mEditor.getLength();
+}
+
+LLLabelTextSegment::LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor )
+:	LLNormalTextSegment(style, start, end, editor)
+{
+}
+
+LLLabelTextSegment::LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible)
+:	LLNormalTextSegment(color, start, end, editor, is_visible)
+{
+}
+
+/*virtual*/
+const LLWString& LLLabelTextSegment::getWText()	const
+{
+	return mEditor.getWlabel();
+}
+/*virtual*/
+const S32 LLLabelTextSegment::getLength() const
+{
+	return mEditor.getLabel().length();
+}
+
 //
 // LLOnHoverChangeableTextSegment
 //
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 0549141b72..412272b352 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -105,7 +105,7 @@ class LLNormalTextSegment : public LLTextSegment
 public:
 	LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
 	LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
-	~LLNormalTextSegment();
+	virtual ~LLNormalTextSegment();
 
 	/*virtual*/ bool				getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
 	/*virtual*/ S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
@@ -130,6 +130,9 @@ public:
 protected:
 	F32					drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect);
 
+	virtual		const LLWString&	getWText()	const;
+	virtual		const S32			getLength()	const;
+
 protected:
 	class LLTextBase&	mEditor;
 	LLStyleConstSP		mStyle;
@@ -139,6 +142,21 @@ protected:
 	boost::signals2::connection mImageLoadedConnection;
 };
 
+// This text segment is the same as LLNormalTextSegment, the only difference
+// is that LLNormalTextSegment draws value of LLTextBase (LLTextBase::getWText()),
+// but LLLabelTextSegment draws label of the LLTextBase (LLTextBase::mLabel)
+class LLLabelTextSegment : public LLNormalTextSegment
+{
+public:
+	LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
+	LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
+
+protected:
+
+	/*virtual*/	const LLWString&	getWText()	const;
+	/*virtual*/	const S32			getLength()	const;
+};
+
 // Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment)
 class LLOnHoverChangeableTextSegment : public LLNormalTextSegment
 {
@@ -249,6 +267,7 @@ public:
 		Optional<LLUIColor>		cursor_color,
 								text_color,
 								text_readonly_color,
+								text_tentative_color,
 								bg_readonly_color,
 								bg_writeable_color,
 								bg_focus_color,
@@ -311,6 +330,9 @@ public:
 	/*virtual*/ BOOL		canDeselect() const;
 	/*virtual*/ void		deselect();
 
+	virtual void	onFocusReceived();
+	virtual void	onFocusLost();
+
 	// used by LLTextSegment layout code
 	bool					getWordWrap() { return mWordWrap; }
 	bool					getUseEllipses() { return mUseEllipses; }
@@ -330,6 +352,21 @@ public:
 	const LLWString&       	getWText() const;
 
 	void					appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
+
+	void					setLabel(const LLStringExplicit& label);
+	virtual BOOL			setLabelArg(const std::string& key, const LLStringExplicit& text );
+
+	const	std::string& 	getLabel()	{ return mLabel.getString(); }
+	const	LLWString&		getWlabel() { return mLabel.getWString();}
+
+	/**
+	 * If label is set, draws text label (which is LLLabelTextSegment)
+	 * that is visible when no user text provided and has no focus
+	 */
+	void					resetLabel();
+
+	void					setFont(const LLFontGL* font);
+
 	// force reflow of text
 	void					needsReflow(S32 index = 0);
 
@@ -369,7 +406,7 @@ public:
 	bool					scrolledToStart();
 	bool					scrolledToEnd();
 
-	const LLFontGL*			getDefaultFont() const					{ return mDefaultFont; }
+	const LLFontGL*			getFont() const					{ return mFont; }
 
 	virtual void			appendLineBreakSegment(const LLStyle::Params& style_params);
 	virtual void			appendImageSegment(const LLStyle::Params& style_params);
@@ -469,7 +506,7 @@ protected:
 	void							createDefaultSegment();
 	virtual void					updateSegments();
 	void							insertSegment(LLTextSegmentPtr segment_to_insert);
-	const LLStyle::Params&			getDefaultStyleParams();
+	const LLStyle::Params&			getStyleParams();
 
 	//  manage lines
 	S32								getLineStart( S32 line ) const;
@@ -514,15 +551,16 @@ protected:
 	LLRect						mTextBoundingRect;
 
 	// default text style
-	LLStyle::Params				mDefaultStyle;
+	LLStyle::Params				mStyle;
 	bool						mStyleDirty;
-	const LLFontGL* const		mDefaultFont;		// font that is used when none specified, can only be set by constructor
-	const LLFontGL::ShadowType	mFontShadow;		// shadow style, can only be set by constructor
+	const LLFontGL*				mFont;
+	const LLFontGL::ShadowType	mFontShadow;
 
 	// colors
 	LLUIColor					mCursorColor;
 	LLUIColor					mFgColor;
 	LLUIColor					mReadOnlyFgColor;
+	LLUIColor					mTentativeFgColor;
 	LLUIColor					mWriteableBgColor;
 	LLUIColor					mReadOnlyBgColor;
 	LLUIColor					mFocusBgColor;
@@ -558,6 +596,7 @@ protected:
 	bool						mClip;				// clip text to widget rect
 	bool						mClipPartial;		// false if we show lines that are partially inside bounding rect
 	bool						mPlainText;			// didn't use Image or Icon segments
+	bool						mAutoIndent;
 	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes
 
 	// support widgets
@@ -573,6 +612,7 @@ protected:
 	// Fired when a URL link is clicked
 	commit_signal_t*			mURLClickSignal;
 
+	LLUIString					mLabel;	// text label that is visible when no user text provided
 };
 
 #endif
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 9720dded6c..4fa6ea085e 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -235,6 +235,7 @@ LLTextEditor::Params::Params()
 	embedded_items("embedded_items", false),
 	ignore_tab("ignore_tab", true),
 	show_line_numbers("show_line_numbers", false),
+	auto_indent("auto_indent", true),
 	default_color("default_color"),
     commit_on_focus_lost("commit_on_focus_lost", false),
 	show_context_menu("show_context_menu")
@@ -249,6 +250,7 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
 	mLastCmd( NULL ),
 	mDefaultColor(		p.default_color() ),
 	mShowLineNumbers ( p.show_line_numbers ),
+	mAutoIndent(p.auto_indent),
 	mCommitOnFocusLost( p.commit_on_focus_lost),
 	mAllowEmbeddedItems( p.embedded_items ),
 	mMouseDownX(0),
@@ -256,7 +258,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
 	mTabsToNextField(p.ignore_tab),
 	mPrevalidateFunc(p.prevalidate_callback()),
 	mContextMenu(NULL),
-	mShowContextMenu(p.show_context_menu)
+	mShowContextMenu(p.show_context_menu),
+	mPassDelete(FALSE)
 {
 	mSourceID.generate();
 
@@ -1606,7 +1609,10 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask)
 			{
 				deleteSelection(FALSE);
 			}
-			autoIndent(); // TODO: make this optional
+			if (mAutoIndent)
+			{
+				autoIndent();
+			}
 		}
 		else
 		{
@@ -1746,7 +1752,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
 // virtual
 BOOL LLTextEditor::canDoDelete() const
 {
-	return !mReadOnly && ( hasSelection() || (mCursorPos < getLength()) );
+	return !mReadOnly && ( !mPassDelete || ( hasSelection() || (mCursorPos < getLength())) );
 }
 
 void LLTextEditor::doDelete()
@@ -1984,7 +1990,7 @@ void LLTextEditor::drawPreeditMarker()
 		return;
 	}
 		
-	const S32 line_height = mDefaultFont->getLineHeight();
+	const S32 line_height = mFont->getLineHeight();
 
 	S32 line_start = getLineStart(cur_line);
 	S32 line_y = mVisibleTextRect.mTop - line_height;
@@ -2023,16 +2029,16 @@ void LLTextEditor::drawPreeditMarker()
 				S32 preedit_left = mVisibleTextRect.mLeft;
 				if (left > line_start)
 				{
-					preedit_left += mDefaultFont->getWidth(text, line_start, left - line_start);
+					preedit_left += mFont->getWidth(text, line_start, left - line_start);
 				}
 				S32 preedit_right = mVisibleTextRect.mLeft;
 				if (right < line_end)
 				{
-					preedit_right += mDefaultFont->getWidth(text, line_start, right - line_start);
+					preedit_right += mFont->getWidth(text, line_start, right - line_start);
 				}
 				else
 				{
-					preedit_right += mDefaultFont->getWidth(text, line_start, line_end - line_start);
+					preedit_right += mFont->getWidth(text, line_start, line_end - line_start);
 				}
 
 				if (mPreeditStandouts[i])
@@ -2707,11 +2713,11 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
 
     const LLWString textString(getWText());
 	const llwchar * const text = textString.c_str();
-	const S32 line_height = mDefaultFont->getLineHeight();
+	const S32 line_height = mFont->getLineHeight();
 
 	if (coord)
 	{
-		const S32 query_x = mVisibleTextRect.mLeft + mDefaultFont->getWidth(text, current_line_start, query - current_line_start);
+		const S32 query_x = mVisibleTextRect.mLeft + mFont->getWidth(text, current_line_start, query - current_line_start);
 		const S32 query_y = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height - line_height / 2;
 		S32 query_screen_x, query_screen_y;
 		localPointToScreen(query_x, query_y, &query_screen_x, &query_screen_y);
@@ -2723,17 +2729,17 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
 		S32 preedit_left = mVisibleTextRect.mLeft;
 		if (preedit_left_position > current_line_start)
 		{
-			preedit_left += mDefaultFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
+			preedit_left += mFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
 		}
 
 		S32 preedit_right = mVisibleTextRect.mLeft;
 		if (preedit_right_position < current_line_end)
 		{
-			preedit_right += mDefaultFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
+			preedit_right += mFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
 		}
 		else
 		{
-			preedit_right += mDefaultFont->getWidth(text, current_line_start, current_line_end - current_line_start);
+			preedit_right += mFont->getWidth(text, current_line_start, current_line_end - current_line_start);
 		}
 
 		const S32 preedit_top = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height;
@@ -2810,7 +2816,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
 
 S32 LLTextEditor::getPreeditFontSize() const
 {
-	return llround((F32)mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+	return llround((F32)mFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
 }
 
 BOOL LLTextEditor::isDirty() const
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 40821ae9fb..f8f636b876 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -64,7 +64,8 @@ public:
 								ignore_tab,
 								show_line_numbers,
 								commit_on_focus_lost,
-								show_context_menu;
+								show_context_menu,
+								auto_indent;
 
 		//colors
 		Optional<LLUIColor>		default_color;
@@ -202,6 +203,8 @@ public:
 	void			setShowContextMenu(bool show) { mShowContextMenu = show; }
 	bool			getShowContextMenu() const { return mShowContextMenu; }
 
+	void			setPassDelete(BOOL b) { mPassDelete = b; }
+
 protected:
 	void			showContextMenu(S32 x, S32 y);
 	void			drawPreeditMarker();
@@ -214,8 +217,8 @@ protected:
 	S32				indentLine( S32 pos, S32 spaces );
 	void			unindentLineBeforeCloseBrace();
 
+	virtual	BOOL	handleSpecialKey(const KEY key, const MASK mask);
 	BOOL			handleNavigationKey(const KEY key, const MASK mask);
-	BOOL			handleSpecialKey(const KEY key, const MASK mask);
 	BOOL			handleSelectionKey(const KEY key, const MASK mask);
 	BOOL			handleControlKey(const KEY key, const MASK mask);
 
@@ -279,6 +282,7 @@ protected:
 	LLUIColor			mDefaultColor;
 
 	BOOL				mShowLineNumbers;
+	bool				mAutoIndent;
 
 	/*virtual*/ void	updateSegments();
 	void				updateLinkSegments();
@@ -321,6 +325,7 @@ private:
 	BOOL			mAllowEmbeddedItems;
 	bool			mShowContextMenu;
 	bool			mParseOnTheFly;
+	bool			mPassDelete;
 
 	LLUUID			mSourceID;
 
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index 935dcb74b0..a50184460b 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -150,7 +150,7 @@ void LLExpandableTextBox::LLTextBoxEx::showExpandText()
 		std::pair<S32, S32> visible_lines = getVisibleLines(true);
 		S32 last_line = visible_lines.second - 1;
 
-		LLStyle::Params expander_style(getDefaultStyleParams());
+		LLStyle::Params expander_style(getStyleParams());
 		expander_style.font.style = "UNDERLINE";
 		expander_style.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
 		LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, mExpanderLabel, *this);
@@ -166,7 +166,7 @@ void LLExpandableTextBox::LLTextBoxEx::hideExpandText()
 	if (mExpanderVisible)
 	{
 		// this will overwrite the expander segment and all text styling with a single style
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		LLNormalTextSegment* segmentp = new LLNormalTextSegment(sp, 0, getLength() + 1, *this);
 		insertSegment(segmentp);
 		
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 2de891565c..aba3d74d87 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -406,7 +406,7 @@ void LLGroupListItem::setActive(bool active)
 	// *BUG: setName() overrides the style params.
 
 	// Active group should be bold.
-	LLFontDescriptor new_desc(mGroupNameBox->getDefaultFont()->getFontDesc());
+	LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
 
 	// *NOTE dzaporozhan
 	// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 30a9c29ec6..dde7d248dd 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -44,7 +44,7 @@
 #include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
 #include "llinventoryfunctions.h"
 //#include "lllayoutstack.h"
-#include "lllineeditor.h"
+#include "llchatentry.h"
 #include "lllogchat.h"
 #include "llscreenchannel.h"
 #include "llsyswellwindow.h"
@@ -64,6 +64,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
 	mInputEditor(NULL),
+	mInputEditorTopPad(0),
 	mSavedTitle(),
 	mTypingStart(),
 	mShouldSendTypingState(false),
@@ -190,7 +191,9 @@ void LLIMFloater::sendMsg()
 	{
 		if (mInputEditor)
 		{
-			LLWString text = mInputEditor->getConvertedText();
+			LLWString text = mInputEditor->getWText();
+			LLWStringUtil::trim(text);
+			LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
 			if(!text.empty())
 			{
 				// Truncate and convert to UTF8 for transport
@@ -287,26 +290,26 @@ BOOL LLIMFloater::postBuild()
 {
 	LLIMConversation::postBuild();
 
-	mInputEditor = getChild<LLLineEditor>("chat_editor");
+	mInputEditor = getChild<LLChatEntry>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
 	// enable line history support for instant message bar
-	mInputEditor->setEnableLineHistory(TRUE);
 
 	LLFontGL* font = LLViewerChat::getChatFont();
 	mInputEditor->setFont(font);	
 	
 	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
 	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
-	mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
+	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
 	mInputEditor->setCommitOnFocusLost( FALSE );
-	mInputEditor->setRevertOnEsc( FALSE );
-	mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
 	mInputEditor->setPassDelete( TRUE );
 
-	childSetCommitCallback("chat_editor", onSendMsg, this);
+	mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this));
+	mInputEditor->setTextExpandedCallback(boost::bind(&LLIMFloater::reshapeChatHistory, this));
 	
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
+	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
+
 	setDocked(true);
 
 	mTypingStart = LLTrans::getString("IM_typing_start_string");
@@ -880,7 +883,7 @@ void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userd
 }
 
 // static
-void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
+void LLIMFloater::onInputEditorKeystroke(LLTextEditor* caller, void* userdata)
 {
 	LLIMFloater* self = (LLIMFloater*) userdata;
 	std::string text = self->mInputEditor->getText();
@@ -1077,7 +1080,7 @@ private:
 BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 {
 	LLViewerRegion* region = gAgent.getRegion();
-	bool is_region_exist = !!region;
+	bool is_region_exist = region != NULL;
 
 	if (is_region_exist)
 	{
@@ -1158,6 +1161,17 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 	}
 }
 
+void LLIMFloater::reshapeChatHistory()
+{
+	LLRect chat_rect  = mChatHistory->getRect();
+	LLRect input_rect = mInputEditor->getRect();
+
+	int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad);
+
+	chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height);
+	mChatHistory->setShape(chat_rect);
+}
+
 // static
 void LLIMFloater::closeHiddenIMToasts()
 {
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 333340c696..1992bd930c 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -37,7 +37,9 @@
 
 class LLAvatarName;
 class LLButton;
-class LLLineEditor;
+class LLChatEntry;
+class LLTextEditor;
+class LLPanelChatControlPanel;
 class LLChatHistory;
 class LLInventoryItem;
 class LLInventoryCategory;
@@ -142,7 +144,7 @@ private:
 	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
 	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
-	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
+	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
 	void setTyping(bool typing);
 	void onAddButtonClicked();
 	void onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
@@ -161,6 +163,13 @@ private:
 	// Remove the "User is typing..." indicator.
 	void removeTypingIndicator(const LLIMInfo* im_info = NULL);
 
+	/**
+	 * Adjusts chat history height to fit vertically with input chat field
+	 * and avoid overlapping, since input chat field can be vertically expanded.
+	 * Implementation: chat history bottom "follows" top+top_pad of input chat field
+	 */
+	void reshapeChatHistory();
+
 	static void closeHiddenIMToasts();
 
 	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
@@ -171,9 +180,11 @@ private:
 
 	LLChatHistory* mChatHistory;
 
+	int mInputEditorTopPad; // padding between input field and chat history
+
 	EInstantMessage mDialog;
 	LLUUID mOtherParticipantUUID;
-	LLLineEditor* mInputEditor;
+	LLChatEntry* mInputEditor;
 	bool mPositioned;
 
 	std::string mSavedTitle;
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index 280cc11179..854deb00d0 100644
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -230,7 +230,7 @@ void LLPanelTopInfoBar::buildLocationString(std::string& loc_str, bool show_coor
 void LLPanelTopInfoBar::setParcelInfoText(const std::string& new_text)
 {
 	LLRect old_rect = getRect();
-	const LLFontGL* font = mParcelInfoText->getDefaultFont();
+	const LLFontGL* font = mParcelInfoText->getFont();
 	S32 new_text_width = font->getWidth(new_text);
 
 	mParcelInfoText->setText(new_text);
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 707d2d9765..ed350ea144 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -112,7 +112,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
 		style.font = date_font;
 	pMessageText->appendText(timeStr + "\n", TRUE, style);
 	
-	style.font = pMessageText->getDefaultFont();
+	style.font = pMessageText->getFont();
 	pMessageText->appendText(message, TRUE, style);
 
 	//attachment
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index e20d516392..09f8dcf83c 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -68,7 +68,7 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 	if (message->getVisible())
 	{
 		S32 heightDelta = 0;
-		S32 maxTextHeight = message->getDefaultFont()->getLineHeight() * maxLineCount;
+		S32 maxTextHeight = message->getFont()->getLineHeight() * maxLineCount;
 
 		LLRect messageRect = message->getRect();
 		S32 oldTextHeight = messageRect.getHeight();
diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
index 2529ec865a..45fbabad59 100644
--- a/indra/newview/lltoastscripttextbox.cpp
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -65,7 +65,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification
 	pMessageText->clear();
 
 	LLStyle::Params style;
-	style.font = pMessageText->getDefaultFont();
+	style.font = pMessageText->getFont();
 	pMessageText->appendText(message, TRUE, style);
 
 	//submit button
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index a4695b8c09..f6d5b20a65 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -242,18 +242,21 @@
              bottom="-1" 
              follows="left|right|bottom" 
              tab_group="1">    
-            	<line_editor
+            	<text_editor
              		bottom="0"
+             		expand_lines_count="5"
              		follows="left|right|bottom"
 	         		font="SansSerifSmall"
 	         		visible="true"
              		height="20"
+             		is_expandable="true"
              		label="To"
              		layout="bottomleft"
              		name="chat_editor"
              		tab_group="3"
-             		width="220">
-            	</line_editor>
+             		width="240"
+             		wrap="true">
+            	</text_editor>
               </panel>
     </layout_panel>
   </layout_stack>
diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml
index 134f2d7522..2102074674 100644
--- a/indra/newview/skins/default/xui/en/widgets/text.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text.xml
@@ -9,6 +9,7 @@
       h_pad="0" 
       allow_scroll="false"
       text_readonly_color="LabelTextColor"
+      text_tentative_color="TextFgTentativeColor"
       bg_writeable_color="FloaterDefaultBackgroundColor" 
       use_ellipses="false"
       bg_visible="false" 
-- 
cgit v1.2.3


From ad4ae5583534197cb00c13d769e504fcde4d19d5 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 19 Jun 2012 20:37:07 +0300
Subject: Win build fix

---
 indra/llui/llchatentry.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index 6f51705b90..1da7900f59 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -30,7 +30,7 @@
 
 static LLDefaultChildRegistry::Register<LLChatEntry> r("text_editor");
 
-LLChatEntry::LLChatEntry::Params::Params()
+LLChatEntry::Params::Params()
 :	has_history("has_history", true),
  	is_expandable("is_expandable", false),
  	expand_lines_count("expand_lines_count", 1)
-- 
cgit v1.2.3


From c0842339e72b15331a5bbb6bd41324c28916d678 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 19 Jun 2012 15:05:20 -0700
Subject: CHUI-138 : Suppress chiclets for conversations when using tabbed UI;
 Make sure list is cleaned up on close

---
 indra/newview/llchicletbar.cpp |  9 ++++++++-
 indra/newview/llimfloater.cpp  | 20 ++++++++++----------
 2 files changed, 18 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index 8701b602ce..54a49ca49c 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -102,6 +102,13 @@ void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& nam
 	// no need to spawn chiclets for participants in P2P calls called through Avaline
 	if (session->isP2P() && session->isOtherParticipantAvaline()) return;
 
+	// Do not spawn chiclet when using the new multitab conversation UI
+	if (LLIMConversation::isChatMultiTab())
+	{
+		LLIMFloater::addToHost(session_id);
+		return;
+	}
+	
 	if (getChicletPanel()->findChiclet<LLChiclet>(session_id)) return;
 
 	LLIMChiclet* chiclet = createIMChiclet(session_id);
@@ -109,7 +116,7 @@ void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& nam
 	{
 		chiclet->setIMSessionName(name);
 		chiclet->setOtherParticipantId(other_participant_id);
-		
+
 		LLIMFloater::onIMChicletCreated(session_id);
 
 	}
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 882637151d..4b954de738 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -109,6 +109,16 @@ void LLIMFloater::onFocusReceived()
 // virtual
 void LLIMFloater::onClose(bool app_quitting)
 {
+	// Always suppress the IM from the conversations list on close if present for any reason
+	if (LLIMConversation::isChatMultiTab())
+	{
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
+		if (im_box)
+		{
+            im_box->removeConversationListItem(mSessionID);
+        }
+    }
+
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
 				mSessionID);
 
@@ -140,16 +150,6 @@ void LLIMFloater::onClose(bool app_quitting)
 	// Last change:
 	// EXT-3516 X Button should end IM session, _ button should hide
 	gIMMgr->leaveSession(mSessionID);
-    
-	// Suppress the IM from the conversations list
-	if (LLIMConversation::isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
-		if (im_box)
-		{
-            im_box->removeConversationListItem(mSessionID);
-        }
-    }
 }
 
 /* static */
-- 
cgit v1.2.3


From 49596f4b7fca83dbd7e49ee0780ac6f5574a5746 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 19 Jun 2012 16:41:08 -0700
Subject: CHUI-148 : Fix reattaching on a hidden message panel; also prevents
 recreation of list items (eventually lead to crashes).

---
 indra/newview/llimfloatercontainer.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 10188febab..fb5697e2f2 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -123,7 +123,11 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 		openFloater(floaterp->getKey());
 		return;
 	}
+	
+	// Make sure the message panel is open when adding a floater or it stays mysteriously hidden
+	collapseMessagesPane(false);
 
+	// Add the floater
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
 	LLUUID session_id = floaterp->getKey();
@@ -355,6 +359,14 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
 // CHUI-137 : Temporary implementation of conversations list
 void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp)
 {
+	// Check if the item is not already in the list, exit if it is (nothing to do)
+	// Note: this happens often, when reattaching a torn off conversation for instance
+	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
+	if (item_it != mConversationsItems.end())
+	{
+		return;
+	}
+
 	// Create a conversation item
 	LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, containerp);
 	mConversationsItems[uuid] = item;
-- 
cgit v1.2.3


From c8857cc72270479ed3a5a04b14be3361b2eafea9 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 19 Jun 2012 19:25:58 -0700
Subject: CHUI-142 : Changes to chat related preferences

---
 indra/newview/app_settings/settings.xml            | 15 +-----
 indra/newview/llfloaterpreference.cpp              |  6 ---
 indra/newview/llimconversation.cpp                 |  3 +-
 .../default/xui/en/panel_preferences_chat.xml      | 58 ----------------------
 4 files changed, 3 insertions(+), 79 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 46c29e32e2..feb80a3611 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1538,7 +1538,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>ChatBubbleOpacity</key>
     <map>
@@ -1617,17 +1617,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>ChatWindow</key>
-    <map>
-      <key>Comment</key>
-      <string>Show chat in multiple windows(by default) or in one multi-tabbed window(requires restart)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>S32</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>CheesyBeacon</key>
     <map>
       <key>Comment</key>
@@ -9809,7 +9798,7 @@
 	<key>ShowScriptErrorsLocation</key>
     <map>
       <key>Comment</key>
-      <string>Show script error in chat or window</string>
+      <string>Show script error in chat (0) or window (1).</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 18ab9dc264..996cf1e212 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -423,8 +423,6 @@ void LLFloaterPreference::saveAvatarProperties( void )
 
 BOOL LLFloaterPreference::postBuild()
 {
-//	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
-
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
@@ -542,8 +540,6 @@ void LLFloaterPreference::apply()
 	
 //	LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString());
 //	LLWStringUtil::replaceTabsWithSpaces(busy_response, 4);
-
-	gSavedSettings.setBOOL("PlainTextChatHistory", getChild<LLUICtrl>("plain_text_chat_history")->getValue().asBoolean());
 	
 	if (mGotPersonalInfo)
 	{ 
@@ -1412,8 +1408,6 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
 	getChildView("send_im_to_email")->setEnabled(TRUE);
 	getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
-	getChildView("plain_text_chat_history")->setEnabled(TRUE);
-	getChild<LLUICtrl>("plain_text_chat_history")->setValue(gSavedSettings.getBOOL("PlainTextChatHistory"));
 	getChildView("log_instant_messages")->setEnabled(TRUE);
 //	getChildView("log_chat")->setEnabled(TRUE);
 //	getChildView("busy_response")->setEnabled(TRUE);
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index ead87e3ed5..c3dba3e49e 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -321,6 +321,5 @@ void LLIMConversation::onTearOffClicked()
 bool LLIMConversation::isChatMultiTab()
 {
 	// Restart is required in order to change chat window type.
-	static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1;
-	return is_single_window;
+	return true;
 }
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index caf7fc85f5..d7a7f7d735 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -75,15 +75,6 @@
      name="send_im_to_email"
      top_pad="5"
      width="400" />
-    <check_box
-     enabled="false"
-     height="16"
-     label="Enable plain text IM and chat history"
-     layout="topleft"
-     left_delta="0"
-     name="plain_text_chat_history"
-     top_pad="5"
-     width="400" />
     <check_box
      control_name="UseChatBubbles"
      follows="left|top"
@@ -94,55 +85,6 @@
      top_pad="5"
      name="bubble_text_chat"
      width="150" />     
-    <text
-     name="show_ims_in_label"
-     follows="left|top"
-     layout="topleft"
-     left="30"
-     height="20"
-     width="170"
-     top_pad="15">
-     Show IMs in:
-    </text>
-    <text
-     name="requires_restart_label"
-     follows="left|top"
-     layout="topleft"
-     top_delta="0" 
-     left="170" 
-  	 height="20"
-	 width="130"
-     text_color="White_25">
-      (requires restart)
-      </text>
-    <radio_group
-     follows="left|top"
-     height="30"
-     left="40"
-     control_name="ChatWindow"
-     name="chat_window"
-     top_pad="0"
-     tool_tip="Show your Instant Messages in separate floaters, or in one floater with many tabs (Requires restart)"
-     width="150">
-     <radio_item
-      height="16"
-      label="Separate Windows"
-      layout="topleft"
-      left="0"
-      name="radio"
-      value="0"
-      top="0"
-      width="150" />
-     <radio_item
-      height="16"
-      label="Tabs"
-      layout="topleft"
-      left_delta="0"
-      name="radio2"
-      value="1"
-      top_pad="5"
-      width="150" />
-    </radio_group>
     <text
      name="disable_toast_label"
      follows="left|top"
-- 
cgit v1.2.3


From 9e49fb558f894a1960d208114b8c051536f58c9e Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 19 Jun 2012 22:36:12 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose added more casts to
 LLFolderViewModelItemInventory, etc. to fix compile errors

---
 indra/newview/llavataractions.cpp                  |  4 +-
 indra/newview/llinventorybridge.cpp                | 42 +++-------
 indra/newview/llinventorybridge.h                  | 11 +--
 indra/newview/llinventorypanel.cpp                 |  6 ++
 indra/newview/llinventorypanel.h                   |  1 +
 indra/newview/llpanellandmarks.cpp                 | 94 +++++++++++-----------
 indra/newview/llpanellandmarks.h                   |  2 +
 indra/newview/llpanelmaininventory.cpp             |  6 +-
 indra/newview/llpanelmarketplaceinbox.cpp          |  8 +-
 indra/newview/llpanelmarketplaceinboxinventory.cpp |  2 +-
 indra/newview/llpanelobjectinventory.cpp           | 21 +++--
 indra/newview/lltexturectrl.cpp                    |  2 +-
 12 files changed, 103 insertions(+), 96 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 68dc7681cc..b154dd458c 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -733,7 +733,7 @@ std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
 		it != end_it;
 		++it)
 	{
-		inventory_selected_uuids.insert((*it)->getListener()->getUUID());
+		inventory_selected_uuids.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
 	}
 	return inventory_selected_uuids;
 }
@@ -778,7 +778,7 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 	const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
 	for (; it != it_end; ++it)
 	{
-		LLViewerInventoryCategory* inv_cat = gInventory.getCategory((*it)->getItemViewModel()->getUUID());
+		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
 		// any category can be offered.
 		if (inv_cat)
 		{
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 312b7314a1..44d0fdd3dd 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -895,7 +895,7 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const
 	return panel ? panel->getModel() : NULL;
 }
 
-LLInventoryFilter* getInventoryFilter() const
+LLInventoryFilter* LLInvFVBridge::getInventoryFilter() const
 {
 	LLInventoryPanel* panel = mInventoryPanel.get();
 	return panel ? panel->getFilter() : NULL;
@@ -1278,7 +1278,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 			LLFolderViewFolder * object_folderp =   mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(object_id) : NULL;
 			if (object_folderp)
 			{
-				can_list = !object_folderp->isLoading();
+				can_list = !static_cast<LLFolderBridge*>(object_folderp->getViewModelItem())->isLoading();
 			}
 		}
 		
@@ -1319,7 +1319,7 @@ LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const
 		return LLToolDragAndDrop::SOURCE_LIBRARY;
 	}
 
-	return SOURCE_VIEWER;
+	return LLToolDragAndDrop::SOURCE_VIEWER;
 }
 
 
@@ -1534,7 +1534,7 @@ PermissionMask LLItemBridge::getPermissionMask() const
 	return perm_mask;
 }
 
-void LLItemBridge::buildDisplayName()
+void LLItemBridge::buildDisplayName() const
 {
 	if(getItem())
 	{
@@ -1817,7 +1817,7 @@ void LLFolderBridge::selectItem()
 	LLInventoryModelBackgroundFetch::instance().start(getUUID(), true);
 }
 
-void LLFolderBridge::buildDisplayName()
+void LLFolderBridge::buildDisplayName() const
 {
 	LLFolderType::EType preferred_type = getPreferredType();
 
@@ -1845,7 +1845,7 @@ void LLFolderBridge::buildDisplayName()
 	//can not be detected as protected with LLFolderType::lookupIsProtectedType
 	if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
 	{
-		LLTrans::findString(mDisplayName, "InvFolder " + getName());
+		LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
 	};
 }
 
@@ -1859,7 +1859,7 @@ void LLFolderBridge::update()
 		possibly_has_children = true;
 	}
 
-	BOOL loading = (possibly_has_children
+	bool loading = (possibly_has_children
 		&& !up_to_date );
 
 	if (loading != mIsLoading)
@@ -3415,7 +3415,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 			// Do not call execute() or done() here as if the folder is here, there's likely no point drilling down 
 			// This saves lots of time as buildContextMenu() is called a lot
 			delete fetch;
-			buildContextMenuFolderOptions(flags);
+			buildContextMenuFolderOptions(flags, items, disabled_items);
 		}
 		else
 		{
@@ -3628,23 +3628,6 @@ void LLFolderBridge::pasteClipboard(void* user_data)
 	if(self) self->pasteFromClipboard();
 }
 
-void LLFolderBridge::createNewCategory(void* user_data)
-{
-	LLFolderBridge* bridge = (LLFolderBridge*)user_data;
-	if(!bridge) return;
-	LLInventoryModel* model = bridge->getInventoryModel();
-	if(!model) return;
-	LLUUID id;
-	id = model->createNewCategory(bridge->getUUID(),
-								  LLFolderType::FT_NONE,
-								  LLStringUtil::null);
-	model->notifyObservers();
-
-	// At this point, the bridge has probably been deleted, but the
-	// view is still there.
-	panel->setSelection(id, TAKE_FOCUS_YES);
-}
-
 void LLFolderBridge::createNewShirt(void* user_data)
 {
 	LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_SHIRT);
@@ -3830,9 +3813,10 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
 	LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
 	LLInventoryPanel* panel = mInventoryPanel.get();
 	LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
-	if (drag_over_item && drag_over_item->getViewModelItem())
+	LLFolderViewModelItemInventory* view_model = drag_over_item ? static_cast<LLFolderViewModelItemInventory*>(drag_over_item->getViewModelItem()) : NULL;
+	if (view_model)
 	{
-		cb.get()->setTargetLandmarkId(drag_over_item->getViewModelItem()->getUUID());
+		cb.get()->setTargetLandmarkId(view_model->getUUID());
 	}
 
 	copy_inventory_item(
@@ -4032,7 +4016,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 				if (itemp)
 				{
 					LLUUID srcItemId = inv_item->getUUID();
-					LLUUID destItemId = itemp->getViewModelItem()->getUUID();
+					LLUUID destItemId = static_cast<LLFolderViewModelItemInventory*>(itemp->getViewModelItem())->getUUID();
 					gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId);
 				}
 			}
@@ -6119,7 +6103,7 @@ void LLLinkFolderBridge::gotoItem()
 	const LLUUID &cat_uuid = getFolderID();
 	if (!cat_uuid.isNull())
 	{
-                LLFolderViewItem *base_folder =   mInventoryPanel.get()->getItemByID(cat_uuid)
+		LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid);
 		if (base_folder)
 		{
 			if (LLInventoryModel* model = getInventoryModel())
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index bc5ac24c70..d303e8377d 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -176,7 +176,7 @@ protected:
 	mutable std::string			mDisplayName;
 
 	void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
-	virtual void buildDisplayName();
+	virtual void buildDisplayName() const;
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -230,7 +230,7 @@ public:
 protected:
 	BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
 	virtual BOOL isItemPermissive() const;
-	virtual void buildDisplayName();
+	virtual void buildDisplayName() const;
 
 };
 
@@ -249,7 +249,7 @@ public:
 	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);
 	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg);
 
-    virtual void buildDisplayName();
+    virtual void buildDisplayName() const;
 
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual void openItem();
@@ -293,6 +293,8 @@ public:
 	LLViewerInventoryCategory* getCategory() const;
 	LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
 
+	bool isLoading() { return mIsLoading; }
+
 protected:
 	void buildContextMenuOptions(U32 flags, menuentry_vec_t& items,   menuentry_vec_t& disabled_items);
 	void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items,   menuentry_vec_t& disabled_items);
@@ -301,7 +303,6 @@ protected:
 	// Menu callbacks
 	//--------------------------------------------------------------------
 	static void pasteClipboard(void* user_data);
-	static void createNewCategory(void* user_data);
 	static void createNewShirt(void* user_data);
 	static void createNewPants(void* user_data);
 	static void createNewShoes(void* user_data);
@@ -337,7 +338,7 @@ private:
 	bool							mWearables;
 	bool							mIsLoading;
 	LLTimer							mTimeSinceRequestStart;
-	std::string						mDisplayName;
+	mutable std::string				mDisplayName;
 	LLRootHandle<LLFolderBridge> mHandle;
 };
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index e739694fe0..d3f6474392 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -600,6 +600,11 @@ LLFolderView* LLInventoryPanel::getRootFolder()
 	return mFolderRoot; 
 }
 
+LLUUID LLInventoryPanel::getRootFolderID()
+{
+	return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
+}
+
 
 // static
 void LLInventoryPanel::onIdle(void *userdata)
@@ -1146,6 +1151,7 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
 	if (!floater_inventory)
 	{
 		llwarns << "Could not find My Inventory floater" << llendl;
+
 		return FALSE;
 	}
 
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index cd32b18779..2aa05e1b61 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -203,6 +203,7 @@ public:
 	// This method is called when something has changed about the inventory.
 	void modelChanged(U32 mask);
 	LLFolderView* getRootFolder();
+	LLUUID getRootFolderID();
 	LLScrollContainer* getScrollableContainer() { return mScroller; }
 	
 	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 54ad2bcb76..901c6379de 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -138,7 +138,7 @@ private:
 // virtual
 void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)
 {
-	if (folder->getViewModelItem() && folder->getViewModelItem()->getUUID() == mFolderID)
+	if (folder->getViewModelItem() && static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem())->getUUID() == mFolderID)
 	{
 		if (!folder->isOpen())
 		{
@@ -281,28 +281,21 @@ void LLLandmarksPanel::onShowOnMap()
 //virtual
 void LLLandmarksPanel::onShowProfile()
 {
-	LLFolderViewItem* cur_item = getCurSelectedItem();
+	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
 
 	if(!cur_item)
 		return;
 
-	cur_item->getViewModelItem()->performAction(mCurrentSelectedList->getModel(),"about");
+	cur_item->performAction(mCurrentSelectedList->getModel(),"about");
 }
 
 // virtual
 void LLLandmarksPanel::onTeleport()
 {
-	LLFolderViewItem* current_item = getCurSelectedItem();
-	if (!current_item)
-	{
-		llwarns << "There are no selected list. No actions are performed." << llendl;
-		return;
-	}
-
-	LLFolderViewModelItem* listenerp = current_item->getViewModelItem();
-	if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	LLFolderViewModelItemInventory* view_model_item = getCurSelectedViewModelItem();
+	if (view_model_item && view_model_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
-		listenerp->openItem();
+		view_model_item->openItem();
 	}
 }
 
@@ -360,7 +353,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()
 	LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
 	if (!cur_item) return;
 
-	LLFolderViewModelItem* listenerp = cur_item->getViewModelItem();
+	LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
 	if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		LLSD key;
@@ -417,8 +410,9 @@ void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_
 
 bool LLLandmarksPanel::isLandmarkSelected() const 
 {
-	LLFolderViewItem* current_item = getCurSelectedItem();
-	if(current_item && current_item->getViewModelItem()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	LLFolderViewModelItemInventory* current_item = getCurSelectedViewModelItem();
+
+	if(current_item && current_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		return true;
 	}
@@ -440,10 +434,10 @@ bool LLLandmarksPanel::isReceivedFolderSelected() const
 
 void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
 {
-	LLFolderViewItem* cur_item = getCurSelectedItem();
-	if(cur_item && cur_item->getViewModelItem()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
+	if(cur_item && cur_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{ 
-		LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getViewModelItem()->getUUID(), cb);
+		LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getUUID(), cb);
 		if (landmark)
 		{
 			cb(landmark);
@@ -456,6 +450,17 @@ LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const
 	return mCurrentSelectedList ?  mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL;
 }
 
+LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem() const
+{
+	LLFolderViewItem* cur_item = getCurSelectedItem();
+	if (cur_item)
+	{
+		return 	static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
+	}
+	return NULL;
+}
+
+
 LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
 															 const std::string& tab_name,
 															 const LLUUID& obj_id,
@@ -508,12 +513,12 @@ void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)
 	// We have to make request to sever to get parcel_id and snaption_id. 
 	if(isLandmarkSelected())
 	{
-		LLFolderViewItem* cur_item = getCurSelectedItem();
+		LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
 		if (!cur_item) return;
-		LLUUID id = cur_item->getViewModelItem()->getUUID();
+		LLUUID id = cur_item->getUUID();
 		LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
 		doActionOnCurSelectedLandmark(boost::bind(
-				&LLLandmarksPanel::doProcessParcelInfo, this, _1, cur_item, inv_item, parcel_data));
+				&LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data));
 	}
 }
 
@@ -646,7 +651,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI
 	// Start background fetch, mostly for My Inventory and Library
 	if (expanded)
 	{
-		const LLUUID &cat_id = inventory_list->getRootFolderID();
+		const LLUUID &cat_id = mCurrentSelectedList->getRootFolderID();
 		// Just because the category itself has been fetched, doesn't mean its child folders have.
 		/*
 		  if (!gInventory.isCategoryComplete(cat_id))
@@ -731,14 +736,9 @@ void LLLandmarksPanel::onActionsButtonClick()
 {
 	LLToggleableMenu* menu = mGearFolderMenu;
 
-	LLFolderViewItem* cur_item = NULL;
 	if(mCurrentSelectedList)
 	{
-		cur_item = mCurrentSelectedList->getRootFolder()->getCurSelectedItem();
-		if(!cur_item)
-			return;
-
-		LLFolderViewModelItem* listenerp = cur_item->getViewModelItem();
+		LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem();
 		if(!listenerp)
 			return;
 
@@ -776,6 +776,9 @@ void LLLandmarksPanel::onTrashButtonClick() const
 
 void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 {
+	LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem();
+	LLFolderViewItem* item = getCurSelectedItem();
+
 	std::string command_name = userdata.asString();
 	if("add_landmark" == command_name)
 	{
@@ -791,21 +794,21 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 	} 
 	else if ("category" == command_name)
 	{
-		LLFolderViewItem* item = getCurSelectedItem();
 		if (item && mCurrentSelectedList == mLandmarksInventoryPanel)
 		{
 			LLFolderViewModelItem* folder_bridge = NULL;
-			if (item-> getViewModelItem()->getInventoryType()
+
+			if (view_model->getInventoryType()
 					== LLInventoryType::IT_LANDMARK)
 			{
 				// for a landmark get parent folder bridge
 				folder_bridge = item->getParentFolder()->getViewModelItem();
 			}
-			else if (item-> getViewModelItem()->getInventoryType()
+			else if (view_model->getInventoryType()
 					== LLInventoryType::IT_CATEGORY)
 			{
 				// for a folder get its own bridge
-				folder_bridge = item->getViewModelItem();
+				folder_bridge = view_model;
 			}
 
 			menu_create_inventory_item(mCurrentSelectedList,
@@ -834,9 +837,9 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
 	std::string command_name = userdata.asString();
     if("copy_slurl" == command_name)
 	{
-    	LLFolderViewItem* cur_item = getCurSelectedItem();
+    	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
 		if(cur_item)
-			LLLandmarkActions::copySLURLtoClipboard(cur_item->getViewModelItem()->getUUID());
+			LLLandmarkActions::copySLURLtoClipboard(cur_item->getUUID());
 	}
 	else if ( "paste" == command_name)
 	{
@@ -984,11 +987,6 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 		{
 			LLFolderViewItem* item = *iter;
 
-			// If no item is found it might be a folder id.
-			if (!item)
-			{
-				item = root_folder_view->getFolderByID(*iter);
-			}
 			if (!item) return false;
 
 			if (!canItemBeModified(command_name, item)) return false;
@@ -1012,10 +1010,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 
 		if ("show_on_map" == command_name)
 		{
-			LLFolderViewItem* cur_item = root_folder_view->getCurSelectedItem();
+			LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
 			if (!cur_item) return false;
 
-			LLViewerInventoryItem* inv_item = static_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem())->getInventoryObject());
+			LLViewerInventoryItem* inv_item = dynamic_cast<LLViewerInventoryItem*>(cur_item->getInventoryObject());
 			if (!inv_item) return false;
 
 			LLUUID asset_uuid = inv_item->getAssetUUID();
@@ -1105,23 +1103,23 @@ void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)
 	{
 		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
 
-		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList();
+		std::set<LLFolderViewItem*> selected_items =    root_folder_view->getSelectionList();
 
 		// Iterate through selected items to find out if any of these items are in Trash
 		// or all the items are in Trash category.
-		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_items.begin(); iter != selected_items.end(); ++iter)
 		{
 			LLFolderViewItem* item = *iter;
 
 			// If no item is found it might be a folder id.
 			if (!item) continue;
 
-			LLFolderViewModelItem* listenerp = item->getViewModelItem();
+			LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
 			if(!listenerp) continue;
 
 			// Trash category itself should not be included because it can't be
 			// actually restored from trash.
-			are_all_items_in_trash &= listenerp->isItemInTrash() &&    (*iter)->getItemViewModel()->getUUID() != trash_id;
+			are_all_items_in_trash &= listenerp->isItemInTrash() &&    listenerp->getUUID() != trash_id;
 
 			// If there are any selected items in Trash including the Trash category itself
 			// we show "Restore Item" in context menu and hide other irrelevant items.
@@ -1160,7 +1158,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 	bool can_be_modified = false;
 
 	// landmarks can be modified in any other accordion...
-	if (item->getViewModelItem()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		can_be_modified = true;
 
@@ -1198,7 +1196,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 
 	if (can_be_modified)
 	{
-		LLFolderViewModelItemInventory* listenerp = item->getViewModelItem();
+		LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
 
 		if ("cut" == command_name)
 		{
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index b2f4e92473..aa5f69739d 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -44,6 +44,7 @@ class LLMenuGL;
 class LLToggleableMenu;
 class LLInventoryPanel;
 class LLPlacesInventoryPanel;
+class LLFolderViewModelItemInventory;
 
 class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 {
@@ -87,6 +88,7 @@ protected:
 	bool isReceivedFolderSelected() const;
 	void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
 	LLFolderViewItem* getCurSelectedItem() const;
+	LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const;
 
 	/**
 	 * Selects item with "obj_id" in "inventory_list" and scrolls accordion
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index fbdbce61bd..565a7408c2 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -47,6 +47,7 @@
 #include "llresmgr.h"
 #include "llscrollcontainer.h"
 #include "llsdserialize.h"
+#include "llsdparam.h"
 #include "llspinctrl.h"
 #include "lltoggleablemenu.h"
 #include "lltooldraganddrop.h"
@@ -230,7 +231,10 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
 		if (filter)
 		{
 			LLSD filterState;
-			filter->toLLSD(filterState);
+			LLInventoryFilter::Params p;
+			filter->toParams(p);
+			LLParamSDParser parser;
+			parser.writeSD(filterState, p);
 			filterRoot[filter->getName()] = filterState;
 		}
 
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 8a07d6d516..3547156197 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -143,8 +143,8 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 		
 		if (inbox_folder)
 		{
-			LLFolderViewFolder::folders_t::iterator folders_it = inbox_folder->getFoldersBegin();
-			LLFolderViewFolder::folders_t::iterator folders_end = inbox_folder->getFoldersEnd();
+			LLFolderViewFolder::folders_t::const_iterator folders_it = inbox_folder->getFoldersBegin();
+			LLFolderViewFolder::folders_t::const_iterator folders_end = inbox_folder->getFoldersEnd();
 
 			for (; folders_it != folders_end; ++folders_it)
 			{
@@ -157,8 +157,8 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 				}
 			}
 
-			LLFolderViewFolder::items_t::iterator items_it = inbox_folder->getItemsBegin();
-			LLFolderViewFolder::items_t::iterator items_end = inbox_folder->getItemsEnd();
+			LLFolderViewFolder::items_t::const_iterator items_it = inbox_folder->getItemsBegin();
+			LLFolderViewFolder::items_t::const_iterator items_end = inbox_folder->getItemsEnd();
 
 			for (; items_it != items_end; ++items_it)
 			{
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 1d079adfd3..2947be3c2e 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -30,7 +30,7 @@
 
 #include "llfolderview.h"
 #include "llfolderviewitem.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 #include "llpanellandmarks.h"
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index ae68b5ce95..56df01e150 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -109,6 +109,8 @@ public:
 	/*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
 	virtual const LLUUID& getUUID() const { return mUUID; }
 	virtual time_t getCreationDate() const;
+	virtual void setCreationDate(time_t creation_date_utc);
+
 	virtual LLUIImagePtr getIcon() const;
 	virtual void openItem();
 	virtual BOOL canOpenItem() const { return FALSE; }
@@ -130,11 +132,15 @@ public:
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual BOOL isUpToDate() const { return TRUE; }
-	virtual BOOL hasChildren() const { return FALSE; }
+	virtual bool hasChildren() const { return FALSE; }
 	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
 	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+	virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; }
+	virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); }
+
 
 	// LLDragAndDropBridge functionality
+	virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_WORLD; }
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
@@ -338,6 +344,10 @@ time_t LLTaskInvFVBridge::getCreationDate() const
 	return 0;
 }
 
+void LLTaskInvFVBridge::setCreationDate(time_t creation_date_utc)
+{}
+
+
 LLUIImagePtr LLTaskInvFVBridge::getIcon() const
 {
 	const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS);
@@ -461,7 +471,7 @@ BOOL LLTaskInvFVBridge::removeItem()
 	return FALSE;
 }
 
-void   LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewModelItem*>&   batch)
+void   LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
 {
 	if (!mPanel)
 	{
@@ -703,7 +713,7 @@ public:
 	virtual BOOL renameItem(const std::string& new_name);
 	virtual BOOL isItemRemovable() const;
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-	virtual BOOL hasChildren() const;
+	virtual bool hasChildren() const;
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
@@ -711,6 +721,7 @@ public:
 							std::string& tooltip_msg);
 	virtual BOOL canOpenItem() const { return TRUE; }
 	virtual void openItem();
+	virtual EInventorySortGroup getSortGroup() const { return SG_NORMAL_FOLDER; }
 };
 
 LLTaskCategoryBridge::LLTaskCategoryBridge(
@@ -761,7 +772,7 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	hide_context_entries(menu, items, disabled_items);
 }
 
-BOOL LLTaskCategoryBridge::hasChildren() const
+bool LLTaskCategoryBridge::hasChildren() const
 {
 	// return TRUE if we have or do know know if we have children.
 	// *FIX: For now, return FALSE - we will know for sure soon enough.
@@ -1748,7 +1759,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 			}
 			view->addToFolder(folder);
-                        addItemID(view->getViewModelItem()->getUUID(), view);
+			addItemID(view->getViewModelItem()->getUUID(), view);
 		}
 	}
 
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index a995f07df7..b7fa283dd2 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -623,7 +623,7 @@ void LLFloaterTexturePicker::draw()
 		LLFolderView* folder_view = mInventoryPanel->getRootFolder();
 		if (!folder_view) return;
 
-		LLInventoryFilter* filter = folder_view->getFilter();
+		LLInventoryFilter* filter = static_cast<LLInventoryFilter*>(folder_view->getFilter());
 		if (!filter) return;
 
 		bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
-- 
cgit v1.2.3


From 3882e9c177190b22276e1ef3fc39e4cb910820fd Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 20 Jun 2012 00:19:05 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose more compilation
 fixes, just need to add getName() back to LLInventoryFilter et al

---
 indra/llinventory/llinventory.cpp                  |  6 ++++++
 indra/newview/llfolderview.cpp                     |  8 +++++++-
 indra/newview/llfolderviewitem.cpp                 |  6 ++++++
 indra/newview/llfolderviewitem.h                   |  4 ++--
 indra/newview/llfolderviewmodel.h                  |  9 ---------
 indra/newview/llinventorybridge.h                  |  2 +-
 indra/newview/llinventoryfilter.h                  |  1 -
 indra/newview/llinventorypanel.cpp                 |  5 +++++
 indra/newview/llpanelmaininventory.cpp             | 17 ++++++++--------
 indra/newview/llpanelmarketplaceinboxinventory.cpp | 23 +++++++++++-----------
 indra/newview/llpanelobjectinventory.cpp           |  1 -
 indra/newview/llpaneloutfitedit.cpp                |  8 ++++----
 indra/newview/llplacesinventorypanel.cpp           |  2 +-
 indra/newview/llsidepanelinventory.cpp             |  4 ++--
 indra/newview/lltexturectrl.cpp                    |  2 +-
 indra/newview/llviewerinventory.cpp                |  2 +-
 indra/newview/llviewermessage.cpp                  |  4 ++--
 17 files changed, 58 insertions(+), 46 deletions(-)

(limited to 'indra')

diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 784e20ad46..6e54f9d78a 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -509,6 +509,12 @@ U32 LLInventoryItem::getFlags() const
 	return mFlags;
 }
 
+time_t LLInventoryItem::getCreationDate() const
+{
+	return mCreationDate;
+}
+
+
 // virtual
 void LLInventoryItem::packMessage(LLMessageSystem* msg) const
 {
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index f0edbb638a..78f4bc1119 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -1976,7 +1976,7 @@ void LLFolderView::doIdle()
 		LLFastTimer t3(FTM_AUTO_SELECT);
 		// select new item only if a filtered item not currently selected
 		LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
-		if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->potentiallyFiltered()))
+		if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->potentiallyHidden()))
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
@@ -2293,3 +2293,9 @@ S32 LLFolderView::getItemHeight()
 	}
 	return debug_height;
 }
+
+//TODO RN: move to llfolderviewmodel.cpp file
+bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
+{
+	return item->getSortVersion() < mTargetSortVersion;
+}
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 6e60ec5e1a..5b73a34d29 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -221,6 +221,12 @@ BOOL LLFolderViewItem::potentiallyVisible()
 		||	getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration(); // or we don't know yet
 }
 
+BOOL LLFolderViewItem::potentiallyHidden()
+{
+	return !mPassedFilter // didn't pass the filter
+		|| getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration(); // or we don't know yet
+}
+
 BOOL LLFolderViewItem::getFiltered() 
 { 
 	return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 9e024d7eea..1f8c12cf73 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -245,8 +245,8 @@ public:
 	BOOL			isDescendantOf( const LLFolderViewFolder* potential_ancestor );
 	S32				getIndentation() { return mIndentation; }
 
-	virtual BOOL	potentiallyVisible(); // do we know for a fact that this item won't be displayed?
-	virtual BOOL	potentiallyFiltered(); // do we know for a fact that this item has been filtered out?
+	virtual BOOL	potentiallyVisible(); // is the item definitely visible or we haven't made up our minds yet?
+	virtual BOOL	potentiallyHidden(); // did this item not pass the filter or do we not know yet?
 
 	virtual BOOL	getFiltered();
 	virtual BOOL	getFiltered(S32 filter_generation);
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 9bbd7f48cf..631e3eec1c 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -88,7 +88,6 @@ public:
 	virtual bool 				isActive() const = 0;
 	virtual bool 				isModified() const = 0;
 	virtual void 				clearModified() = 0;
-	virtual const std::string& 	getName() const = 0;
 	virtual const std::string& 	getFilterText() = 0;
 	//RN: this is public to allow system to externally force a global refilter
 	virtual void 				setModified(EFilterModified behavior = FILTER_RESTART) = 0;
@@ -305,12 +304,4 @@ protected:
 	FilterType	mFilter;
 };
 
-
-bool LLFolderViewModelCommon::needsSort(class LLFolderViewModelItem* item)
-{
-	return item->getSortVersion() < mTargetSortVersion;
-}
-
-
-
 #endif
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index d303e8377d..111735e198 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -176,7 +176,7 @@ protected:
 	mutable std::string			mDisplayName;
 
 	void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
-	virtual void buildDisplayName() const;
+	virtual void buildDisplayName() const {}
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index e0c3d7141b..175a16c401 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -220,7 +220,6 @@ public:
 	bool 				isModified() const;
 	bool 				isSinceLogoff() const;
 	void 				clearModified();
-	const std::string& 	getName() const;
 	const std::string& 	getFilterText();
 	//RN: this is public to allow system to externally force a global refilter
 	void 				setModified(EFilterModified behavior = FILTER_RESTART);
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index d3f6474392..f6861d83de 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -358,6 +358,11 @@ const LLInventoryFilter* LLInventoryPanel::getFilter() const
 	return &getFolderViewModel()->getFilter();
 }
 
+LLInventoryFilter* LLInventoryPanel::getFilter()
+{
+	return &getFolderViewModel()->getFilter();
+}
+
 void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
 {
 	if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 565a7408c2..e3446fdb3a 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -981,7 +981,7 @@ void LLPanelMainInventory::saveTexture(const LLSD& userdata)
 		return;
 	}
 	
-	const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
+	const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 	LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
 	if (preview_texture)
 	{
@@ -1054,7 +1054,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		const LLUUID item_id = current_item->getViewModelItem()->getUUID();
+		const LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item)
 		{
@@ -1069,7 +1069,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		current_item->getViewModelItem()->performAction(getActivePanel()->getModel(), "goto");
+		static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto");
 	}
 
 	if (command_name == "find_links")
@@ -1079,7 +1079,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
+		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		const std::string &item_name = current_item->getViewModelItem()->getName();
 		mFilterSubString = item_name;
 		LLInventoryFilter *filter = mActivePanel->getFilter();
@@ -1125,9 +1125,8 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 				 iter != selection_set.end();
 				 ++iter)
 			{
-				const LLUUID &item_id = (*iter);
 				LLFolderViewItem *item = *iter;
-				const LLFolderViewModelItemInventory *listener = item->getViewModelItem();
+				const LLFolderViewModelItemInventory *listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 				llassert(listener);
 				if (!listener) return FALSE;
 				can_delete &= listener->isItemRemovable();
@@ -1145,7 +1144,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	{
 		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
+		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		const LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item && item->getIsLinkType() && !item->getIsBrokenLink())
 		{
@@ -1161,7 +1160,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 		if (selection_set.size() != 1) return FALSE;
 		LLFolderViewItem* current_item = root->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
+		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		const LLInventoryObject *obj = gInventory.getObject(item_id);
 		if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
 		{
@@ -1174,7 +1173,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	{
 		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getViewModelItem()->getUUID();
+		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		const LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item && item->getIsBrokenLink())
 		{
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 2947be3c2e..d2143783ad 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -208,7 +208,7 @@ void LLInboxFolderViewFolder::computeFreshness()
 
 	if (last_expansion_utc > 0)
 	{
-		mFresh = (mCreationDate > last_expansion_utc);
+		mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
 
 #if DEBUGGING_FRESHNESS
 		if (mFresh)
@@ -230,15 +230,16 @@ void LLInboxFolderViewFolder::deFreshify()
 	gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
 }
 
-void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc)
-{ 
-	mCreationDate = creation_date_utc; 
-
-	if (mParentFolder == mRoot)
-	{
-		computeFreshness();
-	}
-}
+// TODO RN: move this behavior to modelview?
+//void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc)
+//{ 
+//	mCreationDate = creation_date_utc; 
+//
+//	if (LLFolderViewItem::mParentFolder == mRoot)
+//	{
+//		computeFreshness();
+//	}
+//}
 
 //
 // LLInboxFolderViewItem Implementation
@@ -304,7 +305,7 @@ void LLInboxFolderViewItem::computeFreshness()
 
 	if (last_expansion_utc > 0)
 	{
-		mFresh = (mCreationDate > last_expansion_utc);
+		mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
 
 #if DEBUGGING_FRESHNESS
 		if (mFresh)
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 56df01e150..0ba8c1ce6d 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1759,7 +1759,6 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 			}
 			view->addToFolder(folder);
-			addItemID(view->getViewModelItem()->getUUID(), view);
 		}
 	}
 
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index a95d27f992..d690a18477 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -891,7 +891,7 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT
 
 			if (result.second == 1)
 			{
-				result.first =    getWearableTypeByItemUUID((*selected_items.begin())->getListener()->getUUID());
+				result.first = getWearableTypeByItemUUID(static_cast<LLFolderViewModelItemInventory*>((*selected_items.begin())->getViewModelItem())->getUUID());
 			}
 		}
 		else if (mWearableItemsList != NULL && mWearableItemsList->getVisible())
@@ -1310,7 +1310,7 @@ void LLPanelOutfitEdit::getCurrentItemUUID(LLUUID& selected_id)
 		LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
 		if (!curr_item) return;
 
-		LLFolderViewModelItemInventory* listenerp  = curr_item->getViewModelItem();
+		LLFolderViewModelItemInventory* listenerp  = static_cast<LLFolderViewModelItemInventory*>(curr_item->getViewModelItem());
 		if (!listenerp) return;
 
 		selected_id = listenerp->getUUID();
@@ -1332,7 +1332,7 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)
 			it != end_it;
 			++it)
 		{
-			uuid_list.push_back((*it)->getItemViewModel()->getUUID());
+			uuid_list.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
 		}
 	}
 	else if (mWearablesListViewPanel->getVisible())
@@ -1384,7 +1384,7 @@ void LLPanelOutfitEdit::saveListSelection()
 
 		for (std::set<LLFolderViewItem*>::const_iterator item_id =    selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
 		{
-			mWearableItemsList->selectItemByUUID((*item_id)->getItemViewModel()->getUUID(),    true);
+			mWearableItemsList->selectItemByUUID(static_cast<LLFolderViewModelItemInventory*>((*item_id)->getViewModelItem())->getUUID(),    true);
 		}
 		mWearableItemsList->scrollToShowFirstSelectedItem();
 	}
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index da5ce7d4b7..1c2d75d88c 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -162,7 +162,7 @@ BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	// then determine its type and set necessary menu handle
 	if (getCurSelectedItem())
 	{
-		LLInventoryType::EType inventory_type = getCurSelectedItem()->getViewModelItem()->getInventoryType();
+		LLInventoryType::EType inventory_type = static_cast<LLFolderViewModelItemInventory*>(getCurSelectedItem()->getViewModelItem())->getInventoryType();
 		inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
 
 		if (it_handle != mMenuHandlesByInventoryType.end())
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index f3d32e7a67..47bd620fc6 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -473,7 +473,7 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
 		}
 	}
 
-	current_item->getViewModelItem()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
+	static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
 }
 
 void LLSidepanelInventory::onWearButtonClicked()
@@ -663,7 +663,7 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
 			return NULL;
 		}
 	}
-	const LLUUID &item_id = current_item->getViewModelItem()->getUUID();
+	const LLUUID &item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 	LLInventoryItem *item = gInventory.getItem(item_id);
 	return item;
 }
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index b7fa283dd2..50d63911ad 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -800,7 +800,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
 	if (items.size())
 	{
 		LLFolderViewItem* first_item = items.front();
-		LLInventoryItem* itemp = gInventory.getItem(first_item->getViewModelItem()->getUUID());
+		LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID());
 		mNoCopyTextureSelected = FALSE;
 		if (itemp)
 		{
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index d827b2b8aa..749a6d22e0 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1375,7 +1375,7 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge,
 			llwarns << "Can't create unrecognized type " << type_name << llendl;
 		}
 	}
-	panel->getRoot()->->setNeedsAutoRename(TRUE);	
+	panel->getRootFolder()->setNeedsAutoRename(TRUE);	
 }
 
 LLAssetType::EType LLViewerInventoryItem::getType() const
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 90d144b458..b0e36d756d 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -821,7 +821,7 @@ private:
 				it != end_it;
 				++it)
 			{
-				mSelectedItems.insert((*it)->getListener()->getUUID());
+				mSelectedItems.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
 			}
 		}
 		mSelectedItems.erase(mMoveIntoFolderID);
@@ -864,7 +864,7 @@ private:
 			it != end_it;
 			++it)
 		{
-			selected_items.insert((*it)->getListener()->getUUID());
+			selected_items.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
 		}
 		selected_items.erase(mMoveIntoFolderID);
 
-- 
cgit v1.2.3


From fd247320ceab3ab6dc6abdf17008618cf3f6a8ff Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 20 Jun 2012 17:51:56 +0300
Subject: CHUI-125 FIXED if a call is accept then open im-session's floater

---
 indra/newview/llchiclet.h              |  7 ++++---
 indra/newview/llchicletbar.cpp         | 19 ++++++++++++-------
 indra/newview/llchicletbar.h           |  7 ++++---
 indra/newview/llimfloatercontainer.cpp | 13 +++++++++++++
 indra/newview/llimfloatercontainer.h   | 11 ++++++++++-
 indra/newview/llimview.cpp             | 15 +++++++++++++--
 indra/newview/llimview.h               |  2 ++
 indra/newview/llsyswellwindow.h        |  1 +
 8 files changed, 59 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 3973b6547a..f51d7b622c 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -873,9 +873,10 @@ class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
 {
 	friend class LLUICtrlFactory;
 public:
-	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
-	virtual void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
-	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
+	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
+	/*virtual*/ void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
+	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
 
 	~LLIMWellChiclet();
 protected:
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index 8701b602ce..66c93bd18b 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -57,19 +57,24 @@ LLChicletBar::LLChicletBar(const LLSD&)
 :	mChicletPanel(NULL),
 	mToolbarStack(NULL)
 {
-	// Firstly add our self to IMSession observers, so we catch session events
-	// before chiclets do that.
-	LLIMMgr::getInstance()->addSessionObserver(this);
+	// IM floaters are from now managed by LLIMFloaterContainer.
+	// See LLIMFloaterContainer::sessionVoiceOrIMStarted() and CHUI-125
+
+//	// Firstly add our self to IMSession observers, so we catch session events
+//	// before chiclets do that.
+//	LLIMMgr::getInstance()->addSessionObserver(this);
 
 	buildFromFile("panel_chiclet_bar.xml");
 }
 
 LLChicletBar::~LLChicletBar()
 {
-	if (!LLSingleton<LLIMMgr>::destroyed())
-	{
-		LLIMMgr::getInstance()->removeSessionObserver(this);
-	}
+	// IM floaters are from now managed by LLIMFloaterContainer.
+	// See LLIMFloaterContainer::sessionVoiceOrIMStarted() and CHUI-125
+//	if (!LLSingleton<LLIMMgr>::destroyed())
+//	{
+//		LLIMMgr::getInstance()->removeSessionObserver(this);
+//	}
 }
 
 LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id)
diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h
index 1427bf95e0..7d0d904810 100644
--- a/indra/newview/llchicletbar.h
+++ b/indra/newview/llchicletbar.h
@@ -50,9 +50,10 @@ public:
 	LLChicletPanel*	getChicletPanel() { return mChicletPanel; }
 
 	// LLIMSessionObserver observe triggers
-	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-	virtual void sessionRemoved(const LLUUID& session_id);
-	void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
+	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
+	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
 
 	S32 getTotalUnreadIMCount();
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 8493a0e7b8..deeb0e9e0b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -50,6 +50,9 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 :	LLMultiFloater(seed)
 	,mExpandCollapseBtn(NULL)
 {
+	// Firstly add our self to IMSession observers, so we catch session events
+    LLIMMgr::getInstance()->addSessionObserver(this);
+
 	mAutoResize = FALSE;
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
 }
@@ -61,8 +64,18 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 	gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed());
 	gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
+
+	if (!LLSingleton<LLIMMgr>::destroyed())
+	{
+		LLIMMgr::getInstance()->removeSessionObserver(this);
+	}
 }
 
+void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
+{
+		LLIMFloater::show(session_id);
+};
+
 BOOL LLIMFloaterContainer::postBuild()
 {
 	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index b5b60615b3..239d6a08a3 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -30,6 +30,7 @@
 #include <map>
 #include <vector>
 
+#include "llimview.h"
 #include "llfloater.h"
 #include "llmultifloater.h"
 #include "llavatarpropertiesprocessor.h"
@@ -117,7 +118,9 @@ private:
 };
 // CHUI-137 : End
 
-class LLIMFloaterContainer : public LLMultiFloater
+class LLIMFloaterContainer
+	: public LLMultiFloater
+	, public LLIMSessionObserver
 {
 public:
 	LLIMFloaterContainer(const LLSD& seed);
@@ -144,6 +147,12 @@ public:
 	
 	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 
+	// LLIMSessionObserver observe triggers
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
+	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
+	/*virtual*/ void sessionRemoved(const LLUUID& session_id) {};
+	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {};
+
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
 	avatarID_panel_map_t mSessions;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 0d2b1f06b5..4b82596f37 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2582,7 +2582,9 @@ LLUUID LLIMMgr::addSession(
 {
 	LLDynamicArray<LLUUID> ids;
 	ids.put(other_participant_id);
-	return addSession(name, dialog, other_participant_id, ids, voice);
+	LLUUID session_id = addSession(name, dialog, other_participant_id, ids, voice);
+	notifyObserverSessionVoiceOrIMStarted(session_id);
+	return session_id;
 }
 
 // Adds a session using the given session_id.  If the session already exists 
@@ -2609,7 +2611,8 @@ LLUUID LLIMMgr::addSession(
 
 	if (floater_id.notNull())
 	{
-		LLIMFloater* im_floater = LLIMFloater::findInstance(floater_id);
+		LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+
 		if (im_floater && im_floater->getStartConferenceInSameFloater())
 		{
 			// The IM floater should be initialized with a new session_id
@@ -2936,6 +2939,14 @@ void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::st
 	}
 }
 
+void LLIMMgr::notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id)
+{
+	for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+	{
+		(*it)->sessionVoiceOrIMStarted(session_id);
+	}
+}
+
 void LLIMMgr::notifyObserverSessionRemoved(const LLUUID& session_id)
 {
 	for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 58a2ac5162..80bf315aa8 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -298,6 +298,7 @@ class LLIMSessionObserver
 public:
 	virtual ~LLIMSessionObserver() {}
 	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) = 0;
 	virtual void sessionRemoved(const LLUUID& session_id) = 0;
 	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) = 0;
 };
@@ -462,6 +463,7 @@ private:
 	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
 
 	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	void notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id);
 	void notifyObserverSessionRemoved(const LLUUID& session_id);
 	void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
 
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index f497f546aa..8758c8c4e5 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -169,6 +169,7 @@ public:
 
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
 
-- 
cgit v1.2.3


From 84c8050ca0a39fe16a40d3fb9870160ad3fbee84 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 20 Jun 2012 21:26:56 +0300
Subject: CHUI-149 [WIP] Add the participant list to the nearby chat as
 IM-conversation

---
 indra/newview/llimconversation.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index c3dba3e49e..f12821352b 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -120,8 +120,11 @@ BOOL LLIMConversation::tick()
 }
 
 void LLIMConversation::buildParticipantList()
-{	if (mIsNearbyChat)
+{
+	if (mIsNearbyChat)
 	{
+		LLLocalSpeakerMgr* speaker_manager = LLLocalSpeakerMgr::getInstance();
+		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);
 	}
 	else
 	{
@@ -212,8 +215,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 	bool is_participant_list_visible =
 			!is_hosted
 			&& gSavedSettings.getBOOL("IMShowControlPanel")
-			&& !mIsP2PChat
-			&& !mIsNearbyChat; // *TODO: temporarily disabled for Nearby chat
+			&& !mIsP2PChat;
 
 	mParticipantListPanel->setVisible(is_participant_list_visible);
 
@@ -223,7 +225,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
 
 	// The button (>>) should be disabled for torn off P2P conversations.
-	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat && !mIsNearbyChat);
+	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat);
 
 	if (mDragHandle)
 	{
-- 
cgit v1.2.3


From 316d8fc875d54bfcc7e7eb8d215a4810947bcb71 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 20 Jun 2012 14:58:02 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose fixed final build
 errors

---
 indra/newview/llfolderview.cpp      | 2 +-
 indra/newview/llfolderviewmodel.h   | 1 +
 indra/newview/llinventoryfilter.cpp | 3 ++-
 indra/newview/llinventoryfilter.h   | 6 +++++-
 4 files changed, 9 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 78f4bc1119..2bc6f26c85 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -183,7 +183,7 @@ LLFolderView::LLFolderView(const Params& p)
 	mNeedsAutoRename(FALSE),
 	mDebugFilters(FALSE),
 	mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME),	// This gets overridden by a pref immediately
-	mFilter(),
+	mFilter(new LLInventoryFilter(LLInventoryFilter::Params().name(p.title))),
 	mShowSelectionContext(FALSE),
 	mShowSingleSelection(FALSE),
 	mArrangeGeneration(0),
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 631e3eec1c..946943530a 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -88,6 +88,7 @@ public:
 	virtual bool 				isActive() const = 0;
 	virtual bool 				isModified() const = 0;
 	virtual void 				clearModified() = 0;
+	virtual const std::string& 	getName() const = 0;
 	virtual const std::string& 	getFilterText() = 0;
 	//RN: this is public to allow system to externally force a global refilter
 	virtual void 				setModified(EFilterModified behavior = FILTER_RESTART) = 0;
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 9c9b04d03d..c13bb5123e 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -65,7 +65,8 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
 /// Class LLInventoryFilter
 ///----------------------------------------------------------------------------
 LLInventoryFilter::LLInventoryFilter(const Params& p)
-:	mFilterModified(FILTER_NONE),
+:	mName(p.name),
+	mFilterModified(FILTER_NONE),
 	mEmptyLookupMessage("InventoryNoMatchingItems"),
     mFilterOps(p.filter_ops),
 	mOrder(p.sort_order),
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 175a16c401..5b92c21a85 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -131,13 +131,15 @@ public:
 							
 	struct Params : public LLInitParam::Block<Params>
 	{
+		Optional<std::string>		name;
 		Optional<FilterOps::Params>	filter_ops;
 		Optional<std::string>		substring;
 		Optional<U32>				sort_order;
 		Optional<bool>				since_logoff;
 
 		Params()
-		:	filter_ops(""),
+		:	name("name"),
+			filter_ops(""),
 			substring("substring"),
 			sort_order("sort_order"),
 			since_logoff("since_logoff")
@@ -220,6 +222,7 @@ public:
 	bool 				isModified() const;
 	bool 				isSinceLogoff() const;
 	void 				clearModified();
+	const std::string& 	getName() const { return mName; }
 	const std::string& 	getFilterText();
 	//RN: this is public to allow system to externally force a global refilter
 	void 				setModified(EFilterModified behavior = FILTER_RESTART);
@@ -265,6 +268,7 @@ private:
 
 	std::string				mFilterSubString;
 	std::string				mFilterSubStringOrig;
+	const std::string		mName;
 
 	S32						mLastSuccessGeneration;
 	S32						mLastFailGeneration;
-- 
cgit v1.2.3


From c517863b9c0e19507eafc8842e1e68379e6122a9 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 20 Jun 2012 19:17:54 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose build fix for gcc

---
 indra/newview/llfolderviewitem.h  | 5 ++---
 indra/newview/llfolderviewmodel.h | 4 ++--
 2 files changed, 4 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 1f8c12cf73..feba32e31d 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -464,7 +464,6 @@ public:
 									   std::string& tooltip_msg);
 	virtual void draw();
 
-
 	folders_t::iterator getFoldersBegin() { return mFolders.begin(); }
 	folders_t::iterator getFoldersEnd() { return mFolders.end(); }
 	folders_t::size_type getFoldersCount() const { return mFolders.size(); }
@@ -478,8 +477,8 @@ public:
 
 public:
 	//WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
-	template<typename SORT_FUNC> void sortFolders(SORT_FUNC& func) { mFolders.sort(func); }
-	template<typename SORT_FUNC> void sortItems(SORT_FUNC& func) { mItems.sort(func); }
+	template<typename SORT_FUNC> void sortFolders(const SORT_FUNC& func) { mFolders.sort(func); }
+	template<typename SORT_FUNC> void sortItems(const SORT_FUNC& func) { mItems.sort(func); }
 };
 
 
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 946943530a..930c26384c 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -255,12 +255,12 @@ public:
 		:	mSorter(sorter)
 		{}
 		
-		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b)
+		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
 		{
 			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
 		}
 
-		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b)
+		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
 		{
 			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
 		}
-- 
cgit v1.2.3


From a02f2e63f20021d007a6a20c33cc961500b14236 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 21 Jun 2012 10:11:55 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose one more gcc build fix

---
 indra/newview/llfolderview.cpp     | 7 +++++--
 indra/newview/llinventorypanel.cpp | 3 ++-
 2 files changed, 7 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 2bc6f26c85..6bae1d5644 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -289,6 +289,9 @@ LLFolderView::~LLFolderView( void )
 
 	delete mFilter;
 	mFilter = NULL;
+
+	delete mViewModel;
+	mViewModel = NULL;
 }
 
 BOOL LLFolderView::canFocusChildren() const
@@ -345,12 +348,12 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_gen
 	LLFolderViewFolder::arrange(&mMinWidth, &target_height, mFilter->getFirstSuccessGeneration());
 
 	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
-	reshape( llmax(scroll_rect.getWidth(), mMinWidth), mCurHeight );
+	reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
 
 	LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
 	if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
 	{
-		reshape( llmax(scroll_rect.getWidth(), mMinWidth), mCurHeight );
+		reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
 	}
 
 	// move item renamer text field to item's new position
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index f6861d83de..d576160277 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -685,7 +685,8 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
 	p.rect = folder_rect;
 	p.parent_panel = this;
 	p.tool_tip = p.name;
-	p.listener =  bridge;
+	p.listener = bridge;
+	p.view_model = new LLFolderViewModelInventory();
 	p.use_label_suffix = useLabelSuffix;
 	p.allow_multiselect = mAllowMultiSelect;
 	p.show_empty_message = mShowEmptyMessage;
-- 
cgit v1.2.3


From 4775084000233ec9f0770f421771215397b987e7 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 21 Jun 2012 23:28:24 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose inventory item labels
 and icons displaying again

---
 indra/newview/llfavoritesbar.cpp                   | 308 ++++++++++++++++++-
 indra/newview/llfavoritesbar.h                     | 111 +++++++
 indra/newview/llfolderview.cpp                     |   2 +
 indra/newview/llfolderview.h                       |   6 +-
 indra/newview/llfolderviewitem.cpp                 |  71 ++---
 indra/newview/llfolderviewitem.h                   |  11 +-
 indra/newview/llfolderviewmodel.h                  |  38 ++-
 indra/newview/llinventorybridge.cpp                |  24 +-
 indra/newview/llinventorybridge.h                  |   7 +-
 indra/newview/llinventorymodel.cpp                 |  61 ----
 indra/newview/llinventorymodel.h                   |   9 -
 indra/newview/llinventorypanel.cpp                 |  44 +--
 indra/newview/llinventorypanel.h                   |   2 +-
 indra/newview/llpanelmarketplaceinboxinventory.cpp |  16 -
 .../newview/llpanelmarketplaceoutboxinventory.cpp  |  16 -
 indra/newview/llpanelobjectinventory.cpp           |  16 +-
 indra/newview/llviewerinventory.cpp                | 341 ---------------------
 indra/newview/llviewerinventory.h                  |  17 +-
 18 files changed, 512 insertions(+), 588 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 575b613ccf..4a96de942d 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -38,6 +38,7 @@
 #include "lltooltip.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llclipboard.h"
 #include "llclipboard.h"
 #include "llinventorybridge.h"
@@ -45,12 +46,14 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llfloaterworldmap.h"
 #include "lllandmarkactions.h"
+#include "lllogininstance.h"
 #include "llnotificationsutil.h"
 #include "lltoggleablemenu.h"
 #include "llviewerinventory.h"
 #include "llviewermenu.h"
 #include "llviewermenu.h"
 #include "lltooldraganddrop.h"
+#include "llsdserialize.h"
 
 static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
 
@@ -317,7 +320,8 @@ public:
 
 		if (item)
 		{
-			item->setSortField(mSortField);
+			LLFavoritesOrderStorage::instance().setSortIndex(item, mSortField);
+
 			item->setComplete(TRUE);
 			item->updateServer(FALSE);
 
@@ -339,8 +343,8 @@ struct LLFavoritesSort
 	// TODO - made it customizible using gSavedSettings
 	bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)
 	{
-		S32 sortField1 = a->getSortField();
-		S32 sortField2 = b->getSortField();
+		S32 sortField1 = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
+		S32 sortField2 = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
 
 		if (!(sortField1 < 0 && sortField2 < 0))
 		{
@@ -528,7 +532,7 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
 		mItems.push_back(gInventory.getItem(mDragItemId));
 	}
 
-	gInventory.saveItemsOrder(mItems);
+	LLFavoritesOrderStorage::instance().saveItemsOrder(mItems);
 
 	LLToggleableMenu* menu = (LLToggleableMenu*) mOverflowMenuHandle.get();
 
@@ -587,7 +591,8 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
 		}
 		else
 		{
-			currItem->setSortField(++sortField);
+			LLFavoritesOrderStorage::instance().setSortIndex(currItem, ++sortField);
+
 			currItem->setComplete(TRUE);
 			currItem->updateServer(FALSE);
 
@@ -640,7 +645,7 @@ void LLFavoritesBarCtrl::changed(U32 mask)
 		
 		for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
 		{
-			(*i)->getSLURL();
+			LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
 		}
 		updateButtons();
 	}
@@ -909,7 +914,7 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
 		S32 sortField = 0;
 		for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
 		{
-			(*i)->setSortField(++sortField);
+			LLFavoritesOrderStorage::instance().setSortIndex((*i), ++sortField);
 		}
 	}
 
@@ -1355,7 +1360,7 @@ BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array
 	// if there is an item without sort order field set, we need to save items order
 	for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
 	{
-		if ((*i)->getSortField() < 0)
+		if (LLFavoritesOrderStorage::instance().getSortIndex((*i)->getUUID()) < 0)
 		{
 			result = TRUE;
 			break;
@@ -1390,4 +1395,291 @@ void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const
 	}
 }
 
+const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
+const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
+
+void LLFavoritesOrderStorage::setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index)
+{
+	mSortIndexes[inv_item->getUUID()] = sort_index;
+	mIsDirty = true;
+	getSLURL(inv_item->getAssetUUID());
+}
+
+S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
+{
+	sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
+	if (it != mSortIndexes.end())
+	{
+		return it->second;
+	}
+	return NO_INDEX;
+}
+
+void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
+{
+	mSortIndexes.erase(inv_item_id);
+	mIsDirty = true;
+}
+
+void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
+{
+	slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
+	if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
+
+	LLLandmark* lm = gLandmarkList.getAsset(asset_id,
+		boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
+	if (lm)
+	{
+		onLandmarkLoaded(asset_id, lm);
+	}
+}
+
+// static
+void LLFavoritesOrderStorage::destroyClass()
+{
+	LLFavoritesOrderStorage::instance().cleanup();
+	if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
+	{
+		LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
+	}
+	else
+	{
+		LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
+	}
+}
+
+void LLFavoritesOrderStorage::load()
+{
+	// load per-resident sorting information
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+
+	LLSD settings_llsd;
+	llifstream file;
+	file.open(filename);
+	if (file.is_open())
+	{
+		LLSDSerialize::fromXML(settings_llsd, file);
+	}
+
+	for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+		iter != settings_llsd.endMap(); ++iter)
+	{
+		mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+	}
+}
+
+void LLFavoritesOrderStorage::saveFavoritesSLURLs()
+{
+	// Do not change the file if we are not logged in yet.
+	if (!LLLoginInstance::getInstance()->authSuccess())
+	{
+		llwarns << "Cannot save favorites: not logged in" << llendl;
+		return;
+	}
+
+	std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+	if (user_dir.empty())
+	{
+		llwarns << "Cannot save favorites: empty user dir name" << llendl;
+		return;
+	}
+
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+	llifstream in_file;
+	in_file.open(filename);
+	LLSD fav_llsd;
+	if (in_file.is_open())
+	{
+		LLSDSerialize::fromXML(fav_llsd, in_file);
+	}
+
+	const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+	LLSD user_llsd;
+	for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
+	{
+		LLSD value;
+		value["name"] = (*it)->getName();
+		value["asset_id"] = (*it)->getAssetUUID();
+
+		slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
+		if (slurl_iter != mSLURLs.end())
+		{
+			lldebugs << "Saving favorite: idx=" << LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID()) << ", SLURL=" <<  slurl_iter->second << ", value=" << value << llendl;
+			value["slurl"] = slurl_iter->second;
+			user_llsd[LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())] = value;
+		}
+		else
+		{
+			llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl;
+		}
+	}
+
+	LLAvatarName av_name;
+	LLAvatarNameCache::get( gAgentID, &av_name );
+	lldebugs << "Saved favorites for " << av_name.getLegacyName() << llendl;
+	fav_llsd[av_name.getLegacyName()] = user_llsd;
+
+	llofstream file;
+	file.open(filename);
+	LLSDSerialize::toPrettyXML(fav_llsd, file);
+}
+
+void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
+{
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+	LLSD fav_llsd;
+	llifstream file;
+	file.open(filename);
+	if (!file.is_open()) return;
+	LLSDSerialize::fromXML(fav_llsd, file);
+
+	LLAvatarName av_name;
+	LLAvatarNameCache::get( gAgentID, &av_name );
+	lldebugs << "Removed favorites for " << av_name.getLegacyName() << llendl;
+	if (fav_llsd.has(av_name.getLegacyName()))
+	{
+		fav_llsd.erase(av_name.getLegacyName());
+	}
+
+	llofstream out_file;
+	out_file.open(filename);
+	LLSDSerialize::toPrettyXML(fav_llsd, out_file);
+
+}
+
+void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
+{
+	if (!landmark) return;
+
+	LLVector3d pos_global;
+	if (!landmark->getGlobalPos(pos_global))
+	{
+		// If global position was unknown on first getGlobalPos() call
+		// it should be set for the subsequent calls.
+		landmark->getGlobalPos(pos_global);
+	}
+
+	if (!pos_global.isExactlyZero())
+	{
+		LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
+			boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
+	}
+}
+
+void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
+{
+	lldebugs << "Saving landmark SLURL: " << slurl << llendl;
+	mSLURLs[asset_id] = slurl;
+}
+
+void LLFavoritesOrderStorage::save()
+{
+	// nothing to save if clean
+	if (!mIsDirty) return;
+
+	// If we quit from the login screen we will not have an SL account
+	// name.  Don't try to save, otherwise we'll dump a file in
+	// C:\Program Files\SecondLife\ or similar. JC
+	std::string user_dir = gDirUtilp->getLindenUserDir();
+	if (!user_dir.empty())
+	{
+		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+		LLSD settings_llsd;
+
+		for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
+		{
+			settings_llsd[iter->first.asString()] = iter->second;
+		}
+
+		llofstream file;
+		file.open(filename);
+		LLSDSerialize::toPrettyXML(settings_llsd, file);
+	}
+}
+
+void LLFavoritesOrderStorage::cleanup()
+{
+	// nothing to clean
+	if (!mIsDirty) return;
+
+	const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+	IsNotInFavorites is_not_in_fav(items);
+
+	sort_index_map_t  aTempMap;
+	//copy unremoved values from mSortIndexes to aTempMap
+	std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(), 
+		inserter(aTempMap, aTempMap.begin()),
+		is_not_in_fav);
+
+	//Swap the contents of mSortIndexes and aTempMap
+	mSortIndexes.swap(aTempMap);
+}
+
+void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array_t& items )
+{
+	int sortField = 0;
+
+	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+	for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+	{
+		LLViewerInventoryItem* item = *i;
+
+		setSortIndex(item, ++sortField);
+
+		item->setComplete(TRUE);
+		item->updateServer(FALSE);
+
+		gInventory.updateItem(item);
+
+		// Tell the parent folder to refresh its sort order.
+		gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
+	}
+
+	gInventory.notifyObservers();
+}
+
+// See also LLInventorySort where landmarks in the Favorites folder are sorted.
+class LLViewerInventoryItemSort
+{
+public:
+	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
+	{
+		return LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID()) 
+			< LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+	}
+};
+
+// * @param source_item_id - LLUUID of the source item to be moved into new position
+// * @param target_item_id - LLUUID of the target item before which source item should be placed.
+void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
+{
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLIsType is_type(LLAssetType::AT_LANDMARK);
+	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+	// ensure items are sorted properly before changing order. EXT-3498
+	std::sort(items.begin(), items.end(), LLViewerInventoryItemSort());
+
+	// update order
+	gInventory.updateItemsOrder(items, source_item_id, target_item_id);
+
+	saveItemsOrder(items);
+}
+
+void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
+{
+	if (mTargetLandmarkId.isNull()) return;
+
+	LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
+}
 // EOF
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2f75b3bb0e..60e02b661e 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -33,6 +33,7 @@
 
 #include "llinventoryobserver.h"
 #include "llinventorymodel.h"
+#include "llviewerinventory.h"
 
 class LLMenuItemCallGL;
 class LLToggleableMenu;
@@ -161,5 +162,115 @@ private:
 	boost::signals2::connection mEndDragConnection;
 };
 
+class AddFavoriteLandmarkCallback : public LLInventoryCallback
+{
+public:
+	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
+	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
+
+private:
+	void fire(const LLUUID& inv_item);
+
+	LLUUID mTargetLandmarkId;
+};
+
+/**
+ * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
+ * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
+ * Data are stored in user home directory.
+ */
+class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
+	, public LLDestroyClass<LLFavoritesOrderStorage>
+{
+	LOG_CLASS(LLFavoritesOrderStorage);
+public:
+	/**
+	 * Sets sort index for specified with LLUUID favorite landmark
+	 */
+	void setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index);
+
+	/**
+	 * Gets sort index for specified with LLUUID favorite landmark
+	 */
+	S32 getSortIndex(const LLUUID& inv_item_id);
+	void removeSortIndex(const LLUUID& inv_item_id);
+
+	void getSLURL(const LLUUID& asset_id);
+
+	// Saves current order of the passed items using inventory item sort field.
+	// Resets 'items' sort fields and saves them on server.
+	// Is used to save order for Favorites folder.
+	void saveItemsOrder(const LLInventoryModel::item_array_t& items);
+
+	void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+
+	/**
+	 * Implementation of LLDestroyClass. Calls cleanup() instance method.
+	 *
+	 * It is important this callback is called before gInventory is cleaned.
+	 * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
+	 * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
+	 * @see cleanup()
+	 */
+	static void destroyClass();
+
+	const static S32 NO_INDEX;
+private:
+	friend class LLSingleton<LLFavoritesOrderStorage>;
+	LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
+	~LLFavoritesOrderStorage() { save(); }
+
+	/**
+	 * Removes sort indexes for items which are not in Favorites bar for now.
+	 */
+	void cleanup();
+
+	const static std::string SORTING_DATA_FILE_NAME;
+
+	void load();
+	void save();
+
+	void saveFavoritesSLURLs();
+
+	// Remove record of current user's favorites from file on disk.
+	void removeFavoritesRecordOfUser();
+
+	void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
+	void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
+
+	typedef std::map<LLUUID, S32> sort_index_map_t;
+	sort_index_map_t mSortIndexes;
+
+	typedef std::map<LLUUID, std::string> slurls_map_t;
+	slurls_map_t mSLURLs;
+
+	bool mIsDirty;
+
+	struct IsNotInFavorites
+	{
+		IsNotInFavorites(const LLInventoryModel::item_array_t& items)
+			: mFavoriteItems(items)
+		{
+
+		}
+
+		/**
+		 * Returns true if specified item is not found among inventory items
+		 */
+		bool operator()(const sort_index_map_t::value_type& id_index_pair) const
+		{
+			LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
+			if (item.isNull()) return true;
+
+			LLInventoryModel::item_array_t::const_iterator found_it =
+				std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
+
+			return found_it == mFavoriteItems.end();
+		}
+	private:
+		LLInventoryModel::item_array_t mFavoriteItems;
+	};
+
+};
 
 #endif // LL_LLFAVORITESBARCTRL_H
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 6bae1d5644..ee8c94a2dd 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -195,8 +195,10 @@ LLFolderView::LLFolderView(const Params& p)
 	mUseEllipses(p.use_ellipses),
 	mDraggingOverItem(NULL),
 	mStatusTextBox(NULL),
+	mShowItemLinkOverlays(p.show_item_link_overlays),
 	mViewModel(p.view_model)
 {
+	mViewModel->setFolderView(this);
 	mRoot = this;
 
 	LLRect rect = p.rect;
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 813b4d130f..8b58da9f45 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -96,7 +96,8 @@ public:
 		Optional<bool>			use_label_suffix,
 								allow_multiselect,
 								show_empty_message,
-								use_ellipses;
+								use_ellipses,
+								show_item_link_overlays;
 		Mandatory<LLFolderViewModelInterface*>	view_model;
 
 		Params();
@@ -239,6 +240,8 @@ public:
 	void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
 	void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
 
+	bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
+
 	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
 
 	BOOL getDebugFilters() { return mDebugFilters; }
@@ -294,6 +297,7 @@ protected:
 	BOOL							mAutoSelectOverride;
 	BOOL							mNeedsAutoRename;
 	bool							mUseLabelSuffix;
+	bool							mShowItemLinkOverlays;
 	
 	BOOL							mDebugFilters;
 	U32								mSortOrder;
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 5b73a34d29..3f0b493986 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -91,10 +91,7 @@ void LLFolderViewItem::cleanupClass()
 
 // NOTE: Optimize this, we call it a *lot* when opening a large inventory
 LLFolderViewItem::Params::Params()
-:	icon(),
-	icon_open(),
-	icon_overlay(),
-	root(),
+:	root(),
 	listener(),
 	folder_arrow_image("folder_arrow_image"),
 	folder_indentation("folder_indentation"),
@@ -125,12 +122,10 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mDragAndDropTarget(FALSE),
 	mLabel(p.name),
 	mRoot(p.root),
-	mIcon(p.icon),
-	mIconOpen(p.icon_open),
-	mIconOverlay(p.icon_overlay),
 	mListener(p.listener),
 	mIsMouseOverTitle(false)
 {
+	mListener->setFolderViewItem(this);
 }
 
 BOOL LLFolderViewItem::postBuild()
@@ -243,11 +238,6 @@ void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation)
 	mLastFilterGeneration = filter_generation;
 }
 
-void LLFolderViewItem::setIcon(LLUIImagePtr icon)
-{
-	mIcon = icon;
-}
-
 void LLFolderViewItem::refresh()
 {
 	if(!getViewModelItem()) return;
@@ -255,7 +245,10 @@ void LLFolderViewItem::refresh()
 	mLabel = getViewModelItem()->getDisplayName();
 
 	setToolTip(mLabel);
-	setIcon(getViewModelItem()->getIcon());
+	mIcon = getViewModelItem()->getIcon();
+	mIconOpen = getViewModelItem()->getIconOpen();
+	mIconOverlay = getViewModelItem()->getIconOverlay();
+
 	if (mRoot->useLabelSuffix())
 	{
 		mLabelStyle = getViewModelItem()->getLabelStyle();
@@ -907,27 +900,23 @@ void LLFolderViewItem::draw()
 		mDragAndDropTarget = FALSE;
 	}
 
-	//TODO RN: implement this in terms of getIcon() and getIconOverlay()
-
-	//const LLViewerInventoryItem *item = getInventoryItem();
-	//const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType();
-	////--------------------------------------------------------------------------------//
-	//// Draw open icon
-	////
-	//const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
-	//if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
- //	{
-	//	mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
-	//}
-	//else if (mIcon)
-	//{
- //		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
- //	}
+	//--------------------------------------------------------------------------------//
+	// Draw open icon
+	//
+	const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
+	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
+ 	{
+		mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
+	}
+	else if (mIcon)
+	{
+ 		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+ 	}
 
-	//if (highlight_link)
-	//{
-	//	mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
-	//}
+	if (mIconOverlay && getRoot()->showItemLinkOverlays())
+	{
+		mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+	}
 
 	//--------------------------------------------------------------------------------//
 	// Exit if no label to draw
@@ -1242,7 +1231,7 @@ BOOL LLFolderViewFolder::needsArrange()
 
 void LLFolderViewFolder::requestSort()
 {
-	getRoot()->getFolderViewModel()->requestSort(this);
+	getViewModelItem()->requestSort();
 }
 
 void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
@@ -2007,13 +1996,13 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 	addChild( folder );
 	folder->dirtyFilter();
 	// rearrange all descendants too, as our indentation level might have changed
-	folder->requestArrange(TRUE);
+	folder->requestArrange();
 	requestSort();
 
 	return TRUE;
 }
 
-void LLFolderViewFolder::requestArrange(BOOL include_descendants)	
+void LLFolderViewFolder::requestArrange()
 { 
 	mLastArrangeGeneration = -1; 
 	// flag all items up to root
@@ -2021,16 +2010,6 @@ void LLFolderViewFolder::requestArrange(BOOL include_descendants)
 	{
 		mParentFolder->requestArrange();
 	}
-
-	if (include_descendants)
-	{
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();
-			++iter)
-		{
-			(*iter)->requestArrange(TRUE);
-		}
-	}
 }
 
 void LLFolderViewFolder::toggleOpen()
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index feba32e31d..fd2948f34e 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -51,10 +51,7 @@ public:
 
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
 	{
-		Optional<LLUIImage*>						icon,
-													icon_open,     // used for folders
-													icon_overlay,  // for links
-													folder_arrow_image,
+		Optional<LLUIImage*>						folder_arrow_image,
 													selection_image;
 		Optional<LLFolderView*>						root;
 		Mandatory<LLFolderViewModelItem*>			listener;
@@ -252,9 +249,6 @@ public:
 	virtual BOOL	getFiltered(S32 filter_generation);
 	virtual void	setFiltered(BOOL filtered, S32 filter_generation);
 
-	// change the icon
-	void setIcon(LLUIImagePtr icon);
-
 	// refresh information from the object being viewed.
 	virtual void refresh();
 
@@ -416,8 +410,7 @@ public:
 	virtual void setOpen(BOOL openitem = TRUE);
 
 	// Called when a child is refreshed.
-	// don't rearrange child folder contents unless explicitly requested
-	virtual void requestArrange(BOOL include_descendants = FALSE);
+	virtual void requestArrange();
 
 	virtual void requestSort();
 
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 930c26384c..c3dcfed97c 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -120,18 +120,20 @@ class LLFolderViewModelInterface
 {
 public:
 	virtual void requestSortAll() = 0;
-	virtual void requestSort(class LLFolderViewFolder*) = 0;
 
 	virtual void sort(class LLFolderViewFolder*) = 0;
 	virtual void filter(class LLFolderViewFolder*) = 0;
 
 	virtual bool contentsReady() = 0;
+	virtual void setFolderView(LLFolderView* folder_view) = 0;
 };
 
-struct LLFolderViewModelCommon : public LLFolderViewModelInterface
+class LLFolderViewModelCommon : public LLFolderViewModelInterface
 {
+public:
 	LLFolderViewModelCommon()
-	:	mTargetSortVersion(0)
+	:	mTargetSortVersion(0),
+		mFolderView(NULL)
 	{}
 
 	virtual void requestSortAll()
@@ -140,15 +142,14 @@ struct LLFolderViewModelCommon : public LLFolderViewModelInterface
 		mTargetSortVersion++;
 	}
 
-	virtual void requestSort(class LLFolderViewFolder* folder)
-	{
-		folder->requestSort();
-	}
-	
+	void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
+
 protected:
 	bool needsSort(class LLFolderViewModelItem* item);
 
 	S32 mTargetSortVersion;
+	LLFolderView* mFolderView;
+
 };
 
 // This is am abstract base class that users of the folderview classes
@@ -156,6 +157,10 @@ protected:
 class LLFolderViewModelItem
 {
 public:
+	LLFolderViewModelItem()
+	:	mFolderViewItem(NULL)
+	{}
+
 	virtual ~LLFolderViewModelItem( void ) {};
 
 	virtual void update() {}	//called when drawing
@@ -163,7 +168,8 @@ public:
 	virtual const std::string& getDisplayName() const = 0;
 
 	virtual LLPointer<LLUIImage> getIcon() const = 0;
-	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
+	virtual LLPointer<LLUIImage> getIconOpen() const { return getIcon(); }
+	virtual LLPointer<LLUIImage> getIconOverlay() const { return NULL; }
 
 	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
 	virtual std::string getLabelSuffix() const = 0;
@@ -211,6 +217,11 @@ public:
 	virtual void requestSort() = 0;
 	virtual S32 getSortVersion() = 0;
 	virtual void setSortVersion(S32 version) = 0;
+protected:
+	friend LLFolderViewItem;
+	void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
+	LLFolderViewItem*	mFolderViewItem;
+
 };
 
 class LLFolderViewModelItemCommon : public LLFolderViewModelItem
@@ -225,6 +236,7 @@ public:
 	void setSortVersion(S32 version) { mSortVersion = version;}
 
 protected:
+
 	S32 mSortVersion;
 };
 
@@ -232,7 +244,7 @@ template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename
 class LLFolderViewModel : public LLFolderViewModelCommon
 {
 public:
-	LLFolderViewModel() {}
+	LLFolderViewModel(){}
 	virtual ~LLFolderViewModel() {}
 	
 	typedef SORT_TYPE		SortType;
@@ -247,6 +259,8 @@ public:
 	virtual const FilterType& getFilter() const		 { return mFilter; }
 	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
 
+	// TODO RN: remove this and put all filtering logic in view model
+	// add getStatusText and isFiltering()
 	virtual bool contentsReady()					{ return true; }
 
 	struct ViewModelCompare
@@ -301,8 +315,8 @@ public:
 	}
 
 protected:
-	SortType	mSorter;
-	FilterType	mFilter;
+	SortType		mSorter;
+	FilterType		mFilter;
 };
 
 #endif
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 44d0fdd3dd..c0670b71d4 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -37,6 +37,7 @@
 #include "llappearancemgr.h"
 #include "llattachmentsmgr.h"
 #include "llavataractions.h" 
+#include "llfavoritesbar.h" // management of favorites folder
 #include "llfloateropenobject.h"
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
@@ -1846,7 +1847,11 @@ void LLFolderBridge::buildDisplayName() const
 	if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
 	{
 		LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
-	};
+	}
+	else
+	{
+		mDisplayName.assign(getName());
+	}
 }
 
 
@@ -2993,17 +2998,24 @@ LLUIImagePtr LLFolderBridge::getIcon() const
 LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)
 {
 	return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE));
-		/*case LLAssetType::AT_MESH:
-			control = "inv_folder_mesh.tga";
-			break;*/
 }
 
-LLUIImagePtr LLFolderBridge::getOpenIcon() const
+LLUIImagePtr LLFolderBridge::getIconOpen() const
 {
 	return LLUI::getUIImage(LLViewerFolderType::lookupIconName(getPreferredType(), TRUE));
 
 }
 
+LLUIImagePtr LLFolderBridge::getIconOverlay() const
+{
+	if (getInventoryObject() && getInventoryObject()->getIsLinkType())
+	{
+		return LLUI::getUIImage("Inv_Link");
+	}
+	return NULL;
+}
+
+
 BOOL LLFolderBridge::renameItem(const std::string& new_name)
 {
 	rename_category(getInventoryModel(), mUUID, new_name);
@@ -4017,7 +4029,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 				{
 					LLUUID srcItemId = inv_item->getUUID();
 					LLUUID destItemId = static_cast<LLFolderViewModelItemInventory*>(itemp->getViewModelItem())->getUUID();
-					gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId);
+					LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(srcItemId, destItemId);
 				}
 			}
 
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 111735e198..26789627f7 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -260,7 +260,9 @@ public:
 
 	virtual LLFolderType::EType getPreferredType() const;
 	virtual LLUIImagePtr getIcon() const;
-	virtual LLUIImagePtr getOpenIcon() const;
+	virtual LLUIImagePtr getIconOpen() const;
+	virtual LLUIImagePtr getIconOverlay() const;
+
 	static LLUIImagePtr getIcon(LLFolderType::EType preferred_type);
 
 	virtual BOOL renameItem(const std::string& new_name);
@@ -338,8 +340,7 @@ private:
 	bool							mWearables;
 	bool							mIsLoading;
 	LLTimer							mTimeSinceRequestStart;
-	mutable std::string				mDisplayName;
-	LLRootHandle<LLFolderBridge> mHandle;
+	LLRootHandle<LLFolderBridge>	mHandle;
 };
 
 class LLTextureBridge : public LLItemBridge
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 85ecb133d0..9b0d12b353 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -3201,68 +3201,7 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c
 	}
 }
 
-//* @param[in] items vector of items in order to be saved.
-void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items)
-{
-	int sortField = 0;
-
-	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
-	for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
-	{
-		LLViewerInventoryItem* item = *i;
-
-		item->setSortField(++sortField);
-		item->setComplete(TRUE);
-		item->updateServer(FALSE);
-
-		updateItem(item);
-
-		// Tell the parent folder to refresh its sort order.
-		addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
-	}
-
-	notifyObservers();
-}
-
-// See also LLInventorySort where landmarks in the Favorites folder are sorted.
-class LLViewerInventoryItemSort
-{
-public:
-	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
-	{
-		return a->getSortField() < b->getSortField();
-	}
-};
 
-/**
- * Sorts passed items by LLViewerInventoryItem sort field.
- *
- * @param[in, out] items - array of items, not sorted.
- */
-static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
-{
-	static LLViewerInventoryItemSort sort_functor;
-	std::sort(items.begin(), items.end(), sort_functor);
-}
-
-// * @param source_item_id - LLUUID of the source item to be moved into new position
-// * @param target_item_id - LLUUID of the target item before which source item should be placed.
-void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
-{
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	LLIsType is_type(LLAssetType::AT_LANDMARK);
-	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-	gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
-
-	// ensure items are sorted properly before changing order. EXT-3498
-	rearrange_item_order_by_sort_field(items);
-
-	// update order
-	updateItemsOrder(items, source_item_id, target_item_id);
-
-	saveItemsOrder(items);
-}
 
 //----------------------------------------------------------------------------
 
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8382e875b4..3613bc4917 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -362,15 +362,6 @@ public:
 	// Returns end() of the vector if not found.
 	static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
 
-	// Saves current order of the passed items using inventory item sort field.
-	// Resets 'items' sort fields and saves them on server.
-	// Is used to save order for Favorites folder.
-	void saveItemsOrder(const LLInventoryModel::item_array_t& items);
-
-	// Rearranges Landmarks inside Favorites folder.
-	// Moves source landmark before target one.
-	void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
-
 	//--------------------------------------------------------------------
 	// Creation
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index d576160277..74492e0005 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -59,17 +59,6 @@ static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
 //
 // class LLFolderViewModelInventory
 //
-void LLFolderViewModelInventory::requestSort(class LLFolderViewFolder* folder)
-{
-	base_t::requestSort(folder);
-	if (getSorter().isByDate())
-	{
-		// sort by date potentially affects parent folders which use a date
-		// derived from newest item in them
-		requestSort(folder->getParentFolder());
-	}
-}
-
 static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort");
 
 void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
@@ -690,6 +679,7 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
 	p.use_label_suffix = useLabelSuffix;
 	p.allow_multiselect = mAllowMultiSelect;
 	p.show_empty_message = mShowEmptyMessage;
+	p.show_item_link_overlays = mShowItemLinkOverlays;
 
 	return LLUICtrlFactory::create<LLFolderView>(p);
 }
@@ -699,14 +689,6 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
 	LLFolderViewFolder::Params params;
 
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-	
 	params.root = mFolderRoot;
 	params.listener = bridge;
 	params.tool_tip = params.name;
@@ -719,14 +701,6 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
 	LLFolderViewItem::Params params;
 	
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-
 	params.creation_date = bridge->getCreationDate();
 	params.root = mFolderRoot;
 	params.listener = bridge;
@@ -743,7 +717,9 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 	if (!objectp) return NULL;
 
 	LLFolderViewItem* folder_view_item = getItemByID(id);
-	LLFolderViewFolder* parent_folder = folder_view_item->getParentFolder();
+
+	const LLUUID &parent_id = objectp->getParentUUID();
+	LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
 	 
  	if (!folder_view_item && parent_folder)
   	{
@@ -1370,3 +1346,15 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
 	mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
 }
 
+
+void LLFolderViewModelItemInventory::requestSort()
+{
+	LLFolderViewModelItemCommon::requestSort();
+	//TODO RN: need better way to get to root viewmodel, also consider reflecting hierarchy in viewmodel space as well
+	if (static_cast<LLFolderViewModelInventory*>(mFolderViewItem->getRoot()->getFolderViewModel())->getSorter().isByDate())
+	{
+		// sort by date potentially affects parent folders which use a date
+		// derived from newest item in them
+		mFolderViewItem->getParentFolder()->getViewModelItem()->requestSort();
+	}
+}
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 2aa05e1b61..645e2f6d76 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -61,6 +61,7 @@ public:
 	virtual LLWearableType::EType getWearableType() const = 0;
 	virtual EInventorySortGroup getSortGroup() const = 0;
 	virtual LLInventoryObject* getInventoryObject() const = 0;
+	virtual void requestSort();
 };
 
 class LLInventorySort
@@ -97,7 +98,6 @@ public:
 	virtual ~LLFolderViewModelInventory() {}
 
 	void sort(LLFolderViewFolder* folder);
-	void requestSort(LLFolderViewFolder* folder);
 
 	bool contentsReady();
 
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index d2143783ad..f3096e862d 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -122,14 +122,6 @@ LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge
 	LLInboxFolderViewFolder::Params params;
 	
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-	
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-	
 	params.root = mFolderRoot;
 	params.listener = bridge;
 	params.tool_tip = params.name;
@@ -142,14 +134,6 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
 	LLInboxFolderViewItem::Params params;
 
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-
 	params.creation_date = bridge->getCreationDate();
 	params.root = mFolderRoot;
 	params.listener = bridge;
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
index 7db01d9059..783eeb11b8 100644
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
@@ -88,14 +88,6 @@ LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridg
 	LLOutboxFolderViewFolder::Params params;
 	
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-	
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-	
 	params.root = mFolderRoot;
 	params.listener = bridge;
 	params.tool_tip = params.name;
@@ -108,14 +100,6 @@ LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge *
 	LLFolderViewItem::Params params;
 
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-
 	params.creation_date = bridge->getCreationDate();
 	params.root = mFolderRoot;
 	params.listener = bridge;
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 0ba8c1ce6d..da82d70f22 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1551,6 +1551,7 @@ void LLPanelObjectInventory::reset()
 	p.tool_tip= LLTrans::getString("PanelContentsTooltip");
 	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
 	p.folder_indentation = -14; // subtract space normally reserved for folder expanders
+	p.view_model = new LLFolderViewModelInventory();
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
 	//TODO RN: make this happen by manipulating filter object directly
@@ -1693,18 +1694,6 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
 	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
 	if(bridge)
 	{
-		//LLFolderViewFolder* new_folder = NULL;
-		//LLFolderViewFolder::Params p;
-		//p.name = inventory_root->getName();
-		//p.icon = LLUI::getUIImage("Inv_FolderClosed");
-		//p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
-		//p.root = mFolders;
-		//p.listener = bridge;
-		//p.tool_tip = p.name;
-		//new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
-		//new_folder->addToFolder(mFolders, mFolders);
-		//new_folder->toggleOpen();
-
 		createViewsForCategory(&contents, inventory_root, mFolders);
 	}
 }
@@ -1737,8 +1726,6 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 			{
 				LLFolderViewFolder::Params p;
 				p.name = obj->getName();
-				p.icon = LLUI::getUIImage("Inv_FolderClosed");
-				p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
 				p.root = mFolders;
 				p.listener = bridge;
 				p.tool_tip = p.name;
@@ -1750,7 +1737,6 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 			{
 				LLFolderViewItem::Params params;
 				params.name(obj->getName());
-				params.icon(bridge->getIcon());
 				params.creation_date(bridge->getCreationDate());
 				params.root(mFolders);
 				params.listener(bridge);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 749a6d22e0..d81b016fc1 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1030,12 +1030,7 @@ void CreateGestureCallback::fire(const LLUUID& inv_item)
 	gFloaterView->adjustToFitScreen(preview, FALSE);
 }
 
-void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
-{
-	if (mTargetLandmarkId.isNull()) return;
 
-	gInventory.rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
-}
 
 LLInventoryCallbackManager gInventoryCallbacks;
 
@@ -1449,342 +1444,6 @@ const std::string& LLViewerInventoryItem::getName() const
 	return  LLInventoryItem::getName();
 }
 
-/**
- * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
- * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
- * Data are stored in user home directory.
- */
-class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
-	, public LLDestroyClass<LLFavoritesOrderStorage>
-{
-	LOG_CLASS(LLFavoritesOrderStorage);
-public:
-	/**
-	 * Sets sort index for specified with LLUUID favorite landmark
-	 */
-	void setSortIndex(const LLUUID& inv_item_id, S32 sort_index);
-
-	/**
-	 * Gets sort index for specified with LLUUID favorite landmark
-	 */
-	S32 getSortIndex(const LLUUID& inv_item_id);
-	void removeSortIndex(const LLUUID& inv_item_id);
-
-	void getSLURL(const LLUUID& asset_id);
-
-	/**
-	 * Implementation of LLDestroyClass. Calls cleanup() instance method.
-	 *
-	 * It is important this callback is called before gInventory is cleaned.
-	 * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
-	 * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
-	 * @see cleanup()
-	 */
-	static void destroyClass();
-
-	const static S32 NO_INDEX;
-private:
-	friend class LLSingleton<LLFavoritesOrderStorage>;
-	LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
-	~LLFavoritesOrderStorage() { save(); }
-
-	/**
-	 * Removes sort indexes for items which are not in Favorites bar for now.
-	 */
-	void cleanup();
-
-	const static std::string SORTING_DATA_FILE_NAME;
-
-	void load();
-	void save();
-
-	void saveFavoritesSLURLs();
-
-	// Remove record of current user's favorites from file on disk.
-	void removeFavoritesRecordOfUser();
-
-	void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark);
-	void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
-
-	typedef std::map<LLUUID, S32> sort_index_map_t;
-	sort_index_map_t mSortIndexes;
-
-	typedef std::map<LLUUID, std::string> slurls_map_t;
-	slurls_map_t mSLURLs;
-
-	bool mIsDirty;
-
-	struct IsNotInFavorites
-	{
-		IsNotInFavorites(const LLInventoryModel::item_array_t& items)
-			: mFavoriteItems(items)
-		{
-
-		}
-
-		/**
-		 * Returns true if specified item is not found among inventory items
-		 */
-		bool operator()(const sort_index_map_t::value_type& id_index_pair) const
-		{
-			LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
-			if (item.isNull()) return true;
-
-			LLInventoryModel::item_array_t::const_iterator found_it =
-				std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
-
-			return found_it == mFavoriteItems.end();
-		}
-	private:
-		LLInventoryModel::item_array_t mFavoriteItems;
-	};
-
-};
-
-const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
-const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
-
-void LLFavoritesOrderStorage::setSortIndex(const LLUUID& inv_item_id, S32 sort_index)
-{
-	mSortIndexes[inv_item_id] = sort_index;
-	mIsDirty = true;
-}
-
-S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
-{
-	sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
-	if (it != mSortIndexes.end())
-	{
-		return it->second;
-	}
-	return NO_INDEX;
-}
-
-void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
-{
-	mSortIndexes.erase(inv_item_id);
-	mIsDirty = true;
-}
-
-void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
-{
-	slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
-	if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
-
-	LLLandmark* lm = gLandmarkList.getAsset(asset_id,
-			boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
-	if (lm)
-	{
-		onLandmarkLoaded(asset_id, lm);
-	}
-}
-
-// static
-void LLFavoritesOrderStorage::destroyClass()
-{
-	LLFavoritesOrderStorage::instance().cleanup();
-	if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
-	{
-		LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
-	}
-	else
-	{
-		LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
-	}
-}
-
-void LLFavoritesOrderStorage::load()
-{
-	// load per-resident sorting information
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
-
-	LLSD settings_llsd;
-	llifstream file;
-	file.open(filename);
-	if (file.is_open())
-	{
-		LLSDSerialize::fromXML(settings_llsd, file);
-	}
-
-	for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
-		iter != settings_llsd.endMap(); ++iter)
-	{
-		mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
-	}
-}
-
-void LLFavoritesOrderStorage::saveFavoritesSLURLs()
-{
-	// Do not change the file if we are not logged in yet.
-	if (!LLLoginInstance::getInstance()->authSuccess())
-	{
-		llwarns << "Cannot save favorites: not logged in" << llendl;
-		return;
-	}
-	
-	std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
-	if (user_dir.empty())
-	{
-		llwarns << "Cannot save favorites: empty user dir name" << llendl;
-		return;
-	}
-
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
-	llifstream in_file;
-	in_file.open(filename);
-	LLSD fav_llsd;
-	if (in_file.is_open())
-	{
-		LLSDSerialize::fromXML(fav_llsd, in_file);
-	}
-
-	const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
-	LLSD user_llsd;
-	for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
-	{
-		LLSD value;
-		value["name"] = (*it)->getName();
-		value["asset_id"] = (*it)->getAssetUUID();
-
-		slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
-		if (slurl_iter != mSLURLs.end())
-		{
-			lldebugs << "Saving favorite: idx=" << (*it)->getSortField() << ", SLURL=" <<  slurl_iter->second << ", value=" << value << llendl;
-			value["slurl"] = slurl_iter->second;
-			user_llsd[(*it)->getSortField()] = value;
-		}
-		else
-		{
-			llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl;
-		}
-	}
-
-	LLAvatarName av_name;
-	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Saved favorites for " << av_name.getLegacyName() << llendl;
-	fav_llsd[av_name.getLegacyName()] = user_llsd;
-
-	llofstream file;
-	file.open(filename);
-	LLSDSerialize::toPrettyXML(fav_llsd, file);
-}
-
-void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
-{
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
-	LLSD fav_llsd;
-	llifstream file;
-	file.open(filename);
-	if (!file.is_open()) return;
-	LLSDSerialize::fromXML(fav_llsd, file);
-
-	LLAvatarName av_name;
-	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Removed favorites for " << av_name.getLegacyName() << llendl;
-	if (fav_llsd.has(av_name.getLegacyName()))
-	{
-		fav_llsd.erase(av_name.getLegacyName());
-	}
-
-	llofstream out_file;
-	out_file.open(filename);
-	LLSDSerialize::toPrettyXML(fav_llsd, out_file);
-
-}
-
-void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
-{
-	if (!landmark) return;
-
-	LLVector3d pos_global;
-	if (!landmark->getGlobalPos(pos_global))
-	{
-		// If global position was unknown on first getGlobalPos() call
-		// it should be set for the subsequent calls.
-		landmark->getGlobalPos(pos_global);
-	}
-
-	if (!pos_global.isExactlyZero())
-	{
-		LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
-				boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
-	}
-}
-
-void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
-{
-	lldebugs << "Saving landmark SLURL: " << slurl << llendl;
-	mSLURLs[asset_id] = slurl;
-}
-
-void LLFavoritesOrderStorage::save()
-{
-	// nothing to save if clean
-	if (!mIsDirty) return;
-
-	// If we quit from the login screen we will not have an SL account
-	// name.  Don't try to save, otherwise we'll dump a file in
-	// C:\Program Files\SecondLife\ or similar. JC
-	std::string user_dir = gDirUtilp->getLindenUserDir();
-	if (!user_dir.empty())
-	{
-		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
-		LLSD settings_llsd;
-
-		for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
-		{
-			settings_llsd[iter->first.asString()] = iter->second;
-		}
-
-		llofstream file;
-		file.open(filename);
-		LLSDSerialize::toPrettyXML(settings_llsd, file);
-	}
-}
-
-void LLFavoritesOrderStorage::cleanup()
-{
-	// nothing to clean
-	if (!mIsDirty) return;
-
-	const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
-	IsNotInFavorites is_not_in_fav(items);
-
-	sort_index_map_t  aTempMap;
-	//copy unremoved values from mSortIndexes to aTempMap
-	std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(), 
-		inserter(aTempMap, aTempMap.begin()),
-		is_not_in_fav);
-
-	//Swap the contents of mSortIndexes and aTempMap
-	mSortIndexes.swap(aTempMap);
-}
-
-
-S32 LLViewerInventoryItem::getSortField() const
-{
-	return LLFavoritesOrderStorage::instance().getSortIndex(mUUID);
-}
-
-void LLViewerInventoryItem::setSortField(S32 sortField)
-{
-	LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
-	getSLURL();
-}
-
-void LLViewerInventoryItem::getSLURL()
-{
-	LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID);
-}
-
 const LLUUID& LLViewerInventoryItem::getCreatorUUID() const
 {
 	if (const LLViewerInventoryItem *linked_item = getLinkedItem())
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index d66362d544..3cf03c3bc5 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -60,9 +60,6 @@ public:
 	virtual const LLUUID& getAssetUUID() const;
 	virtual const LLUUID& getProtectedAssetUUID() const; // returns LLUUID::null if current agent does not have permission to expose this asset's UUID to the user
 	virtual const std::string& getName() const;
-	virtual S32 getSortField() const;
-	virtual void setSortField(S32 sortField);
-	virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here.
 	virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied
 	virtual const LLUUID& getCreatorUUID() const;
 	virtual const std::string& getDescription() const;
@@ -72,7 +69,7 @@ public:
 	virtual LLWearableType::EType getWearableType() const;
 	virtual U32 getFlags() const;
 
-        using LLInventoryItem::getPermissions;
+    using LLInventoryItem::getPermissions;
 	using LLInventoryItem::getCreationDate;
 	using LLInventoryItem::setCreationDate;
 	using LLInventoryItem::getCRC32;
@@ -287,18 +284,6 @@ public:
 	void fire(const LLUUID& inv_item);
 };
 
-class AddFavoriteLandmarkCallback : public LLInventoryCallback
-{
-public:
-	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
-	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
-
-private:
-	void fire(const LLUUID& inv_item);
-
-	LLUUID mTargetLandmarkId;
-};
-
 // misc functions
 //void inventory_reliable_callback(void**, S32 status);
 
-- 
cgit v1.2.3


From d866328f6a9e6537eb8a9775acf4f403b7ad6af6 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 22 Jun 2012 16:11:25 +0300
Subject: CHUI-100 Fix floater's key

---
 indra/newview/llimview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 4b82596f37..79018ec366 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2611,7 +2611,7 @@ LLUUID LLIMMgr::addSession(
 
 	if (floater_id.notNull())
 	{
-		LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+		LLIMFloater* im_floater = LLIMFloater::findInstance(floater_id);
 
 		if (im_floater && im_floater->getStartConferenceInSameFloater())
 		{
-- 
cgit v1.2.3


From 6bb554fc3661d3b8b1284db96bb7c7b0934df621 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 22 Jun 2012 16:54:42 +0300
Subject: CHUI-160 FIXED (Text entered in local chat text field scrolls up and
 becomes only partially visible after hitting return)

- Replaced LLLineEditor with LLChatEntry in nearby chat
- Moved reshape method from LLIMFloater to the base LLIMConversation so that vertical reshaping work properly for both LLNearbyChat and LLIMFloater
---
 indra/newview/llimconversation.cpp | 22 ++++++++++++++++++++++
 indra/newview/llimconversation.h   | 14 ++++++++++++++
 indra/newview/llimfloater.cpp      | 15 ---------------
 indra/newview/llimfloater.h        |  9 ---------
 indra/newview/llnearbychat.cpp     | 25 ++++++++++---------------
 indra/newview/llnearbychat.h       |  6 +++---
 indra/newview/llviewerwindow.cpp   |  5 +++--
 7 files changed, 52 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index f12821352b..bbbc9fcffd 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -29,6 +29,8 @@
 
 #include "llimconversation.h"
 
+#include "llchatentry.h"
+#include "llchathistory.h"
 #include "lldraghandle.h"
 #include "llfloaterreg.h"
 #include "llimfloater.h"
@@ -47,6 +49,9 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)
   ,  mCloseBtn(NULL)
   ,  mSessionID(session_id)
   , mParticipantList(NULL)
+  , mChatHistory(NULL)
+  , mInputEditor(NULL)
+  , mInputEditorTopPad(0)
 {
 	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
 			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2));
@@ -86,6 +91,12 @@ BOOL LLIMConversation::postBuild()
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
 
+	mChatHistory = getChild<LLChatHistory>("chat_history");
+	mInputEditor = getChild<LLChatEntry>("chat_editor");
+
+	mInputEditor->setTextExpandedCallback(boost::bind(&LLIMConversation::reshapeChatHistory, this));
+	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
+
 	if (!getTornOff())
 	{
 		setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
@@ -242,6 +253,17 @@ void LLIMConversation::updateHeaderAndToolbar()
 	showTranslationCheckbox();
 }
 
+void LLIMConversation::reshapeChatHistory()
+{
+	LLRect chat_rect  = mChatHistory->getRect();
+	LLRect input_rect = mInputEditor->getRect();
+
+	int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad);
+
+	chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height);
+	mChatHistory->setShape(chat_rect);
+}
+
 void LLIMConversation::showTranslationCheckbox(BOOL show)
 {
 	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE);
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 66401b9a3c..f4b8a38242 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -35,6 +35,8 @@
 #include "lleventtimer.h"
 
 class LLPanelChatControlPanel;
+class LLChatEntry;
+class LLChatHistory;
 
 class LLIMConversation
 	: public LLTransientDockableFloater
@@ -102,6 +104,18 @@ protected:
 private:
 	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
 	void updateHeaderAndToolbar();
+
+	/**
+	 * Adjusts chat history height to fit vertically with input chat field
+	 * and avoid overlapping, since input chat field can be vertically expanded.
+	 * Implementation: chat history bottom "follows" top+top_pad of input chat field
+	 */
+	void reshapeChatHistory();
+
+
+	LLChatHistory* mChatHistory;
+	LLChatEntry* mInputEditor;
+	int mInputEditorTopPad; // padding between input field and chat history
 };
 
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 4b954de738..98ebc82f99 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -64,7 +64,6 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
 	mInputEditor(NULL),
-	mInputEditorTopPad(0),
 	mSavedTitle(),
 	mTypingStart(),
 	mShouldSendTypingState(false),
@@ -314,12 +313,9 @@ BOOL LLIMFloater::postBuild()
 	mInputEditor->setPassDelete( TRUE );
 
 	mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this));
-	mInputEditor->setTextExpandedCallback(boost::bind(&LLIMFloater::reshapeChatHistory, this));
 	
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
-	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
-
 	setDocked(true);
 
 	mTypingStart = LLTrans::getString("IM_typing_start_string");
@@ -1171,17 +1167,6 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 	}
 }
 
-void LLIMFloater::reshapeChatHistory()
-{
-	LLRect chat_rect  = mChatHistory->getRect();
-	LLRect input_rect = mInputEditor->getRect();
-
-	int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad);
-
-	chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height);
-	mChatHistory->setShape(chat_rect);
-}
-
 // static
 void LLIMFloater::closeHiddenIMToasts()
 {
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 1992bd930c..6847efedf1 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -163,13 +163,6 @@ private:
 	// Remove the "User is typing..." indicator.
 	void removeTypingIndicator(const LLIMInfo* im_info = NULL);
 
-	/**
-	 * Adjusts chat history height to fit vertically with input chat field
-	 * and avoid overlapping, since input chat field can be vertically expanded.
-	 * Implementation: chat history bottom "follows" top+top_pad of input chat field
-	 */
-	void reshapeChatHistory();
-
 	static void closeHiddenIMToasts();
 
 	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
@@ -180,8 +173,6 @@ private:
 
 	LLChatHistory* mChatHistory;
 
-	int mInputEditorTopPad; // padding between input field and chat history
-
 	EInstantMessage mDialog;
 	LLUUID mOtherParticipantUUID;
 	LLChatEntry* mInputEditor;
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 1b2d9b6801..29ab4384cb 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -30,6 +30,7 @@
 
 #include "lliconctrl.h"
 #include "llappviewer.h"
+#include "llchatentry.h"
 #include "llfloaterreg.h"
 #include "lltrans.h"
 #include "llimfloatercontainer.h"
@@ -138,19 +139,14 @@ LLNearbyChat::LLNearbyChat(const LLSD& key)
 //virtual
 BOOL LLNearbyChat::postBuild()
 {
-	mChatBox = getChild<LLLineEditor>("chat_editor");
+	mChatBox = getChild<LLChatEntry>("chat_editor");
 
 	mChatBox->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this));
-	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
+	mChatBox->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
 	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
 	mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this));
-	mChatBox->setIgnoreArrowKeys( FALSE ); 
 	mChatBox->setCommitOnFocusLost( FALSE );
-	mChatBox->setRevertOnEsc( FALSE );
-	mChatBox->setIgnoreTab(TRUE);
 	mChatBox->setPassDelete(TRUE);
-	mChatBox->setReplaceNewlinesWithSpaces(FALSE);
-	mChatBox->setEnableLineHistory(TRUE);
 	mChatBox->setFont(LLViewerChat::getChatFont());
 
 //	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
@@ -459,7 +455,7 @@ BOOL LLNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string*
 	return string_was_found;
 }
 
-void LLNearbyChat::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
+void LLNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata)
 {
 	LLFirstUse::otherAvatarChatFirst(false);
 
@@ -513,17 +509,16 @@ void LLNearbyChat::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
 		{
 			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
 			self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
-			S32 outlength = self->mChatBox->getLength(); // in characters
 
 			// Select to end of line, starting from the character
 			// after the last one the user typed.
-			self->mChatBox->setSelection(length, outlength);
+			self->mChatBox->selectNext(rest_of_match, false);
 		}
 		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
 		{
 			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
 			self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
-			self->mChatBox->setCursorToEnd();
+			self->mChatBox->endOfDoc();
 		}
 
 		//llinfos << "GESTUREDEBUG " << trigger 
@@ -581,11 +576,11 @@ void LLNearbyChat::sendChat( EChatType type )
 {
 	if (mChatBox)
 	{
-		LLWString text = mChatBox->getConvertedText();
+		LLWString text = mChatBox->getWText();
+		LLWStringUtil::trim(text);
+		LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
 		if (!text.empty())
 		{
-			// store sent line in history, duplicates will get filtered
-			mChatBox->updateHistory();
 			// Check if this is destined for another channel
 			S32 channel = 0;
 			stripChannelNumber(text, &channel);
@@ -794,7 +789,7 @@ void LLNearbyChat::startChat(const char* line)
 			cb->mChatBox->setText(line_string);
 		}
 
-		cb->mChatBox->setCursorToEnd();
+		cb->mChatBox->endOfDoc();
 	}
 }
 
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 3dc94ce0da..c9aa69a912 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -71,7 +71,7 @@ public:
 	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);
 	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
 
-	LLLineEditor* getChatBox() { return mChatBox; }
+	LLChatEntry* getChatBox() { return mChatBox; }
 
 	//virtual void draw();
 
@@ -90,7 +90,7 @@ public:
 
 protected:
 	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
-	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
+	static void onChatBoxKeystroke(LLTextEditor* caller, void* userdata);
 	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
 	void onChatBoxFocusReceived();
 
@@ -113,7 +113,7 @@ protected:
 	// Which non-zero channel did we last chat on?
 	static S32 sLastSpecialChatChannel;
 
-	LLLineEditor*			mChatBox;
+	LLChatEntry*			mChatBox;
 	LLOutputMonitorCtrl*	mOutputMonitor;
 	LLLocalSpeakerMgr*		mSpeakerMgr;
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 016da1d994..258bc5b698 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -56,6 +56,7 @@
 
 // linden library includes
 #include "llaudioengine.h"		// mute on minimize
+#include "llchatentry.h"
 #include "indra_constants.h"
 #include "llassetstorage.h"
 #include "llerrorcontrol.h"
@@ -2492,7 +2493,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 
 		if (nearby_chat)
 		{
-			LLLineEditor* chat_editor = nearby_chat->getChatBox();
+			LLChatEntry* chat_editor = nearby_chat->getChatBox();
 		
 		// arrow keys move avatar while chatting hack
 		if (chat_editor && chat_editor->hasFocus())
@@ -2555,7 +2556,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
-		LLLineEditor* chat_editor = LLNearbyChat::getInstance()->getChatBox();
+		LLChatEntry* chat_editor = LLNearbyChat::getInstance()->getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
-- 
cgit v1.2.3


From 91be3bf3019581b74a3515c1081aef883c0658fa Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 22 Jun 2012 16:56:33 +0300
Subject: CHUI-161 FIXED (Text entered in local chat is not visible to other
 users nearby)

- Applied Merov's fix.
The problem was that text_editor was registered twice and, depending of the machine you ran, the viewer would pick one or the other.
Mac users were unlucky enough to pick the wrong one all the time.
---
 indra/llui/llchatentry.cpp                                | 2 +-
 indra/newview/skins/default/xui/en/floater_im_session.xml | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index 1da7900f59..dea8ff9bb2 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -28,7 +28,7 @@
 
 #include "llchatentry.h"
 
-static LLDefaultChildRegistry::Register<LLChatEntry> r("text_editor");
+static LLDefaultChildRegistry::Register<LLChatEntry> r("chat_editor");
 
 LLChatEntry::Params::Params()
 :	has_history("has_history", true),
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index f6d5b20a65..0720a4b011 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -242,7 +242,7 @@
              bottom="-1" 
              follows="left|right|bottom" 
              tab_group="1">    
-            	<text_editor
+            	<chat_editor
              		bottom="0"
              		expand_lines_count="5"
              		follows="left|right|bottom"
@@ -256,7 +256,7 @@
              		tab_group="3"
              		width="240"
              		wrap="true">
-            	</text_editor>
+            	</chat_editor>
               </panel>
     </layout_panel>
   </layout_stack>
-- 
cgit v1.2.3


From 47c140b81d868229187f85185e4721946430ad87 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 22 Jun 2012 17:04:47 +0300
Subject: CHUI-127 ADDITIONAL FIX (Make chat field auto resizable)

- Fixed crash which occurred while navigating through history of sent messages
---
 indra/llui/llchatentry.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index dea8ff9bb2..a6ba125406 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -170,13 +170,14 @@ BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
 	case KEY_DOWN:
 		if (mHasHistory && MASK_CONTROL == mask)
 		{
-			if (!mLineHistory.empty() && ++mCurrentHistoryLine < mLineHistory.end())
+			if (!mLineHistory.empty() && mCurrentHistoryLine < (mLineHistory.end() - 1) )
 			{
-				setText(*mCurrentHistoryLine);
+				setText(*(++mCurrentHistoryLine));
 				endOfDoc();
 			}
-			else if (!mLineHistory.empty() && mCurrentHistoryLine == mLineHistory.end())
+			else if (!mLineHistory.empty() && mCurrentHistoryLine == (mLineHistory.end() - 1) )
 			{
+				mCurrentHistoryLine++;
 				std::string empty("");
 				setText(empty);
 				needsReflow();
-- 
cgit v1.2.3


From 3807f97facc79960c579793376412a0baf6b9de3 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 22 Jun 2012 18:13:34 +0300
Subject: CHUI-136 FIXED (Implement new design for blocked list on the people
 floater)

- Created new LLBlockList class and replaced LLScrollContainer with it
- Also created new LLBlockedListItem class which represents blocked objects and blocked avatars
---
 indra/newview/CMakeLists.txt                       |   4 +
 indra/newview/app_settings/settings.xml            |  11 +
 indra/newview/llblockedlistitem.cpp                | 105 ++++++++
 indra/newview/llblockedlistitem.h                  |  73 ++++++
 indra/newview/llblocklist.cpp                      | 273 +++++++++++++++++++++
 indra/newview/llblocklist.h                        | 138 +++++++++++
 indra/newview/llgrouplist.h                        |   4 +
 indra/newview/llpanelblockedlist.cpp               | 134 ++++++----
 indra/newview/llpanelblockedlist.h                 |  35 +--
 .../default/xui/en/menu_people_blocked_gear.xml    |  26 ++
 .../default/xui/en/menu_people_blocked_plus.xml    |  20 ++
 .../default/xui/en/menu_people_blocked_view.xml    |  26 ++
 .../default/xui/en/panel_block_list_sidetray.xml   | 160 ++++++------
 .../default/xui/en/panel_blocked_list_item.xml     |  62 +++++
 .../newview/skins/default/xui/en/panel_people.xml  |   1 +
 15 files changed, 928 insertions(+), 144 deletions(-)
 create mode 100644 indra/newview/llblockedlistitem.cpp
 create mode 100644 indra/newview/llblockedlistitem.h
 create mode 100644 indra/newview/llblocklist.cpp
 create mode 100644 indra/newview/llblocklist.h
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_people_blocked_view.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_blocked_list_item.xml

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 785bf4b868..e67089c4de 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -103,6 +103,8 @@ set(viewer_SOURCE_FILES
     llavatarlist.cpp
     llavatarlistitem.cpp
     llavatarpropertiesprocessor.cpp
+    llblockedlistitem.cpp
+    llblocklist.cpp
     llbox.cpp
     llbreadcrumbview.cpp
     llbrowsernotification.cpp
@@ -659,6 +661,8 @@ set(viewer_HEADER_FILES
     llavatarlist.h
     llavatarlistitem.h
     llavatarpropertiesprocessor.h
+    llblockedlistitem.h
+    llblocklist.h
     llbox.h
     llbreadcrumbview.h
     llbuycurrencyhtml.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index feb80a3611..fe6829a712 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9982,6 +9982,17 @@
       <key>Value</key>
       <integer>2</integer>
     </map>
+    <key>BlockPeopleSortOrder</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies sort order for recent people (0 = by name, 1 = by type)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>2</integer>
+    </map>
     <key>ShowPGSearchAll</key>    
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llblockedlistitem.cpp b/indra/newview/llblockedlistitem.cpp
new file mode 100644
index 0000000000..14da35c85a
--- /dev/null
+++ b/indra/newview/llblockedlistitem.cpp
@@ -0,0 +1,105 @@
+/**
+ * @file llviewerobjectlistitem.cpp
+ * @brief viewer object list item implementation
+ *
+ * Class LLPanelInventoryListItemBase displays inventory item as an element
+ * of LLInventoryItemsList.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llblockedlistitem.h"
+
+// llui
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "lltextutil.h"
+
+// newview
+#include "llavatariconctrl.h"
+#include "llinventoryicon.h"
+#include "llviewerobject.h"
+
+LLBlockedListItem::LLBlockedListItem(const LLMute* item)
+:	LLPanel(),
+	mItemID(item->mID),
+	mItemName(item->mName),
+	mMuteType(item->mType)
+{
+	buildFromFile("panel_blocked_list_item.xml");
+}
+
+BOOL LLBlockedListItem::postBuild()
+{
+	mTitleCtrl = getChild<LLTextBox>("item_name");
+	mTitleCtrl->setValue(mItemName);
+
+	switch (mMuteType)
+	{
+	case LLMute::AGENT:
+		{
+			LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+			avatar_icon->setVisible(TRUE);
+			avatar_icon->setValue(mItemID);
+		}
+		break;
+
+	case LLMute::OBJECT:
+		getChild<LLUICtrl>("object_icon")->setVisible(TRUE);
+		break;
+
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+
+void LLBlockedListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+	getChildView("hovered_icon")->setVisible(true);
+	LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLBlockedListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	getChildView("hovered_icon")->setVisible(false);
+	LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLBlockedListItem::setValue(const LLSD& value)
+{
+	if (!value.isMap() || !value.has("selected"))
+	{
+		return;
+	}
+
+	getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
+void LLBlockedListItem::highlightName(const std::string& highlited_text)
+{
+	LLStyle::Params params;
+	LLTextUtil::textboxSetHighlightedVal(mTitleCtrl, params, mItemName, highlited_text);
+}
diff --git a/indra/newview/llblockedlistitem.h b/indra/newview/llblockedlistitem.h
new file mode 100644
index 0000000000..05409e8a3b
--- /dev/null
+++ b/indra/newview/llblockedlistitem.h
@@ -0,0 +1,73 @@
+/**
+ * @file llviewerobjectlistitem.h
+ * @brief viewer object list item header file
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#ifndef LLVIEWEROBJECTLISTITEM_H_
+#define LLVIEWEROBJECTLISTITEM_H_
+
+#include "llmutelist.h"
+#include "llpanel.h"
+#include "llstyle.h"
+#include "lltextbox.h"
+#include "lliconctrl.h"
+
+/**
+ * This class represents items of LLBlockList, which represents
+ * contents of LLMuteList. LLMuteList "consists" of LLMute items.
+ * Each LLMute represents either blocked avatar or object and
+ * stores info about mute type (avatar or object)
+ *
+ * Each item consists if object/avatar icon and object/avatar name
+ *
+ * To create a blocked list item just need to pass LLMute pointer
+ * and appropriate block list item will be created depending on
+ * LLMute type (LLMute::EType) and other LLMute's info
+ */
+class LLBlockedListItem : public LLPanel
+{
+public:
+
+	LLBlockedListItem(const LLMute* item);
+	virtual BOOL postBuild();
+
+	void onMouseEnter(S32 x, S32 y, MASK mask);
+	void onMouseLeave(S32 x, S32 y, MASK mask);
+
+	virtual void setValue(const LLSD& value);
+
+	void 					highlightName(const std::string& highlited_text);
+	const std::string&		getName() const { return mItemName; }
+	const LLMute::EType&	getType() const { return mMuteType; }
+	const LLUUID&			getUUID() const { return mItemID;	}
+
+private:
+
+	LLTextBox*		mTitleCtrl;
+	const LLUUID	mItemID;
+	std::string		mItemName;
+	LLMute::EType	mMuteType;
+
+};
+
+#endif /* LLVIEWEROBJECTLISTITEM_H_ */
diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
new file mode 100644
index 0000000000..521add4bdc
--- /dev/null
+++ b/indra/newview/llblocklist.cpp
@@ -0,0 +1,273 @@
+/**
+ * @file llblocklist.cpp
+ * @brief List of the blocked avatars and objects.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llavataractions.h"
+#include "llblocklist.h"
+#include "llblockedlistitem.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llviewermenu.h"
+
+static LLDefaultChildRegistry::Register<LLBlockList> r("block_list");
+
+static const LLBlockListNameComparator 		NAME_COMPARATOR;
+static const LLBlockListNameTypeComparator	NAME_TYPE_COMPARATOR;
+
+LLBlockList::LLBlockList(const Params& p)
+:	LLFlatListViewEx(p),
+ 	mSelectedItem(NULL),
+ 	mDirty(true)
+{
+
+	LLMuteList::getInstance()->addObserver(this);
+
+	// Set up context menu.
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+	registrar.add		("Block.Action",	boost::bind(&LLBlockList::onCustomAction,	this, _2));
+	enable_registrar.add("Block.Enable",	boost::bind(&LLBlockList::isActionEnabled,	this, _2));
+
+	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
+									"menu_people_blocked_gear.xml",
+									gMenuHolder,
+									LLViewerMenuHolderGL::child_registry_t::instance());
+	if(context_menu)
+	{
+		mContextMenu = context_menu->getHandle();
+	}
+}
+
+LLBlockList::~LLBlockList()
+{
+	if (mContextMenu.get())
+	{
+		mContextMenu.get()->die();
+	}
+
+	LLMuteList::getInstance()->removeObserver(this);
+}
+
+BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
+
+	LLToggleableMenu* context_menu = mContextMenu.get();
+	if (context_menu && size())
+	{
+		context_menu->buildDrawLabels();
+		context_menu->updateParent(LLMenuGL::sMenuContainer);
+		LLMenuGL::showPopup(this, context_menu, x, y);
+	}
+
+	return handled;
+}
+
+void LLBlockList::setNameFilter(const std::string& filter)
+{
+	std::string filter_upper = filter;
+	LLStringUtil::toUpper(filter_upper);
+	if (mNameFilter != filter_upper)
+	{
+		mNameFilter = filter_upper;
+		setDirty();
+	}
+}
+
+void LLBlockList::sortByName()
+{
+	setComparator(&NAME_COMPARATOR);
+	sort();
+}
+
+void LLBlockList::sortByType()
+{
+	setComparator(&NAME_TYPE_COMPARATOR);
+	sort();
+}
+
+void LLBlockList::draw()
+{
+	if (mDirty)
+	{
+		refresh();
+	}
+
+	LLFlatListView::draw();
+}
+
+void LLBlockList::addNewItem(const LLMute* mute)
+{
+	LLBlockedListItem* item = new LLBlockedListItem(mute);
+	if (!mNameFilter.empty())
+	{
+		item->highlightName(mNameFilter);
+	}
+	addItem(item, item->getUUID(), ADD_BOTTOM);
+}
+
+void LLBlockList::refresh()
+{
+	bool have_filter = !mNameFilter.empty();
+
+	// save selection to restore it after list rebuilt
+	LLUUID selected = getSelectedUUID();
+
+	// calling refresh may be initiated by removing currently selected item
+	// so select next item and save the selection to restore it after list rebuilt
+	if (!selectNextItemPair(false, true))
+	{
+		selectNextItemPair(true, true);
+	}
+	LLUUID next_selected = getSelectedUUID();
+
+	clear();
+
+	std::vector<LLMute> mutes = LLMuteList::instance().getMutes();
+	std::vector<LLMute>::const_iterator mute_it = mutes.begin();
+
+	for (; mute_it != mutes.end(); ++mute_it)
+	{
+		if (have_filter && !findInsensitive(mute_it->mName, mNameFilter))
+			continue;
+
+		addNewItem(&*mute_it);
+	}
+
+	if (getItemPair(selected))
+	{
+		// restore previously selected item
+		selectItemPair(getItemPair(selected), true);
+	}
+	else if (getItemPair(next_selected))
+	{
+		// previously selected item was removed, so select next item
+		selectItemPair(getItemPair(next_selected), true);
+	}
+
+	// Sort the list.
+	sort();
+
+	setDirty(false);
+}
+
+bool LLBlockList::findInsensitive(std::string haystack, const std::string& needle_upper)
+{
+    LLStringUtil::toUpper(haystack);
+    return haystack.find(needle_upper) != std::string::npos;
+}
+
+LLBlockedListItem* LLBlockList::getBlockedItem() const
+{
+	LLPanel* panel = LLFlatListView::getSelectedItem();
+	LLBlockedListItem* item = dynamic_cast<LLBlockedListItem*>(panel);
+	return item;
+}
+
+bool LLBlockList::isActionEnabled(const LLSD& userdata)
+{
+	bool action_enabled = true;
+
+	const std::string command_name = userdata.asString();
+
+	if ("unblock_item" == command_name || "profile_item" == command_name)
+	{
+		action_enabled = getSelectedItem() != NULL;
+	}
+
+	return action_enabled;
+}
+
+void LLBlockList::onCustomAction(const LLSD& userdata)
+{
+	if (!isActionEnabled(userdata))
+	{
+		return;
+	}
+
+	LLBlockedListItem* item = getBlockedItem();
+	const std::string command_name = userdata.asString();
+
+	if ("unblock_item" == command_name)
+	{
+		LLMute mute(item->getUUID(), item->getName());
+		LLMuteList::getInstance()->remove(mute);
+	}
+	else if ("profile_item" == command_name)
+	{
+		switch(item->getType())
+		{
+
+		case LLMute::AGENT:
+			LLAvatarActions::showProfile(item->getUUID());
+			break;
+
+		case LLMute::OBJECT:
+			LLFloaterSidePanelContainer::showPanel("inventory", LLSD().with("id", item->getUUID()));
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+bool LLBlockListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
+{
+	const LLBlockedListItem* blocked_item1 = dynamic_cast<const LLBlockedListItem*>(item1);
+	const LLBlockedListItem* blocked_item2 = dynamic_cast<const LLBlockedListItem*>(item2);
+
+	if (!blocked_item1 || !blocked_item2)
+	{
+		llerror("blocked_item1 and blocked_item2 cannot be null", 0);
+		return true;
+	}
+
+	return doCompare(blocked_item1, blocked_item2);
+}
+
+bool LLBlockListNameComparator::doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const
+{
+	std::string name1 = blocked_item1->getName();
+	std::string name2 = blocked_item2->getName();
+
+	LLStringUtil::toUpper(name1);
+	LLStringUtil::toUpper(name2);
+
+	return name1 < name2;
+}
+
+bool LLBlockListNameTypeComparator::doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const
+{
+	LLMute::EType type1 = blocked_item1->getType();
+	LLMute::EType type2 = blocked_item2->getType();
+
+	if (type1 != type2)
+	{
+		return type1 > type2;
+	}
+
+	return NAME_COMPARATOR.compare(blocked_item1, blocked_item2);
+}
diff --git a/indra/newview/llblocklist.h b/indra/newview/llblocklist.h
new file mode 100644
index 0000000000..1a215710f4
--- /dev/null
+++ b/indra/newview/llblocklist.h
@@ -0,0 +1,138 @@
+/**
+ * @file llblocklist.h
+ * @brief List of the blocked avatars and objects.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#ifndef LLBLOCKLIST_H_
+#define LLBLOCKLIST_H_
+
+#include "llflatlistview.h"
+#include "lllistcontextmenu.h"
+#include "llmutelist.h"
+#include "lltoggleablemenu.h"
+
+class LLBlockedListItem;
+class LLMute;
+
+/**
+ * List of blocked avatars and objects.
+ * This list represents contents of the LLMuteList.
+ * Each change in LLMuteList leads to rebuilding this list, so
+ * it's always in actual state.
+ */
+class LLBlockList: public LLFlatListViewEx, public LLMuteListObserver
+{
+	LOG_CLASS(LLBlockList);
+public:
+	struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+	{
+		Params(){};
+	};
+
+	LLBlockList(const Params& p);
+	virtual ~LLBlockList();
+
+	virtual BOOL 		handleRightMouseDown(S32 x, S32 y, MASK mask);
+	LLToggleableMenu*	getContextMenu() const { return mContextMenu.get(); }
+	LLBlockedListItem*	getBlockedItem() const;
+
+	virtual void onChange() { refresh(); }
+	virtual void draw();
+
+	void setNameFilter(const std::string& filter);
+	void sortByName();
+	void sortByType();
+	void refresh();
+
+private:
+
+	void addNewItem(const LLMute* mute);
+	void setDirty(bool dirty = true) { mDirty = dirty; }
+	bool findInsensitive(std::string haystack, const std::string& needle_upper);
+
+	bool isActionEnabled(const LLSD& userdata);
+	void onCustomAction (const LLSD& userdata);
+
+
+	LLHandle<LLToggleableMenu>	mContextMenu;
+
+	LLBlockedListItem*			mSelectedItem;
+	std::string 				mNameFilter;
+	bool 						mDirty;
+
+};
+
+
+/*
+ * Abstract comparator for blocked items
+ */
+class LLBlockListItemComparator : public LLFlatListView::ItemComparator
+{
+	LOG_CLASS(LLBlockListItemComparator);
+
+public:
+	LLBlockListItemComparator() {};
+	virtual ~LLBlockListItemComparator() {};
+
+	virtual bool compare(const LLPanel* item1, const LLPanel* item2) const;
+
+protected:
+
+	virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const = 0;
+};
+
+
+/*
+ * Compares items by name
+ */
+class LLBlockListNameComparator : public LLBlockListItemComparator
+{
+	LOG_CLASS(LLBlockListNameComparator);
+
+public:
+	LLBlockListNameComparator() {};
+	virtual ~LLBlockListNameComparator() {};
+
+protected:
+
+	virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const;
+};
+
+/*
+ * Compares items by type and then by name within type
+ * Objects come first then avatars
+ */
+class LLBlockListNameTypeComparator : public LLBlockListItemComparator
+{
+	LOG_CLASS(LLBlockListNameTypeComparator);
+
+public:
+	LLBlockListNameTypeComparator() {};
+	virtual ~LLBlockListNameTypeComparator() {};
+
+protected:
+
+	virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const;
+};
+
+#endif /* LLBLOCKLIST_H_ */
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 6c8f4406ab..e96a720886 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -48,6 +48,10 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
 {
 	LOG_CLASS(LLGroupList);
 public:
+	struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+	{
+		Params(){};
+	};
 
 	LLGroupList(const Params& p);
 	virtual ~LLGroupList();
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index d2dff63948..35cda14f8d 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -30,15 +30,23 @@
 
 // library include
 #include "llavatarname.h"
+#include "llfiltereditor.h"
 #include "llfloater.h"
 #include "llfloaterreg.h"
 #include "llnotificationsutil.h"
 #include "llscrolllistctrl.h"
+#include "llmenubutton.h"
 
 // project include
+#include "llavatarlistitem.h"
+#include "llblocklist.h"
+#include "llblockedlistitem.h"
 #include "llfloateravatarpicker.h"
 #include "llfloatersidepanelcontainer.h"
+#include "llinventorylistitem.h"
+#include "llinventorymodel.h"
 #include "llsidetraypanelcontainer.h"
+#include "llviewercontrol.h"
 
 static LLRegisterPanelClassWrapper<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray");
 
@@ -54,24 +62,35 @@ const std::string BLOCKED_PARAM_NAME = "blocked_to_select";
 LLPanelBlockedList::LLPanelBlockedList()
 :	LLPanel()
 {
-	mCommitCallbackRegistrar.add("Block.ClickPick",			boost::bind(&LLPanelBlockedList::onPickBtnClick, this));
-	mCommitCallbackRegistrar.add("Block.ClickBlockByName",	boost::bind(&LLPanelBlockedList::onBlockByNameClick, this));
-	mCommitCallbackRegistrar.add("Block.ClickRemove",		boost::bind(&LLPanelBlockedList::onRemoveBtnClick, this));
-}
-
-LLPanelBlockedList::~LLPanelBlockedList()
-{
-	LLMuteList::getInstance()->removeObserver(this);
+	mCommitCallbackRegistrar.add("Block.Action",	boost::bind(&LLPanelBlockedList::onCustomAction,  this, _2));
+	mEnableCallbackRegistrar.add("Block.Check",		boost::bind(&LLPanelBlockedList::isActionChecked, this, _2));
 }
 
 BOOL LLPanelBlockedList::postBuild()
 {
-	mBlockedList = getChild<LLScrollListCtrl>("blocked");
+	mBlockedList = getChild<LLBlockList>("blocked");
 	mBlockedList->setCommitOnSelectionChange(TRUE);
 
-	LLMuteList::getInstance()->addObserver(this);
-	
-	refreshBlockedList();
+	switch (gSavedSettings.getU32("BlockPeopleSortOrder"))
+	{
+	case E_SORT_BY_NAME:
+		mBlockedList->sortByName();
+		break;
+
+	case E_SORT_BY_TYPE:
+		mBlockedList->sortByType();
+		break;
+	}
+
+	// Use the context menu of the Block list for the Block tab gear menu.
+	LLToggleableMenu* blocked_gear_menu = mBlockedList->getContextMenu();
+	if (blocked_gear_menu)
+	{
+		getChild<LLMenuButton>("blocked_gear_btn")->setMenu(blocked_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+	}
+
+	getChild<LLButton>("unblock_btn")->setCommitCallback(boost::bind(&LLPanelBlockedList::unblockItem, this));
+	getChild<LLFilterEditor>("blocked_filter_input")->setCommitCallback(boost::bind(&LLPanelBlockedList::onFilterEdit, this, _2));
 
 	return LLPanel::postBuild();
 }
@@ -92,7 +111,7 @@ void LLPanelBlockedList::onOpen(const LLSD& key)
 
 void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)
 {
-	mBlockedList->selectByID(mute_id);
+	mBlockedList->selectItemByUUID(mute_id);
 }
 
 void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)
@@ -105,55 +124,64 @@ void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)
 //////////////////////////////////////////////////////////////////////////
 // Private Section
 //////////////////////////////////////////////////////////////////////////
-void LLPanelBlockedList::refreshBlockedList()
+void LLPanelBlockedList::updateButtons()
 {
-	mBlockedList->deleteAllItems();
+	bool hasSelected = NULL != mBlockedList->getSelectedItem();
+	getChildView("unblock_btn")->setEnabled(hasSelected);
+}
 
-	std::vector<LLMute> mutes = LLMuteList::getInstance()->getMutes();
-	std::vector<LLMute>::iterator it;
-	for (it = mutes.begin(); it != mutes.end(); ++it)
+void LLPanelBlockedList::unblockItem()
+{
+	LLBlockedListItem* item = mBlockedList->getBlockedItem();
+	if (item)
 	{
-		LLScrollListItem::Params item_p;
-		item_p.enabled(TRUE);
-		item_p.value(it->mID); // link UUID of blocked item with ScrollListItem
-		item_p.columns.add().column("item_name").value(it->mName);//.type("text");
-		item_p.columns.add().column("item_type").value(it->getDisplayType());//.type("text").width(111);
-
-		mBlockedList->addRow(item_p, ADD_BOTTOM);
+		LLMute mute(item->getUUID(), item->getName());
+		LLMuteList::instance().remove(mute);
 	}
 }
 
-void LLPanelBlockedList::updateButtons()
+void LLPanelBlockedList::onCustomAction(const LLSD& userdata)
 {
-	bool hasSelected = NULL != mBlockedList->getFirstSelected();
-	getChildView("Unblock")->setEnabled(hasSelected);
+	const std::string command_name = userdata.asString();
+
+	if ("block_obj_by_name" == command_name)
+	{
+		blockObjectByName();
+	}
+	else if ("block_res_by_name" == command_name)
+	{
+		blockResidentByName();
+	}
+	else if ("sort_by_name" == command_name)
+	{
+		mBlockedList->sortByName();
+		gSavedSettings.setU32("BlockPeopleSortOrder", E_SORT_BY_NAME);
+	}
+	else if ("sort_by_type" == command_name)
+	{
+		mBlockedList->sortByType();
+		gSavedSettings.setU32("BlockPeopleSortOrder", E_SORT_BY_TYPE);
+	}
 }
 
-void LLPanelBlockedList::onRemoveBtnClick()
+BOOL LLPanelBlockedList::isActionChecked(const LLSD& userdata)
 {
-	std::string name = mBlockedList->getSelectedItemLabel();
-	LLUUID id = mBlockedList->getStringUUIDSelectedItem();
-	LLMute mute(id, name);
-	
-	S32 last_selected = mBlockedList->getFirstSelectedIndex();
-	if (LLMuteList::getInstance()->remove(mute))
+	std::string item = userdata.asString();
+	U32 sort_order = gSavedSettings.getU32("BlockPeopleSortOrder");
+
+	if ("sort_by_name" == item)
+	{
+		return E_SORT_BY_NAME == sort_order;
+	}
+	else if ("sort_by_type" == item)
 	{
-		// Above removals may rebuild this dialog.
-		
-		if (last_selected == mBlockedList->getItemCount())
-		{
-			// we were on the last item, so select the last item again
-			mBlockedList->selectNthItem(last_selected - 1);
-		}
-		else
-		{
-			// else select the item after the last item previously selected
-			mBlockedList->selectNthItem(last_selected);
-		}
+		return E_SORT_BY_TYPE == sort_order;
 	}
+
+	return false;
 }
 
-void LLPanelBlockedList::onPickBtnClick()
+void LLPanelBlockedList::blockResidentByName()
 {
 	const BOOL allow_multiple = FALSE;
 	const BOOL close_on_select = TRUE;
@@ -164,11 +192,19 @@ void LLPanelBlockedList::onPickBtnClick()
 	// addDependentFloater(picker);
 }
 
-void LLPanelBlockedList::onBlockByNameClick()
+void LLPanelBlockedList::blockObjectByName()
 {
 	LLFloaterGetBlockedObjectName::show(&LLPanelBlockedList::callbackBlockByName);
 }
 
+void LLPanelBlockedList::onFilterEdit(const std::string& search_string)
+{
+	std::string filter = search_string;
+	LLStringUtil::trimHead(filter);
+
+	mBlockedList->setNameFilter(filter);
+}
+
 void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
 {
 	if (names.empty() || ids.empty()) return;
diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h
index 97236ecdbf..332349dfc0 100644
--- a/indra/newview/llpanelblockedlist.h
+++ b/indra/newview/llpanelblockedlist.h
@@ -30,21 +30,15 @@
 #include "llpanel.h"
 #include "llmutelist.h"
 #include "llfloater.h"
-// #include <vector>
 
-// class LLButton;
-// class LLLineEditor;
-// class LLMessageSystem;
-// class LLUUID;
 class LLAvatarName;
-class LLScrollListCtrl;
+class LLBlockList;
 
-class LLPanelBlockedList
-	:	public LLPanel, public LLMuteListObserver
+class LLPanelBlockedList : public LLPanel
 {
 public:
 	LLPanelBlockedList();
-	~LLPanelBlockedList();
+	~LLPanelBlockedList(){};
 
 	virtual BOOL postBuild();
 	virtual void draw();
@@ -59,24 +53,31 @@ public:
 	 *			If it is LLUUID::null, nothing will be selected.
 	 */
 	static void showPanelAndSelect(const LLUUID& idToSelect);
-
-	// LLMuteListObserver callback interface implementation.
-	/* virtual */ void onChange() {	refreshBlockedList();}
 	
 private:
-	void refreshBlockedList();
+
+	typedef enum e_sort_oder{
+		E_SORT_BY_NAME = 0,
+		E_SORT_BY_TYPE = 1,
+	} ESortOrder;
+
 	void updateButtons();
 
 	// UI callbacks
-	void onRemoveBtnClick();
-	void onPickBtnClick();
-	void onBlockByNameClick();
+	void unblockItem();
+	void blockResidentByName();
+	void blockObjectByName();
+	void onFilterEdit(const std::string& search_string);
+
+	// List commnads
+	void onCustomAction(const LLSD& userdata);
+	BOOL isActionChecked(const LLSD& userdata);
 
 	void callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
 	static void callbackBlockByName(const std::string& text);
 
 private:
-	LLScrollListCtrl* mBlockedList;
+	LLBlockList* mBlockedList;
 };
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000..63295ea27b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_blocked_gear"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_call
+   label="Unblock"
+   name="unblock">
+      <on_click
+       function="Block.Action"
+       parameter="unblock_item" />
+      <on_enable
+       function="Block.Enable"
+       parameter="unblock_item" /> 
+  </menu_item_call>
+  <menu_item_call
+   label="Profile..."
+   name="profile">
+      <on_click
+       function="Block.Action"
+       parameter="profile_item"/>
+      <on_enable
+       function="Block.Enable"
+       parameter="profile_item" />
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000..0c7155667e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_blocked_plus"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_call
+   label="Block Resident by name..."
+   name="block_resident_by_name">
+      <on_click
+       function="Block.Action"
+       parameter="block_res_by_name"/>
+  </menu_item_call>
+  <menu_item_call
+   label="Block object by name"
+   name="block_object_by_name">
+      <on_click
+       function="Block.Action"
+       parameter="block_obj_by_name"/>
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml
new file mode 100644
index 0000000000..2efb70ee37
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_blocked_view"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check
+   label="Sort by name"
+   name="sort_by_name">
+      <on_click
+       function="Block.Action"
+       parameter="sort_by_name"/>
+      <on_check
+       function="Block.Check"
+       parameter="sort_by_name"/>
+  </menu_item_check>
+  <menu_item_check
+   label="Sort by type"
+   name="sort_by_type">
+      <on_click
+       function="Block.Action"
+       parameter="sort_by_type" />
+      <on_check
+       function="Block.Check"
+       parameter="sort_by_type" />
+  </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index 3577d2f457..f466504938 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -5,90 +5,94 @@
  height="305"
  layout="topleft"
  left="0"
- right="-1"
  name="block_list_panel"
  help_topic="blocked_list"
  min_height="350"
  min_width="240"
- width="280">
-        <button
-     follows="top|left"
-     height="24"
-     image_hover_unselected="BackButton_Over"
-     image_pressed="BackButton_Press"
-     image_unselected="BackButton_Off"
-     layout="topleft"
-     name="back"
-     left="4"
-     tab_stop="false"
-     top="1"
-     width="30"/>
-    <text
-     follows="top|left|right"
-     font="SansSerifLargeBold"
-     height="20"
-     layout="topleft"
-     left_pad="10"
-     name="title_text"
-     text_color="white"
-     top="5"
-     width="250">
-        Block List
-     </text>
-    <scroll_list
+ width="323">
+     <panel
+      follows="left|top|right"
+      height="27"
+      label="bottom_panel"
+      layout="topleft"
+      left="0"
+      name="blocked_buttons_panel"
+      right="-1"
+      top="0">
+         <filter_editor
+          follows="left|top|right"
+          height="23"
+          layout="topleft"
+          left="6"
+          label="Filter"
+          max_length_chars="300"
+          name="blocked_filter_input"
+          text_color="Black"
+          text_pad_left="10"
+          top="4"
+          width="177" />
+         <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="OptionsMenu_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="8"
+          menu_filename="menu_people_blocked_gear.xml"
+          menu_position="bottomleft"
+          name="blocked_gear_btn"
+          top="3"
+          width="31" />
+         <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="Inv_Underpants"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="2"
+          menu_filename="menu_people_blocked_view.xml"
+          menu_position="bottomleft"
+          name="view_btn"
+          top_delta="0"
+          width="31" />
+         <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="AddItem_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="2"
+          menu_filename="menu_people_blocked_plus.xml"
+          menu_position="bottomleft"
+          name="plus_btn"
+          top_delta="0"
+          width="31"/>
+          <button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="TrashItem_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          left_pad="2"
+          layout="topleft"
+          name="unblock_btn"
+          top_delta="0"
+          width="31"/>
+     </panel>
+    <block_list
      follows="all"
-     height="190"
+     height="273"
      layout="topleft"
-     left="5"
+     left="3"
      name="blocked"
      tool_tip="List of currently blocked Residents"
-     top="30"
-  	 right="-1"
-     width="270">
-        <scroll_list.columns
-         name="item_name" />
-        <scroll_list.columns
-         name="item_type"
-         width="96" />
-    </scroll_list>
-    <button
-     follows="left|bottom"
-     height="23"
-     label="Block person"
-     layout="topleft"
-     left_delta="0"
-     name="Block resident..."
-     tool_tip="Pick a Resident to block"
-     top_pad="4"
-     width="210">
-        <button.commit_callback
-         function="Block.ClickPick" />
-    </button>
-    <button
-     follows="left|bottom"
-     height="23"
-     label="Block object by name"
-     layout="topleft"
-     left_delta="0"
-     name="Block object by name..."
-     tool_tip="Pick an object to block by name"
-     top_pad="4"
-     width="210" >
-        <button.commit_callback
-         function="Block.ClickBlockByName" />
-    </button>
-    <button
-     enabled="false"
-     follows="left|bottom"
-     height="23"
-     label="Unblock"
-     layout="topleft"
-     left_delta="0"
-     name="Unblock"
-     tool_tip="Remove Resident or object from blocked list"
-     top_pad="4"
-     width="210" >
-        <button.commit_callback
-         function="Block.ClickRemove" />
-    </button>
+     top="31"
+  	 right="-1"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
new file mode 100644
index 0000000000..a63a14ca69
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="blocked_list_item"
+ top="0"
+ width="380">
+    <icon
+     height="24"
+     follows="top|right|left"
+     image_name="ListItem_Select"
+     layout="topleft"
+     left="0"
+     name="selected_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     follows="top|right|left"
+     height="24"
+     image_name="ListItem_Over"
+     layout="topleft"
+     left="0"
+     name="hovered_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <avatar_icon
+     default_icon_name="Generic_Person"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left="5"
+     mouse_opaque="true"
+     top="2"
+     visible="false"
+     width="20" />
+    <icon
+     follows="top|left"
+     height="16"
+     image_name="Inv_Object"
+     layout="topleft"
+     left="7"
+     name="object_icon"
+     top="4"
+     visible="false"
+     width="16" />
+    <text
+     follows="left|right"
+     font="SansSerifSmall"
+     font.color="DkGray"
+     height="15"
+     layout="topleft"
+     left_pad="5"
+     name="item_name"
+     parse_urls="false"
+     top="6"
+     use_ellipses="true"
+     width="180" />
+</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index ceb03d03a9..38a996547c 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -611,6 +611,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
            filename="panel_block_list_sidetray.xml"
            follows="all"
            label="Blocked Residents &amp; Objects"
+           layout="topleft"
            left="0"
            font="SansSerifBold"
            top="0"
-- 
cgit v1.2.3


From afc6a7e6baeb9b568feb31cfd8eb978bb485c0c6 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 22 Jun 2012 20:05:35 +0300
Subject: CHUI-136 ADDITIONAL FIX (Implement new design for blocked list on the
 people floater)

- If mute item type is LLMute::BY_NAME it means that it's an object and we should show corresponding icon
- Also added icon for blocked groups
---
 indra/newview/llblockedlistitem.cpp                           | 11 ++++++++++-
 .../newview/skins/default/xui/en/panel_blocked_list_item.xml  | 10 ++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llblockedlistitem.cpp b/indra/newview/llblockedlistitem.cpp
index 14da35c85a..d9afd2b629 100644
--- a/indra/newview/llblockedlistitem.cpp
+++ b/indra/newview/llblockedlistitem.cpp
@@ -38,6 +38,7 @@
 
 // newview
 #include "llavatariconctrl.h"
+#include "llgroupiconctrl.h"
 #include "llinventoryicon.h"
 #include "llviewerobject.h"
 
@@ -58,14 +59,22 @@ BOOL LLBlockedListItem::postBuild()
 	switch (mMuteType)
 	{
 	case LLMute::AGENT:
+	case LLMute::EXTERNAL:
 		{
 			LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
 			avatar_icon->setVisible(TRUE);
 			avatar_icon->setValue(mItemID);
 		}
 		break;
-
+	case LLMute::GROUP:
+		{
+			LLGroupIconCtrl* group_icon = getChild<LLGroupIconCtrl>("group_icon");
+			group_icon->setVisible(TRUE);
+			group_icon->setValue(mItemID);
+		}
+		break;
 	case LLMute::OBJECT:
+	case LLMute::BY_NAME:
 		getChild<LLUICtrl>("object_icon")->setVisible(TRUE);
 		break;
 
diff --git a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
index a63a14ca69..84e7e467b1 100644
--- a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
@@ -37,6 +37,16 @@
      top="2"
      visible="false"
      width="20" />
+    <group_icon
+     default_icon_name="Generic_Group"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left="5"
+     mouse_opaque="true"
+     top="2"
+     visible="false"
+     width="20" />
     <icon
      follows="top|left"
      height="16"
-- 
cgit v1.2.3


From 75804ef2b918906108af4a3b9ceb6cbfc1354393 Mon Sep 17 00:00:00 2001
From: merov <none@none>
Date: Fri, 22 Jun 2012 19:28:11 +0100
Subject: CHUI-136 : Fix compilation issue showing up when warning treated as
 errors

---
 indra/newview/llblocklist.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index 521add4bdc..cb68f677eb 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -24,8 +24,11 @@
  * $/LicenseInfo$
  */
 
-#include "llavataractions.h"
+#include "llviewerprecompiledheaders.h"
+
 #include "llblocklist.h"
+
+#include "llavataractions.h"
 #include "llblockedlistitem.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llviewermenu.h"
-- 
cgit v1.2.3


From 74092930afdc294ef4d204830173d4750a310616 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 22 Jun 2012 14:13:20 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose build fix for gcc
 added detection of duplicate widget registration

---
 indra/llui/lluictrlfactory.cpp    | 15 ++++++++-------
 indra/llui/lluictrlfactory.h      |  4 ++--
 indra/llxuixml/llregistry.h       |  4 ++++
 indra/newview/llfolderviewmodel.h |  2 +-
 4 files changed, 15 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 25e7a31e90..f64f33bc5e 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -278,13 +278,13 @@ const LLInitParam::BaseBlock& get_empty_param_block()
 
 // adds a widget and its param block to various registries
 //static 
-void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag)
+void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& name)
 {
 	// associate parameter block type with template .xml file
-	std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type);
-	if (existing_tag != NULL)
+	std::string* existing_name = LLWidgetNameRegistry::instance().getValue(param_block_type);
+	if (existing_name != NULL)
 	{
-		if(*existing_tag != tag)
+		if(*existing_name != name)
 		{
 			std::cerr << "Duplicate entry for T::Params, try creating empty param block in derived classes that inherit T::Params" << std::endl;
 			// forcing crash here
@@ -293,18 +293,19 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st
 		}
 		else
 		{
-			// widget already registered
+			// widget already registered this name
 			return;
 		}
 	}
-	LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag);
+
+	LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, name);
 	//FIXME: comment this in when working on schema generation
 	//LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type);
 	//LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block<T>);
 }
 
 //static 
-const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type)
+const std::string* LLUICtrlFactory::getWidgetName(const std::type_info* widget_type)
 {
 	return LLWidgetNameRegistry::instance().getValue(widget_type);
 }
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index d612ad5005..b441cb0c9d 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -105,7 +105,7 @@ private:
 		ParamDefaults()
 		{
 			// look up template file for this param block...
-			const std::string* param_block_tag = getWidgetTag(&typeid(PARAM_BLOCK));
+			const std::string* param_block_tag = getWidgetName(&typeid(PARAM_BLOCK));
 			if (param_block_tag)
 			{	// ...and if it exists, back fill values using the most specific template first
 				PARAM_BLOCK params;
@@ -303,7 +303,7 @@ private:
 	}
 
 
-	static const std::string* getWidgetTag(const std::type_info* widget_type);
+	static const std::string* getWidgetName(const std::type_info* widget_type);
 
 	// this exists to get around dependency on llview
 	static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);
diff --git a/indra/llxuixml/llregistry.h b/indra/llxuixml/llregistry.h
index 36ce6a97b7..3e8d9267cc 100644
--- a/indra/llxuixml/llregistry.h
+++ b/indra/llxuixml/llregistry.h
@@ -302,6 +302,10 @@ public:
 		virtual ~StaticRegistrar() {}
 		StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
 		{
+			if (singleton_t::instance().exists(key))
+			{
+				llerrs << "Duplicate registry entry under key \"" << key << "\"" << llendl;
+			}
 			singleton_t::instance().mStaticScope->add(key, value);
 		}
 	};
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index c3dcfed97c..74c8bb92ef 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -218,7 +218,7 @@ public:
 	virtual S32 getSortVersion() = 0;
 	virtual void setSortVersion(S32 version) = 0;
 protected:
-	friend LLFolderViewItem;
+	friend class LLFolderViewItem;
 	void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
 	LLFolderViewItem*	mFolderViewItem;
 
-- 
cgit v1.2.3


From 9fc77dec8788944f93eda14567f9235f97637097 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Mon, 25 Jun 2012 15:49:49 +0300
Subject: CHUI-175 FIXED (Cannot use scroll bar on chat entry field when multi
 line chat is added)

- This change also fixes:
        CHUI-176 (Only bottom 2 lines of multi line chat allow for selecting in text chat entry)
        CHUI-177 (Text entry field in chat only accepts 256 characters)
---
 .../skins/default/xui/en/floater_im_session.xml    | 39 +++++++++-------------
 1 file changed, 16 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 0720a4b011..56e591e2bb 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -235,29 +235,22 @@
             </layout_panel>
            </layout_stack>
            </panel>
-            <panel width="225" 
-             height="31" 
-             left="4" 
-             name="bottom_panel"
-             bottom="-1" 
-             follows="left|right|bottom" 
-             tab_group="1">    
-            	<chat_editor
-             		bottom="0"
-             		expand_lines_count="5"
-             		follows="left|right|bottom"
-	         		font="SansSerifSmall"
-	         		visible="true"
-             		height="20"
-             		is_expandable="true"
-             		label="To"
-             		layout="bottomleft"
-             		name="chat_editor"
-             		tab_group="3"
-             		width="240"
-             		wrap="true">
-            	</chat_editor>
-              </panel>
+            <chat_editor
+              bottom="0"
+              expand_lines_count="5"
+              follows="left|right|bottom"
+              font="SansSerifSmall"
+              visible="true"
+              height="20"
+              is_expandable="true"
+              label="To"
+              layout="bottomleft"
+              name="chat_editor"
+              max_length="1024"
+              tab_group="3"
+              width="240"
+              wrap="true">
+            </chat_editor>
     </layout_panel>
   </layout_stack>
     </view>
-- 
cgit v1.2.3


From 9353a9e6ef071bd980c319d038b1dedb649d2db0 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 25 Jun 2012 23:55:25 +0300
Subject: CHUI-167 FIXED Move onClose() from LLIMFloater to it's basic class
 (LLIMConversation) for correct using add/remove conversation list items also
 for LLNearbyChat

---
 indra/newview/llimconversation.cpp | 14 +++++++
 indra/newview/llimconversation.h   |  1 +
 indra/newview/llimfloater.cpp      | 84 ++++++++++++++++++--------------------
 3 files changed, 54 insertions(+), 45 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index cbebf3edd3..f304997abf 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -339,6 +339,20 @@ void LLIMConversation::onOpen(const LLSD& key)
 	updateHeaderAndToolbar();
 }
 
+// virtual
+void LLIMConversation::onClose(bool app_quitting)
+{
+	// Always suppress the IM from the conversations list on close if present for any reason
+	if (LLIMConversation::isChatMultiTab())
+	{
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
+		if (im_box)
+		{
+            im_box->removeConversationListItem(mSessionID);
+        }
+    }
+}
+
 void LLIMConversation::onTearOffClicked()
 {
 	onClickTearOff(this);
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index f4b8a38242..47c98d6f8b 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -63,6 +63,7 @@ public:
 
 	// LLFloater overrides
 	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ BOOL postBuild();
 
 protected:
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 98ebc82f99..37ee7b8a7c 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -105,51 +105,6 @@ void LLIMFloater::onFocusReceived()
 	}
 }
 
-// virtual
-void LLIMFloater::onClose(bool app_quitting)
-{
-	// Always suppress the IM from the conversations list on close if present for any reason
-	if (LLIMConversation::isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
-		if (im_box)
-		{
-            im_box->removeConversationListItem(mSessionID);
-        }
-    }
-
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				mSessionID);
-
-	if (session == NULL)
-	{
-		llwarns << "Empty session." << llendl;
-		return;
-	}
-
-	bool is_call_with_chat = session->isGroupSessionType()
-			|| session->isAdHocSessionType() || session->isP2PSessionType();
-
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-	if (is_call_with_chat && voice_channel != NULL
-			&& voice_channel->isActive())
-	{
-		LLSD payload;
-		payload["session_id"] = mSessionID;
-		LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
-		return;
-	}
-
-	setTyping(false);
-
-	// The source of much argument and design thrashing
-	// Should the window hide or the session close when the X is clicked?
-	//
-	// Last change:
-	// EXT-3516 X Button should end IM session, _ button should hide
-	gIMMgr->leaveSession(mSessionID);
-}
 
 /* static */
 void LLIMFloater::newIMCallback(const LLSD& data)
@@ -611,6 +566,45 @@ LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
 	return conversation;
 }
 
+void LLIMFloater::onClose(bool app_quitting)
+{
+	LLIMConversation::onClose(app_quitting);
+
+
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
+				mSessionID);
+
+	if (session == NULL)
+	{
+		llwarns << "Empty session." << llendl;
+		return;
+	}
+
+	bool is_call_with_chat = session->isGroupSessionType()
+			|| session->isAdHocSessionType() || session->isP2PSessionType();
+
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+	if (is_call_with_chat && voice_channel != NULL
+			&& voice_channel->isActive())
+	{
+		LLSD payload;
+		payload["session_id"] = mSessionID;
+		LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+		return;
+	}
+
+	setTyping(false);
+
+	// The source of much argument and design thrashing
+	// Should the window hide or the session close when the X is clicked?
+	//
+	// Last change:
+	// EXT-3516 X Button should end IM session, _ button should hide
+	gIMMgr->leaveSession(mSessionID);
+
+}
+
 void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 {
 	// update notification channel state
-- 
cgit v1.2.3


From 7f3b27289da2478381dcb4d7e9f05e082e37eaa2 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 25 Jun 2012 21:59:13 +0300
Subject: CHUI-168 FIXED Added call of updateHeaderAndToolbar from postBuild
 for correct floater's title and standard buttons showing at start

---
 indra/newview/llimconversation.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index f304997abf..d3f3e41a29 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -103,6 +103,7 @@ BOOL LLIMConversation::postBuild()
 	}
 
 	buildParticipantList();
+	updateHeaderAndToolbar();
 
 	if (isChatMultiTab())
 	{
-- 
cgit v1.2.3


From 5b6db72c5b7c5c3c4cfde671480ec1fc56bbd859 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 25 Jun 2012 13:04:09 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose all inventory names
 are correctly initialized now

---
 indra/newview/llinventorybridge.cpp | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index c0670b71d4..70a174a140 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1844,14 +1844,17 @@ void LLFolderBridge::buildDisplayName() const
 
 	//"Accessories" inventory category has folder type FT_NONE. So, this folder
 	//can not be detected as protected with LLFolderType::lookupIsProtectedType
+	mDisplayName.assign(getName());
 	if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
 	{
 		LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
 	}
-	else
-	{
-		mDisplayName.assign(getName());
-	}
+
+	//if (mDisplayName.empty())
+	//{
+	//	S32 foo;
+	//	foo = 0;
+	//}
 }
 
 
-- 
cgit v1.2.3


From 41e965c12e29136d2b81a9b67d6b6c9af4fb2092 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 25 Jun 2012 15:20:52 -0700
Subject: CHUI-139 : Hide torn off floaters when hiding conversation list; make
 nearby chat always present; leave conversation list around when all torn off

---
 indra/llui/llmultifloater.h            |  4 +--
 indra/newview/llimconversation.cpp     |  6 +++-
 indra/newview/llimfloatercontainer.cpp | 51 ++++++++++++++++++++++++++++++++--
 indra/newview/llimfloatercontainer.h   |  6 ++++
 4 files changed, 62 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index f299ae5dd3..44514a6246 100644
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -45,8 +45,8 @@ public:
 	
 	virtual BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void draw();
-	/*virtual*/ void setVisible(BOOL visible);
+	virtual void draw();
+	virtual void setVisible(BOOL visible);
 	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
 	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
 
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index bbbc9fcffd..cbebf3edd3 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -106,6 +106,10 @@ BOOL LLIMConversation::postBuild()
 
 	if (isChatMultiTab())
 	{
+		if (mIsNearbyChat)
+		{
+			setCanClose(FALSE);
+		}
 		return LLFloater::postBuild();
 	}
 	else
@@ -246,7 +250,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
 
-	mCloseBtn->setVisible(is_hosted);
+	mCloseBtn->setVisible(is_hosted && !mIsNearbyChat);
 
 	enableDisableCallBtn();
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index a2a54bf02c..33b96b20f3 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -103,14 +103,14 @@ BOOL LLIMFloaterContainer::postBuild()
 
 void LLIMFloaterContainer::onOpen(const LLSD& key)
 {
-	LLMultiFloater::onOpen(key);
 	if (getFloaterCount() == 0)
 	{
-		// If there's *no* conversation open so far, we force the opening of the nearby chat conversation
+		// We always force the opening of the nearby chat conversation when we open for the first  time
 		// *TODO: find a way to move this to XML as a default panel or something like that
 		LLSD name("chat_bar");
 		LLFloaterReg::toggleInstanceOrBringToFront(name);
 	}
+	LLMultiFloater::onOpen(key);
 	/*
 	if (key.isDefined())
 	{
@@ -284,6 +284,44 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 	}
 }
 
+void LLIMFloaterContainer::draw()
+{
+	if (mTabContainer->getTabCount() == 0)
+	{
+		// Do not close the container when every conversation is torn off because the user
+		// still needs the conversation list. Simply collapse the message pane in that case.
+		collapseMessagesPane(true);
+	}
+	LLFloater::draw();
+}
+
+void LLIMFloaterContainer::tabClose()
+{
+	if (mTabContainer->getTabCount() == 0)
+	{
+		// Do not close the container when every conversation is torn off because the user
+		// still needs the conversation list. Simply collapse the message pane in that case.
+		collapseMessagesPane(true);
+	}
+}
+
+void LLIMFloaterContainer::setVisible(BOOL visible)
+{
+	// We need to show/hide all the associated conversations that have been torn off
+	// (and therefore, are not longer managed by the multifloater),
+	// so that they show/hide with the conversations manager.
+	conversations_items_map::iterator item_it = mConversationsItems.begin();
+	for (;item_it != mConversationsItems.end(); ++item_it)
+	{
+		LLConversationItem* item = item_it->second;
+		item->setVisibleIfDetached(visible);
+	}
+	
+	// Now, do the normal multifloater show/hide
+	LLMultiFloater::setVisible(visible);
+	
+}
+
 void LLIMFloaterContainer::collapseMessagesPane(bool collapse)
 {
 	if (mMessagesPane->isCollapsed() == collapse)
@@ -485,6 +523,15 @@ void LLConversationItem::selectItem(void)
 	mFloater->setFocus(TRUE);    
 }
 
+void LLConversationItem::setVisibleIfDetached(BOOL visible)
+{
+	// Do this only if the conversation floater has been torn off (i.e. no multi floater host)
+	if (!mFloater->getHost())
+	{
+		mFloater->setVisible(visible);    
+	}
+}
+
 void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
 {
 }
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 3d1324c2fb..c6e7c6a3d9 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -97,6 +97,8 @@ public:
 	virtual void previewItem( void );
 	virtual void selectItem(void);
 	virtual void showProperties(void);
+
+	void setVisibleIfDetached(BOOL visible);
 	
 	// This method should be called when a drag begins.
 	// Returns TRUE if the drag can begin, FALSE otherwise.
@@ -128,6 +130,8 @@ public:
 	
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void draw();
+	/*virtual*/ void setVisible(BOOL visible);
 	void onCloseFloater(LLUUID& id);
 
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
@@ -135,6 +139,8 @@ public:
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
 	/*virtual*/ void removeFloater(LLFloater* floaterp);
 
+	/*virtual*/ void tabClose();
+
 	static LLFloater* getCurrentVoiceFloater();
 
 	static LLIMFloaterContainer* findInstance();
-- 
cgit v1.2.3


From 9c11a6b206f2455e37cf3ba8719bf6b51bc994e8 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 26 Jun 2012 18:58:57 +0300
Subject: CHUI-177 ADDITIONAL FIX (Text entry field in chat only accepts 256
 characters)

- Limited text entry field to 1024 instead of 1025 characters
should take into account zero (0 ... 1023)
---
 indra/newview/skins/default/xui/en/floater_im_session.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 56e591e2bb..08bc46a506 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -246,7 +246,7 @@
               label="To"
               layout="bottomleft"
               name="chat_editor"
-              max_length="1024"
+              max_length="1023"
               tab_group="3"
               width="240"
               wrap="true">
-- 
cgit v1.2.3


From 677c205131e695eb5a3b2a190799330b49d636d8 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 26 Jun 2012 19:08:27 +0300
Subject: CHUI-182 FIXED (Vertical scrollbar flashes on and off when chat entry
 text area expands)

- To avoid unnecessary appearing of scrollbar, first chat entry must be expanded
and only then decision should be taken in the base class whether scrollbar should be shown or not.
---
 indra/llui/llchatentry.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index a6ba125406..2a6ccc3dc9 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -57,12 +57,12 @@ LLChatEntry::~LLChatEntry()
 
 void LLChatEntry::draw()
 {
-	LLTextEditor::draw();
-
 	if(mIsExpandable)
 	{
 		expandText();
 	}
+
+	LLTextEditor::draw();
 }
 
 void LLChatEntry::onCommit()
-- 
cgit v1.2.3


From abe106bd9c33fef12dcf4eacca228d5d669d9e34 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 26 Jun 2012 19:27:19 +0300
Subject: - CHUI-178 (Right click context menu not present in chat entry field)

- Set parameter to true to show context menu
---
 indra/newview/skins/default/xui/en/widgets/chat_editor.xml | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 indra/newview/skins/default/xui/en/widgets/chat_editor.xml

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/widgets/chat_editor.xml b/indra/newview/skins/default/xui/en/widgets/chat_editor.xml
new file mode 100644
index 0000000000..f9facb593a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/chat_editor.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<chat_editor
+  name="chat_editor"
+  show_context_menu="true"/>
-- 
cgit v1.2.3


From c233f0c9494d7dddbd8baab0f87b0ad54f42b0f9 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 26 Jun 2012 17:05:16 -0700
Subject: CHUI-164 : Fix crash when closing ad-hoc conversations; insure
 consistency of the conversation list when adding and removing items from it

---
 indra/newview/llimfloater.cpp          |  9 ++++--
 indra/newview/llimfloatercontainer.cpp | 56 +++++++++++++++++++++++++++-------
 indra/newview/llimfloatercontainer.h   |  8 +++--
 3 files changed, 58 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 98ebc82f99..f89bafc7ea 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -540,8 +540,10 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 		}
 	}
 
+	// Test the existence of the floater before we try to create it
 	bool exist = findInstance(session_id);
 
+	// Get the floater: this will create the instance if it didn't exist
 	LLIMFloater* floater = getInstance(session_id);
 	if (!floater)
 		return NULL;
@@ -550,18 +552,21 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 	{
 		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
 
-		// do not add existed floaters to avoid adding torn off instances
+		// Do not add again existing floaters
 		if (!exist)
 		{
 			//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
 			// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
 			LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
-			
 			if (floater_container)
 			{
 				floater_container->addFloater(floater, TRUE, i_pt);
 			}
 		}
+		
+		// Add a conversation list item in the left pane: nothing will be done if already in there
+		// but relevant clean up will be done to ensure consistency of the conversation list
+		floater_container->addConversationListItem(floater->getTitle(), session_id, floater);
 
 		floater->openFloater(floater->getKey());
 	}
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 33b96b20f3..f6bcf8bbe9 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -146,7 +146,7 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 	LLUUID session_id = floaterp->getKey();
 
 	// Add a conversation list item in the left pane
-	addConversationListItem(floaterp->getTitle(), session_id, floaterp, this);
+	addConversationListItem(floaterp->getTitle(), session_id, floaterp);
 	
 	LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
 
@@ -408,18 +408,33 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
 }
 
 // CHUI-137 : Temporary implementation of conversations list
-void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp)
+void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp)
 {
-	// Check if the item is not already in the list, exit if it is (nothing to do)
+	// Check if the item is not already in the list, exit if it is and has the same name and points to the same floater (nothing to do)
 	// Note: this happens often, when reattaching a torn off conversation for instance
 	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
 	if (item_it != mConversationsItems.end())
 	{
-		return;
+		LLConversationItem* item = item_it->second;
+		// Check if the item has changed
+		if (item->hasSameValues(name,floaterp))
+		{
+			// If it hasn't, nothing to do -> exit
+			return;
+		}
+		// If it has, remove it: it'll be recreated anew further down
+		removeConversationListItem(uuid,false);
+	}
+	
+	// Reverse find and clean up: we need to make sure that no other uuid is pointing to that same floater
+	LLUUID found_id = LLUUID::null;
+	if (findConversationItem(floaterp,found_id))
+	{
+		removeConversationListItem(found_id,false);
 	}
 
 	// Create a conversation item
-	LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, containerp);
+	LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, this);
 	mConversationsItems[uuid] = item;
 
 	// Create a widget from it
@@ -439,7 +454,7 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 	return;
 }
 
-void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id)
+void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id, bool change_focus)
 {
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
@@ -469,16 +484,35 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id)
 	}
 	
 	// Don't let the focus fall IW, select and refocus on the first conversation in the list
-	setFocus(TRUE);
-	conversations_items_map::iterator item_it = mConversationsItems.begin();
-	if (item_it != mConversationsItems.end())
+	if (change_focus)
 	{
-		LLConversationItem* item = item_it->second;
-		item->selectItem();
+		setFocus(TRUE);
+		conversations_items_map::iterator item_it = mConversationsItems.begin();
+		if (item_it != mConversationsItems.end())
+		{
+			LLConversationItem* item = item_it->second;
+			item->selectItem();
+		}
 	}
 	return;
 }
 
+bool LLIMFloaterContainer::findConversationItem(LLFloater* floaterp, LLUUID& uuid)
+{
+	bool found = false;
+	for (conversations_items_map::iterator item_it = mConversationsItems.begin(); item_it != mConversationsItems.end(); ++item_it)
+	{
+		LLConversationItem* item = item_it->second;
+		uuid = item_it->first;
+		if (item->hasSameValue(floaterp))
+		{
+			found = true;
+			break;
+		}
+	}
+	return found;
+}
+
 LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
 {
 	LLFolderViewItem::Params params;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index c6e7c6a3d9..2a8cbf3e1c 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -112,6 +112,9 @@ public:
 							EDragAndDropType cargo_type,
 							void* cargo_data,
 							std::string& tooltip_msg) { return FALSE; }
+	
+	bool hasSameValues(std::string name, LLFloater* floaterp) { return ((name == mName) && (floaterp == mFloater)); }
+	bool hasSameValue(LLFloater* floaterp) { return (floaterp == mFloater); }
 private:
 	std::string mName;
 	const LLUUID mUUID;
@@ -183,9 +186,10 @@ private:
 	
 	// CHUI-137 : Temporary implementation of conversations list
 public:
-	void removeConversationListItem(const LLUUID& session_id);
+	void removeConversationListItem(const LLUUID& session_id, bool change_focus = true);
+	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
+	bool findConversationItem(LLFloater* floaterp, LLUUID& uuid);
 private:
-	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
 	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 	// Conversation list data
 	LLPanel* mConversationsListPanel;	// This is the widget we add items to (i.e. clickable title for each conversation)
-- 
cgit v1.2.3


From a7831406abfe87e9bd1da8091e008edcd65b402c Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Wed, 27 Jun 2012 18:52:08 +0300
Subject: CHUI-180 FIXED (Started an ad hoc IM spams log with drawtext warning)

- Don't draw TextBase context if it's empty and in focus
---
 indra/llui/lltextbase.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c112a7e477..3b3bc64c5b 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -508,7 +508,7 @@ void LLTextBase::drawText()
 	{
 		return;
 	}
-	else if (text_len <= 0 && !mLabel.empty())
+	else if (text_len <= 0 && !mLabel.empty() && !hasFocus())
 	{
 		text_len = mLabel.length();
 	}
-- 
cgit v1.2.3


From 0cfea7b406c87bf593d2f7cf6040d92ef99b64cf Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Tue, 26 Jun 2012 01:38:59 +0300
Subject: CHUI-147 FIX Added updating conference participants in IM floater
 title - The title is updated with the data from participants list widget in
 IM floater. - Creating the participants list is fixed for the case of
 starting the ad hoc session when the session id changes upon initialization
 (see LLIMConversation::buildParticipantList()). - LLEventTimer replaced with
 simple LLTimer to avoid crashes in LLEventTimer::tick(). - Moved the
 build_residents_string() code to LLAvatarActions::buildResidentsString() to
 use it in LLIMFloater::onParticipantsListChanged().

---
 indra/newview/llavataractions.cpp   | 35 +++++++-------
 indra/newview/llavataractions.h     |  9 ++++
 indra/newview/llimconversation.cpp  | 34 +++++++++-----
 indra/newview/llimconversation.h    | 10 ++--
 indra/newview/llimfloater.cpp       | 93 ++++++++++++++++++++++++++++---------
 indra/newview/llimfloater.h         |  9 +++-
 indra/newview/llnearbychat.cpp      | 36 ++++++--------
 indra/newview/llnearbychat.h        |  6 +--
 indra/newview/llparticipantlist.cpp |  1 +
 9 files changed, 151 insertions(+), 82 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index c9031dd26a..21367c224d 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -529,23 +529,6 @@ namespace action_give_inventory
 		return acceptable;
 	}
 
-	static void build_residents_string(const std::vector<LLAvatarName> avatar_names, std::string& residents_string)
-	{
-		llassert(avatar_names.size() > 0);
-
-		const std::string& separator = LLTrans::getString("words_separator");
-		for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
-		{
-			LLAvatarName av_name = *it;
-			residents_string.append(av_name.mDisplayName);
-			if	(++it == avatar_names.end())
-			{
-				break;
-			}
-			residents_string.append(separator);
-		}
-	}
-
 	static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)
 	{
 		llassert(inventory_selected_uuids.size() > 0);
@@ -675,7 +658,7 @@ namespace action_give_inventory
 		}
 
 		std::string residents;
-		build_residents_string(avatar_names, residents);
+		LLAvatarActions::buildResidentsString(avatar_names, residents);
 
 		std::string items;
 		build_items_string(inventory_selected_uuids, items);
@@ -706,7 +689,23 @@ namespace action_give_inventory
 	}
 }
 
+// static
+void LLAvatarActions::buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string)
+{
+	llassert(avatar_names.size() > 0);
 
+	const std::string& separator = LLTrans::getString("words_separator");
+	for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
+	{
+		LLAvatarName av_name = *it;
+		residents_string.append(av_name.mDisplayName);
+		if	(++it == avatar_names.end())
+		{
+			break;
+		}
+		residents_string.append(separator);
+	}
+}
 
 //static
 std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 0a69ad86a3..46830eb22c 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -34,6 +34,7 @@
 #include <string>
 #include <vector>
 
+class LLAvatarName;
 class LLInventoryPanel;
 class LLFloater;
 
@@ -208,6 +209,14 @@ public:
 	 */
 	static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL);
 
+	/**
+	 * Builds a string of residents' display names separated by "words_separator" string.
+	 *
+	 * @param avatar_names - a vector of given avatar names from which resulting string is built
+	 * @param residents_string - the resulting string
+	 */
+	static void buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string);
+
 	static std::set<LLUUID> getInventorySelectedUUIDs();
 
 private:
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index d3f3e41a29..c734c3edd2 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -42,7 +42,6 @@ const F32 REFRESH_INTERVAL = 0.2f;
 
 LLIMConversation::LLIMConversation(const LLUUID& session_id)
   : LLTransientDockableFloater(NULL, true, session_id)
-  ,	LLEventTimer(REFRESH_INTERVAL)
   ,  mIsP2PChat(false)
   ,  mExpandCollapseBtn(NULL)
   ,  mTearOffBtn(NULL)
@@ -52,6 +51,7 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
+  , mRefreshTimer(new LLTimer())
 {
 	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
 			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2));
@@ -67,6 +67,10 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)
 			boost::bind(&LLIMConversation::onIMShowModesMenuItemCheck,   this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
 			boost::bind(&LLIMConversation::onIMShowModesMenuItemEnable,  this, _2));
+
+	// Zero expiry time is set only once to allow initial update.
+	mRefreshTimer->setTimerExpirySec(0);
+	mRefreshTimer->start();
 }
 
 LLIMConversation::~LLIMConversation()
@@ -76,6 +80,8 @@ LLIMConversation::~LLIMConversation()
 		delete mParticipantList;
 		mParticipantList = NULL;
 	}
+
+	delete mRefreshTimer;
 }
 
 BOOL LLIMConversation::postBuild()
@@ -120,19 +126,22 @@ BOOL LLIMConversation::postBuild()
 
 }
 
-BOOL LLIMConversation::tick()
+void LLIMConversation::draw()
 {
-	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater
-	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy().
-	if (isDead()) return false;
+	LLTransientDockableFloater::draw();
 
-	// Need to resort the participant list if it's in sort by recent speaker order.
-	if (mParticipantList)
+	if (mRefreshTimer->hasExpired())
 	{
-		mParticipantList->update();
-	}
+		if (mParticipantList)
+		{
+			mParticipantList->update();
+		}
 
-	return false;
+		refresh();
+
+		// Restart the refresh timer
+		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
+	}
 }
 
 void LLIMConversation::buildParticipantList()
@@ -144,10 +153,11 @@ void LLIMConversation::buildParticipantList()
 	}
 	else
 	{
+		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
 		// for group and ad-hoc chat we need to include agent into list
-		if(!mIsP2PChat && !mParticipantList && mSessionID.notNull())
+		if(!mIsP2PChat && mSessionID.notNull() && speaker_manager)
 		{
-			LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+			delete mParticipantList; // remove the old list and create a new one if the session id has changed
 			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);
 		}
 	}
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 47c98d6f8b..50663137ac 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -40,7 +40,6 @@ class LLChatHistory;
 
 class LLIMConversation
 	: public LLTransientDockableFloater
-	, public LLEventTimer
 {
 
 public:
@@ -65,6 +64,7 @@ public:
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void draw();
 
 protected:
 
@@ -89,8 +89,6 @@ protected:
 	void buildParticipantList();
 	void onSortMenuItemClicked(const LLSD& userdata);
 
-	/*virtual*/ BOOL tick();
-
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
 
@@ -103,6 +101,9 @@ protected:
 	LLButton* mCloseBtn;
 
 private:
+	/// Refreshes the floater at a constant rate.
+	virtual void refresh() = 0;
+
 	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
 	void updateHeaderAndToolbar();
 
@@ -113,10 +114,11 @@ private:
 	 */
 	void reshapeChatHistory();
 
-
 	LLChatHistory* mChatHistory;
 	LLChatEntry* mInputEditor;
 	int mInputEditorTopPad; // padding between input field and chat history
+
+	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
 };
 
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 9ea4bec069..6a5bf153d4 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -105,6 +105,18 @@ void LLIMFloater::onFocusReceived()
 	}
 }
 
+// virtual
+void LLIMFloater::refresh()
+{
+	if (mMeTyping)
+	{
+		// Time out if user hasn't typed for a while.
+		if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS)
+		{
+			setTyping(false);
+		}
+	}
+}
 
 /* static */
 void LLIMFloater::newIMCallback(const LLSD& data)
@@ -188,6 +200,7 @@ void LLIMFloater::sendMsg()
 
 LLIMFloater::~LLIMFloater()
 {
+	mParticipantsListRefreshConnection.disconnect();
 	mVoiceChannelStateChangeConnection.disconnect();
 	if(LLVoiceClient::instanceExists())
 	{
@@ -225,6 +238,8 @@ void LLIMFloater::initIMFloater()
 
 	boundVoiceChannel();
 
+	mTypingStart = LLTrans::getString("IM_typing_start_string");
+
 	// Show control panel in torn off floaters only.
 	mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel"));
 
@@ -246,6 +261,20 @@ void LLIMFloater::initIMFloater()
 	{
 		std::string session_name(LLIMModel::instance().getName(mSessionID));
 		updateSessionName(session_name, session_name);
+
+		// For ad hoc conferences we should update the title with participants names.
+		if ((IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
+						|| mDialog == IM_SESSION_CONFERENCE_START)
+		{
+			if (mParticipantsListRefreshConnection.connected())
+			{
+				mParticipantsListRefreshConnection.disconnect();
+			}
+
+			LLAvatarList* avatar_list = getChild<LLAvatarList>("speakers_list");
+			mParticipantsListRefreshConnection = avatar_list->setRefreshCompleteCallback(
+					boost::bind(&LLIMFloater::onParticipantsListChanged, this, _1));
+		}
 	}
 }
 
@@ -273,8 +302,6 @@ BOOL LLIMFloater::postBuild()
 
 	setDocked(true);
 
-	mTypingStart = LLTrans::getString("IM_typing_start_string");
-
 	LLButton* add_btn = getChild<LLButton>("add_btn");
 
 	// Allow to add chat participants depending on the session type
@@ -341,7 +368,9 @@ bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
        for (uuid_vec_t::const_iterator id = uuids.begin();
                        id != uuids.end(); ++id)
        {
-               if (*id == mOtherParticipantUUID)
+    	   	   // Skip this check for ad hoc conferences,
+    	       // conference participants should be listed in mSession->mInitialTargetIDs.
+               if (mIsP2PChat && *id == mOtherParticipantUUID)
                {
                        return false;
                }
@@ -411,11 +440,6 @@ void LLIMFloater::onCallButtonClicked()
 	}
 }
 
-/*void LLIMFloater::onOpenVoiceControlsClicked()
-{
-	LLFloaterReg::showInstance("voice_controls");
-}*/
-
 void LLIMFloater::onChange(EStatusType status, const std::string &channelURI, bool proximal)
 {
 	if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL)
@@ -448,28 +472,55 @@ void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
 	mTypingStart.setArg("[NAME]", ui_title);
 }
 
-// virtual
-BOOL LLIMFloater::tick()
+void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 {
-	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater
-	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy().
-	if (isDead())
+	LLAvatarList* avatar_list = dynamic_cast<LLAvatarList*>(ctrl);
+	if (!avatar_list)
 	{
-		return false;
+		return;
 	}
 
-	BOOL parents_retcode = LLIMConversation::tick();
+	bool all_names_resolved = true;
+	std::vector<LLSD> participants_uuids;
 
-	if ( mMeTyping )
+	avatar_list->getValues(participants_uuids);
+
+	// Check whether we have all participants names in LLAvatarNameCache
+	for (std::vector<LLSD>::const_iterator it = participants_uuids.begin(); it != participants_uuids.end(); ++it)
 	{
-		// Time out if user hasn't typed for a while.
-		if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS )
+		const LLUUID& id = it->asUUID();
+		LLAvatarName av_name;
+		if (!LLAvatarNameCache::get(id, &av_name))
 		{
-			setTyping(false);
+			all_names_resolved = false;
+
+			// If a name is not found in cache, request it and continue the process recursively
+			// until all ids are resolved into names.
+			LLAvatarNameCache::get(id,
+					boost::bind(&LLIMFloater::onParticipantsListChanged, this, avatar_list));
+			break;
 		}
 	}
 
-	return parents_retcode;
+	if (all_names_resolved)
+	{
+		std::vector<LLAvatarName> avatar_names;
+		std::vector<LLSD>::const_iterator it = participants_uuids.begin();
+		for (; it != participants_uuids.end(); ++it)
+		{
+			const LLUUID& id = it->asUUID();
+			LLAvatarName av_name;
+			if (LLAvatarNameCache::get(id, &av_name))
+			{
+				avatar_names.push_back(av_name);
+			}
+		}
+
+		std::string ui_title;
+		LLAvatarActions::buildResidentsString(avatar_names, ui_title);
+
+		updateSessionName(ui_title, ui_title);
+	}
 }
 
 //static
@@ -737,8 +788,6 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	{
 		initIMSession(im_session_id);
 
-		boundVoiceChannel();
-
 		buildParticipantList();
 	}
 
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 6847efedf1..23f9e75e21 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -66,7 +66,6 @@ public:
 	/*virtual*/ void setVisible(BOOL visible);
 	/*virtual*/ BOOL getVisible();
 	// Check typing timeout timer.
-	/*virtual*/ BOOL tick();
 
 	static LLIMFloater* findInstance(const LLUUID& session_id);
 	static LLIMFloater* getInstance(const LLUUID& session_id);
@@ -131,12 +130,18 @@ private:
 	/* virtual */ void onFocusLost();
 	/* virtual */ void onFocusReceived();
 
+	/*virtual*/ void refresh();
+
 	// Update the window title, input field help text, etc.
 	void updateSessionName(const std::string& ui_title, const std::string& ui_label);
 
 	// For display name lookups for IM window titles
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
 
+	/// Updates the list of ad hoc conference participants
+	/// in an IM floater title.
+	void onParticipantsListChanged(LLUICtrl* ctrl);
+
 	bool dropPerson(LLUUID* person_id, bool drop);
 
 	BOOL isInviteAllowed() const;
@@ -193,6 +198,8 @@ private:
 
 	// connection to voice channel state change signal
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
+
+	boost::signals2::connection mParticipantsListRefreshConnection;
 };
 
 #endif  // LL_IMFLOATER_H
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 29ab4384cb..369ca699c5 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -186,6 +186,21 @@ BOOL LLNearbyChat::postBuild()
 	return LLIMConversation::postBuild();
 }
 
+// virtual
+void LLNearbyChat::refresh()
+{
+	displaySpeakingIndicator();
+	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
+
+	// *HACK: Update transparency type depending on whether our children have focus.
+	// This is needed because this floater is chrome and thus cannot accept focus, so
+	// the transparency type setting code from LLFloater::setFocus() isn't reached.
+	if (getTransparencyType() != TT_DEFAULT)
+	{
+		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
+	}
+}
+
 void LLNearbyChat::onNearbySpeakers()
 {
 	LLSD param;
@@ -389,27 +404,6 @@ void LLNearbyChat::showHistory()
 	storeRectControl();
 }
 
-
-BOOL LLNearbyChat::tick()
-{
-	// This check is needed until LLFloaterReg::removeInstance() is synchronized with deleting the floater
-	// via LLMortician::updateClass(), to avoid calling dead instances. See LLFloater::destroy().
-	if (isDead()) return false;
-
-	displaySpeakingIndicator();
-	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
-
-	// *HACK: Update transparency type depending on whether our children have focus.
-	// This is needed because this floater is chrome and thus cannot accept focus, so
-	// the transparency type setting code from LLFloater::setFocus() isn't reached.
-	if (getTransparencyType() != TT_DEFAULT)
-	{
-		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
-	}
-
-	return LLIMConversation::tick();
-}
-
 std::string LLNearbyChat::getCurrentChat()
 {
 	return mChatBox ? mChatBox->getText() : LLStringUtil::null;
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index c9aa69a912..db367f0b59 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -73,8 +73,6 @@ public:
 
 	LLChatEntry* getChatBox() { return mChatBox; }
 
-	//virtual void draw();
-
 	std::string getCurrentChat();
 
 	virtual BOOL handleKeyHere( KEY key, MASK mask );
@@ -119,8 +117,6 @@ protected:
 
 	S32 mExpandedHeight;
 
-	/*virtual*/ BOOL tick();
-
 private:
 
 	void	getAllowedRect		(LLRect& rect);
@@ -128,6 +124,8 @@ private:
 	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	void	onNearbySpeakers	();
 
+	/*virtual*/ void refresh();
+
 	LLHandle<LLView>	mPopupMenuHandle;
 	std::vector<LLChat> mMessageArchive;
 	LLChatHistory*		mChatHistory;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 59d26edff2..47518a365f 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -475,6 +475,7 @@ void LLParticipantList::update()
 {
 	mSpeakerMgr->update(true);
 
+	// Need to resort the participant list if it's in sort by recent speaker order.
 	if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder() && !isHovered())
 	{
 		// Resort avatar list
-- 
cgit v1.2.3


From 3385a6398951bc94b3dc5da6224e285d85e606ab Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 27 Jun 2012 16:11:04 +0300
Subject: CHUI-162 FIXED Opening a nearby chat when text entered

---
 indra/newview/llnearbychat.cpp | 22 ++++++++++++++++++++++
 indra/newview/llnearbychat.h   |  1 +
 2 files changed, 23 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 369ca699c5..ee7169b1c3 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -131,6 +131,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key)
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
 {
+	setIsChrome(TRUE);
 	mKey = LLSD();
 	mIsNearbyChat = true;
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
@@ -394,6 +395,26 @@ LLNearbyChat* LLNearbyChat::getInstance()
 	return LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar");
 }
 
+void LLNearbyChat::show()
+{
+	// Get the floater
+	LLNearbyChat* floater = LLNearbyChat::getInstance();
+	if (floater)
+	{
+		if(isChatMultiTab())
+		{
+			LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
+
+			// Add a conversation list item in the left pane: nothing will be done if already in there
+			// but relevant clean up will be done to ensure consistency of the conversation list
+			floater_container->addConversationListItem(floater->getTitle(), LLUUID(), floater);
+
+			floater->openFloater(floater->getKey());
+		}
+
+		floater->setVisible(TRUE);
+	}
+}
 
 void LLNearbyChat::showHistory()
 {
@@ -773,6 +794,7 @@ void LLNearbyChat::startChat(const char* line)
 
 	if (cb )
 	{
+		cb->show();
 		cb->setVisible(TRUE);
 		cb->setFocus(TRUE);
 		cb->mChatBox->setFocus(TRUE);
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index db367f0b59..61404df942 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -65,6 +65,7 @@ public:
 	static LLNearbyChat* getInstance();
 
 	void addToHost();
+	void show();
 
 	/** @param archive true - to save a message to the chat history log */
 	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());
-- 
cgit v1.2.3


From 9091986c698af6d008a12f1944724609d649b63e Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Wed, 27 Jun 2012 19:33:22 +0300
Subject: CHUI-147 FIX Added check against empty participants names array to
 pass the assertion in LLAvatarActions::buildResidentsString.

---
 indra/newview/llimfloater.cpp | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 6a5bf153d4..1bbf6cc320 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -516,10 +516,14 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 			}
 		}
 
-		std::string ui_title;
-		LLAvatarActions::buildResidentsString(avatar_names, ui_title);
-
-		updateSessionName(ui_title, ui_title);
+		// We should check whether the vector is not empty to pass the assertion
+		// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
+		if (!avatar_names.empty())
+		{
+			std::string ui_title;
+			LLAvatarActions::buildResidentsString(avatar_names, ui_title);
+			updateSessionName(ui_title, ui_title);
+		}
 	}
 }
 
-- 
cgit v1.2.3


From 0eda1f9a4d909870b15c6d7243e47838540598e8 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Wed, 27 Jun 2012 19:33:27 +0300
Subject: CHUI-169 FIX Restored inventory sharing functionality via IM floater
 drag and drop.

---
 indra/newview/llimfloater.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 1bbf6cc320..b94a4048d4 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -1077,6 +1077,12 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 			*accept = ACCEPT_NO;
 		}
 	}
+	else if (mDialog == IM_NOTHING_SPECIAL)
+	{
+		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
+				cargo_type, cargo_data, accept);
+	}
+
 	return TRUE;
 }
 
-- 
cgit v1.2.3


From 0e316a1510d5051088a62b86e4b0e05702786d9a Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 27 Jun 2012 21:30:05 +0300
Subject: CHUI-125 FIXED Supressed of a commented out code

---
 indra/newview/llchicletbar.cpp | 13 -------------
 1 file changed, 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index 0e58008cd2..39f5d0b8f6 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -57,24 +57,11 @@ LLChicletBar::LLChicletBar(const LLSD&)
 :	mChicletPanel(NULL),
 	mToolbarStack(NULL)
 {
-	// IM floaters are from now managed by LLIMFloaterContainer.
-	// See LLIMFloaterContainer::sessionVoiceOrIMStarted() and CHUI-125
-
-//	// Firstly add our self to IMSession observers, so we catch session events
-//	// before chiclets do that.
-//	LLIMMgr::getInstance()->addSessionObserver(this);
-
 	buildFromFile("panel_chiclet_bar.xml");
 }
 
 LLChicletBar::~LLChicletBar()
 {
-	// IM floaters are from now managed by LLIMFloaterContainer.
-	// See LLIMFloaterContainer::sessionVoiceOrIMStarted() and CHUI-125
-//	if (!LLSingleton<LLIMMgr>::destroyed())
-//	{
-//		LLIMMgr::getInstance()->removeSessionObserver(this);
-//	}
 }
 
 LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id)
-- 
cgit v1.2.3


From 1eb6b4509d9ae79f8313e1e68351028794093a53 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 27 Jun 2012 14:03:16 -0700
Subject: CHUI-139 : Make sure the Nearby Chat shows up in the conversations
 floater in every situation

---
 indra/newview/llimfloatercontainer.cpp | 31 ++++++++++++++-----------------
 1 file changed, 14 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index f6bcf8bbe9..52bacf15e4 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -103,24 +103,7 @@ BOOL LLIMFloaterContainer::postBuild()
 
 void LLIMFloaterContainer::onOpen(const LLSD& key)
 {
-	if (getFloaterCount() == 0)
-	{
-		// We always force the opening of the nearby chat conversation when we open for the first  time
-		// *TODO: find a way to move this to XML as a default panel or something like that
-		LLSD name("chat_bar");
-		LLFloaterReg::toggleInstanceOrBringToFront(name);
-	}
 	LLMultiFloater::onOpen(key);
-	/*
-	if (key.isDefined())
-	{
-		LLIMFloater* im_floater = LLIMFloater::findInstance(key.asUUID());
-		if (im_floater)
-		{
-			im_floater->openFloater();
-		}
-	}
-	 */
 }
 
 // virtual
@@ -307,6 +290,20 @@ void LLIMFloaterContainer::tabClose()
 
 void LLIMFloaterContainer::setVisible(BOOL visible)
 {
+	if (visible)
+	{
+		// Make sure we have the Nearby Chat present when showing the conversation container
+		LLUUID nearbychat_uuid = LLUUID::null;	// Hacky but true: the session id for nearby chat is null
+		conversations_items_map::iterator item_it = mConversationsItems.find(nearbychat_uuid);
+		if (item_it == mConversationsItems.end())
+		{
+			// If not found, force the creation of the nearby chat conversation panel
+			// *TODO: find a way to move this to XML as a default panel or something like that
+			LLSD name("chat_bar");
+			LLFloaterReg::toggleInstanceOrBringToFront(name);
+		}
+	}
+	
 	// We need to show/hide all the associated conversations that have been torn off
 	// (and therefore, are not longer managed by the multifloater),
 	// so that they show/hide with the conversations manager.
-- 
cgit v1.2.3


From d470632799dfdea723d15d91aa5783bdd1700257 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 27 Jun 2012 15:32:08 -0700
Subject: CHUI-130 : Leave minimized torn off IM untouched when showing hiding
 the whole set of conversations

---
 indra/newview/llimfloatercontainer.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 52bacf15e4..34a9758c52 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -556,8 +556,9 @@ void LLConversationItem::selectItem(void)
 
 void LLConversationItem::setVisibleIfDetached(BOOL visible)
 {
-	// Do this only if the conversation floater has been torn off (i.e. no multi floater host)
-	if (!mFloater->getHost())
+	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
+	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
+	if (!mFloater->getHost() && !mFloater->isMinimized())
 	{
 		mFloater->setVisible(visible);    
 	}
-- 
cgit v1.2.3


From c9da4d0a6dccbdcff228a5841d224463bc45297c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 27 Jun 2012 15:55:09 -0700
Subject: CHUI-162 : Simplified the nearby chat show method following CHUI-139
 fixes

---
 indra/newview/llnearbychat.cpp | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index ee7169b1c3..a81d6b4025 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -397,23 +397,11 @@ LLNearbyChat* LLNearbyChat::getInstance()
 
 void LLNearbyChat::show()
 {
-	// Get the floater
-	LLNearbyChat* floater = LLNearbyChat::getInstance();
-	if (floater)
+	if (isChatMultiTab())
 	{
-		if(isChatMultiTab())
-		{
-			LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
-
-			// Add a conversation list item in the left pane: nothing will be done if already in there
-			// but relevant clean up will be done to ensure consistency of the conversation list
-			floater_container->addConversationListItem(floater->getTitle(), LLUUID(), floater);
-
-			floater->openFloater(floater->getKey());
-		}
-
-		floater->setVisible(TRUE);
+		openFloater(getKey());
 	}
+	setVisible(TRUE);
 }
 
 void LLNearbyChat::showHistory()
-- 
cgit v1.2.3


From 7a147c1de99a7d03008d2921f091aa3de03a559f Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 27 Jun 2012 17:08:19 -0700
Subject: CHUI-146 : Fixed. Focus goes to first conversation in list when a
 conversation is dismissed.

---
 indra/newview/llimfloater.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index b94a4048d4..9d3c0f98ce 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -628,9 +628,6 @@ LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
 
 void LLIMFloater::onClose(bool app_quitting)
 {
-	LLIMConversation::onClose(app_quitting);
-
-
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
 				mSessionID);
 
@@ -663,6 +660,8 @@ void LLIMFloater::onClose(bool app_quitting)
 	// EXT-3516 X Button should end IM session, _ button should hide
 	gIMMgr->leaveSession(mSessionID);
 
+	// Clean up the conversation *after* the session has been ended
+	LLIMConversation::onClose(app_quitting);
 }
 
 void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
-- 
cgit v1.2.3


From cbe3c3ae95c0850cd0ecba893ddabe0200bbc0ac Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 27 Jun 2012 17:16:15 -0700
Subject: CHUI-184 : Change default pref LetterKeysFocusChatBar from 1 (chat)
 to 0 (WASD movements)

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index fe6829a712..4a586b02af 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1538,7 +1538,7 @@
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
-      <integer>1</integer>
+      <integer>0</integer>
     </map>
     <key>ChatBubbleOpacity</key>
     <map>
-- 
cgit v1.2.3


From cb865a7e1300d4ce0bedae7c856fb210b68a43f8 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 27 Jun 2012 18:56:10 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose moved filtering logic
 to viewmodel

---
 indra/llui/llnotifications.cpp           |  24 +-
 indra/newview/llfolderview.cpp           | 106 ++---
 indra/newview/llfolderview.h             |  12 +-
 indra/newview/llfolderviewitem.cpp       | 787 +++++++------------------------
 indra/newview/llfolderviewitem.h         |  82 +---
 indra/newview/llfolderviewmodel.h        | 194 ++++----
 indra/newview/llinventorybridge.cpp      |  20 +-
 indra/newview/llinventorybridge.h        |   3 +
 indra/newview/llinventoryfilter.cpp      |  97 ++--
 indra/newview/llinventoryfilter.h        |  20 +-
 indra/newview/llinventoryfunctions.cpp   |  10 +-
 indra/newview/llinventorypanel.cpp       | 128 ++++-
 indra/newview/llinventorypanel.h         |   6 +
 indra/newview/llpanellandmarks.cpp       |   2 +-
 indra/newview/llpanelmaininventory.cpp   |   2 +-
 indra/newview/llpanelobjectinventory.cpp |  11 +
 indra/newview/llsidepanelappearance.cpp  |   2 +-
 indra/newview/lltexturectrl.cpp          |  10 +-
 18 files changed, 557 insertions(+), 959 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 487a2e5fe7..48128e0b40 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1542,34 +1542,32 @@ void LLNotifications::addFromCallback(const LLSD& name)
 	add(name.asString(), LLSD(), LLSD());
 }
 
-LLNotificationPtr LLNotifications::add(const std::string& name, 
-									   const LLSD& substitutions, 
-									   const LLSD& payload)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload)
 {
 	LLNotification::Params::Functor functor_p;
 	functor_p.name = name;
 	return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));	
 }
 
-LLNotificationPtr LLNotifications::add(const std::string& name, 
-									   const LLSD& substitutions, 
-									   const LLSD& payload, 
-									   const std::string& functor_name)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload, const std::string& functor_name)
 {
 	LLNotification::Params::Functor functor_p;
 	functor_p.name = functor_name;
-	return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));	
+	return add(LLNotification::Params().name(name)
+										.substitutions(substitutions)
+										.payload(payload)
+										.functor(functor_p));	
 }
 							  
 //virtual
-LLNotificationPtr LLNotifications::add(const std::string& name, 
-										const LLSD& substitutions, 
-										const LLSD& payload, 
-										LLNotificationFunctorRegistry::ResponseFunctor functor)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload, LLNotificationFunctorRegistry::ResponseFunctor functor)
 {
 	LLNotification::Params::Functor functor_p;
 	functor_p.function = functor;
-	return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));	
+	return add(LLNotification::Params().name(name)
+										.substitutions(substitutions)
+										.payload(payload)
+										.functor(functor_p));	
 }
 
 // generalized add function that takes a parameter block object for more complex instantiations
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index ee8c94a2dd..a37fc7714b 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -181,7 +181,6 @@ LLFolderView::LLFolderView(const Params& p)
 	mNeedsAutoSelect( FALSE ),
 	mAutoSelectOverride(FALSE),
 	mNeedsAutoRename(FALSE),
-	mDebugFilters(FALSE),
 	mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME),	// This gets overridden by a pref immediately
 	mFilter(new LLInventoryFilter(LLInventoryFilter::Params().name(p.title))),
 	mShowSelectionContext(FALSE),
@@ -316,7 +315,7 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 	folder->reshape(getRect().getWidth(), 0);
 	folder->setVisible(FALSE);
 	addChild( folder );
-	folder->dirtyFilter();
+	folder->getViewModelItem()->dirtyFilter();
 	folder->requestArrange();
 	return TRUE;
 }
@@ -339,15 +338,14 @@ void LLFolderView::openTopLevelFolders()
 }
 
 // This view grows and shrinks to enclose all of its children items and folders.
-// mItemHeight = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0;
 // *width should be 0
 // conform show folder state works
-S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )
+S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
 {
 	mMinWidth = 0;
 	S32 target_height;
 
-	LLFolderViewFolder::arrange(&mMinWidth, &target_height, mFilter->getFirstSuccessGeneration());
+	LLFolderViewFolder::arrange(&mMinWidth, &target_height);
 
 	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
 	reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
@@ -371,15 +369,10 @@ void LLFolderView::filter( LLFolderViewFilter& filter )
 	LLFastTimer t2(FTM_FILTER);
 	filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
 
-	if (getCompletedFilterGeneration() < filter.getCurrentGeneration())
+	if (getLastFilterGeneration() < filter.getCurrentGeneration())
 	{
-		mPassedFilter = FALSE;
 		mMinWidth = 0;
-		LLFolderViewFolder::filter(filter);
-	}
-	else
-	{
-		mPassedFilter = TRUE;
+		getViewModelItem()->filter(filter);
 	}
 }
 
@@ -548,15 +541,15 @@ void LLFolderView::sanitizeSelection()
 		LLFolderViewItem* item = *item_iter;
 
 		// ensure that each ancestor is open and potentially passes filtering
-		BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item
+		BOOL visible = item->getViewModelItem()->potentiallyVisible(); // initialize from filter state for this item
 		// modify with parent open and filters states
 		LLFolderViewFolder* parent_folder = item->getParentFolder();
 		// Move up through parent folders and see what's visible
-				while(parent_folder)
-				{
-					visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();
-					parent_folder = parent_folder->getParentFolder();
-				}
+		while(parent_folder)
+		{
+			visible = visible && parent_folder->isOpen() && parent_folder->getViewModelItem()->potentiallyVisible();
+			parent_folder = parent_folder->getParentFolder();
+		}
 
 		//  deselect item if any ancestor is closed or didn't pass filter requirements.
 		if (!visible)
@@ -606,7 +599,7 @@ void LLFolderView::sanitizeSelection()
 				parent_folder;
 				parent_folder = parent_folder->getParentFolder())
 			{
-				if (parent_folder->potentiallyVisible())
+				if (parent_folder->getViewModelItem()->potentiallyVisible())
 				{
 					// give initial selection to first ancestor folder that potentially passes the filter
 					if (!new_selection)
@@ -684,16 +677,6 @@ void LLFolderView::commitRename( const LLSD& data )
 
 void LLFolderView::draw()
 {
-	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", LLColor4::white);
-	if (mDebugFilters)
-	{
-		std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d",
-										mFilter->getCurrentGeneration(), mFilter->getFirstSuccessGeneration(), mFilter->getFirstRequiredGeneration());
-		LLFontGL::getFontMonospace()->renderUTF8(current_filter_string, 0, 2, 
-			getRect().getHeight() - LLFontGL::getFontMonospace()->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), 
-			LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
-	}
-
 	//LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
 	// if cursor has moved off of me during drag and drop
@@ -734,17 +717,14 @@ void LLFolderView::draw()
 	}
 	else if (mShowEmptyMessage)
 	{
-		if (!mViewModel->contentsReady() || mCompletedFilterGeneration < mFilter->getFirstSuccessGeneration())
+		if (!mViewModel->contentsReady() || getLastFilterGeneration() < mFilter->getFirstSuccessGeneration())
 		{
 			// TODO RN: Get this from filter
 			mStatusText = LLTrans::getString("Searching");
 		}
 		else
 		{
-			if (getFilter())
-			{
-				mStatusText = getFilter()->getEmptyLookupMessage();
-			}
+			mStatusText = getFolderViewModel()->getFilter()->getEmptyLookupMessage();
 		}
 		mStatusTextBox->setValue(mStatusText);
 		mStatusTextBox->setVisible( TRUE );
@@ -763,7 +743,11 @@ void LLFolderView::draw()
 			// This will indirectly call ::arrange and reshape of the status textbox.
 			// We should call this method to also notify parent about required rect.
 			// See EXT-7564, EXT-7047.
-			arrangeFromRoot();
+			S32 height = 0;
+			S32 width = 0;
+			S32 total_height = arrange( &width, &height );
+			notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
+
 			LLUI::popMatrix();
 			LLUI::pushMatrix();
 			LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
@@ -902,16 +886,16 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 			}
 			if(parent)
 			{
-				if (parent->removeItem(item_to_delete))
+				if (item_to_delete->remove())
 				{
 					// change selection on successful delete
 					if (new_selection)
 					{
-						setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
+						getRoot()->setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
 					}
 					else
 					{
-						setSelectionFromRoot(NULL, mParentPanel->hasFocus());
+						getRoot()->setSelection(NULL, mParentPanel->hasFocus());
 					}
 				}
 			}
@@ -937,11 +921,11 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 			}
 			if (new_selection)
 			{
-				setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
+				getRoot()->setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
 			}
 			else
 			{
-				setSelectionFromRoot(NULL, mParentPanel->hasFocus());
+				getRoot()->setSelection(NULL, mParentPanel->hasFocus());
 			}
 
 			for(S32 i = 0; i < count; ++i)
@@ -1386,12 +1370,12 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 					if (next->isSelected())
 					{
 						// shrink selection
-						changeSelectionFromRoot(last_selected, FALSE);
+						getRoot()->changeSelection(last_selected, FALSE);
 					}
 					else if (last_selected->getParentFolder() == next->getParentFolder())
 					{
 						// grow selection
-						changeSelectionFromRoot(next, TRUE);
+						getRoot()->changeSelection(next, TRUE);
 					}
 				}
 			}
@@ -1450,12 +1434,12 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 					if (prev->isSelected())
 					{
 						// shrink selection
-						changeSelectionFromRoot(last_selected, FALSE);
+						getRoot()->changeSelection(last_selected, FALSE);
 					}
 					else if (last_selected->getParentFolder() == prev->getParentFolder())
 					{
 						// grow selection
-						changeSelectionFromRoot(prev, TRUE);
+						getRoot()->changeSelection(prev, TRUE);
 					}
 				}
 			}
@@ -1649,7 +1633,7 @@ BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &searc
 			}
 		}
 
-		const std::string current_item_label(search_item->getSearchableLabel());
+		const std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
 		S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
 		if (!current_item_label.compare(0, search_string_length, upper_case_string))
 		{
@@ -1959,13 +1943,6 @@ void LLFolderView::doIdle()
 	
 	LLFastTimer t2(FTM_INVENTORY);
 
-	BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters");
-	if (debug_filters != getDebugFilters())
-	{
-		mDebugFilters = debug_filters;
-		arrangeAll();
-	}
-
 	if (mFilter->isModified() && mFilter->isNotDefault())
 	{
 		mNeedsAutoSelect = TRUE;
@@ -1973,7 +1950,7 @@ void LLFolderView::doIdle()
 	mFilter->clearModified();
 
 	// filter to determine visibility before arranging
-	filterFromRoot();
+	filter(*(getFolderViewModel()->getFilter()));
 
 	// automatically show matching items, and select first one if we had a selection
 	if (mNeedsAutoSelect)
@@ -1981,7 +1958,7 @@ void LLFolderView::doIdle()
 		LLFastTimer t3(FTM_AUTO_SELECT);
 		// select new item only if a filtered item not currently selected
 		LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
-		if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->potentiallyHidden()))
+		if (!mAutoSelectOverride && (!selected_itemp || selected_itemp->passedFilter()))
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
@@ -1991,7 +1968,7 @@ void LLFolderView::doIdle()
 
 		// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
 		// Used by LLPlacesFolderView.
-		if (mAutoSelectOverride && mFilter->showAllResults())
+		if (mFilter->showAllResults())
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
@@ -2002,7 +1979,7 @@ void LLFolderView::doIdle()
 		scrollToShowSelection();
 	}
 
-	BOOL filter_finished = mCompletedFilterGeneration >= mFilter->getCurrentGeneration() 
+	BOOL filter_finished = getLastFilterGeneration() >= mFilter->getCurrentGeneration() 
 						&& mViewModel->contentsReady();
 	if (filter_finished 
 		|| gFocusMgr.childHasKeyboardFocus(inventory_panel) 
@@ -2073,7 +2050,10 @@ void LLFolderView::doIdle()
 		sanitizeSelection();
 		if( needsArrange() )
 		{
-			arrangeFromRoot();
+			S32 height = 0;
+			S32 width = 0;
+			S32 total_height = arrange( &width, &height );
+			notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
 		}
 	}
 
@@ -2278,25 +2258,19 @@ void LLFolderView::onRenamerLost()
 
 	if( mRenameItem )
 	{
-		setSelectionFromRoot( mRenameItem, TRUE );
+		setSelection( mRenameItem, TRUE );
 		mRenameItem = NULL;
 	}
 }
 
-LLFolderViewFilter* LLFolderView::getFilter()
-{
-	return mFilter;
-}
-
 S32 LLFolderView::getItemHeight()
 {
-	S32 debug_height = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0;
 	if(!hasVisibleChildren())
 	{
 		//We need to display status textbox, let's reserve some place for it
-		return llmax(debug_height, mStatusTextBox->getTextPixelHeight());
+		return llmax(0, mStatusTextBox->getTextPixelHeight());
 	}
-	return debug_height;
+	return 0;
 }
 
 //TODO RN: move to llfolderviewmodel.cpp file
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 8b58da9f45..d261a5967d 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -110,9 +110,11 @@ public:
 
 	virtual BOOL canFocusChildren() const;
 
+	virtual const LLFolderView*	getRoot() const { return this; }
 	virtual LLFolderView*	getRoot() { return this; }
 
 	LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; }
+	const LLFolderViewModelInterface* getFolderViewModel() const { return mViewModel; }
 
 	void setFilterPermMask(PermissionMask filter_perm_mask);
 	
@@ -120,9 +122,6 @@ public:
 	void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
 	void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
 	
-	// filter is never null
-	LLFolderViewFilter* getFilter();
-
 	bool getAllowMultiSelect() { return mAllowMultiSelect; }
 
 	// Close all folders in the view
@@ -133,7 +132,7 @@ public:
 
 	// Find width and height of this object and its children. Also
 	// makes sure that this view and its children are the right size.
-	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+	virtual S32 arrange( S32* width, S32* height );
 	virtual S32 getItemHeight();
 
 	void arrangeAll() { mArrangeGeneration++; }
@@ -147,7 +146,7 @@ public:
 
 	// Record the selected item and pass it down the hierarchy.
 	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
-		BOOL take_keyboard_focus);
+		BOOL take_keyboard_focus = TRUE);
 
 	// This method is used to toggle the selection of an item. Walks
 	// children, and keeps track of selected objects.
@@ -244,8 +243,6 @@ public:
 
 	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
 
-	BOOL getDebugFilters() { return mDebugFilters; }
-
 	LLPanel* getParentPanel() { return mParentPanel; }
 	// DEBUG only
 	void dumpSelectionInformation();
@@ -299,7 +296,6 @@ protected:
 	bool							mUseLabelSuffix;
 	bool							mShowItemLinkOverlays;
 	
-	BOOL							mDebugFilters;
 	U32								mSortOrder;
 	LLDepthStack<LLFolderViewFolder>	mAutoOpenItems;
 	LLFolderViewFolder*				mAutoOpenCandidate;
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 3f0b493986..f65a13be1e 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -114,8 +114,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mHasVisibleChildren(FALSE),
 	mIndentation(0),
 	mItemHeight(p.item_height),
-	mPassedFilter(FALSE),
-	mLastFilterGeneration(-1),
 	//TODO RN: create interface for string highlighting
 	//mStringMatchOffset(std::string::npos),
 	mControlLabelRotation(0.f),
@@ -146,6 +144,10 @@ LLFolderView* LLFolderViewItem::getRoot()
 	return mRoot;
 }
 
+const LLFolderView* LLFolderViewItem::getRoot() const
+{
+	return mRoot;
+}
 // Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
 BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
 {
@@ -207,99 +209,47 @@ LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
 	return itemp;
 }
 
-// is this item something we think we should be showing?
-// for example, if we haven't gotten around to filtering it yet, then the answer is yes
-// until we find out otherwise
-BOOL LLFolderViewItem::potentiallyVisible()
-{
-	return getFiltered() // we've passed the filter
-		||	getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration(); // or we don't know yet
-}
-
-BOOL LLFolderViewItem::potentiallyHidden()
+BOOL LLFolderViewItem::passedFilter(S32 filter_generation) 
 {
-	return !mPassedFilter // didn't pass the filter
-		|| getLastFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration(); // or we don't know yet
-}
-
-BOOL LLFolderViewItem::getFiltered() 
-{ 
-	return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
-}
-
-BOOL LLFolderViewItem::getFiltered(S32 filter_generation) 
-{
-	return mPassedFilter && mLastFilterGeneration >= filter_generation;
-}
-
-void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation)
-{
-	mPassedFilter = filtered;
-	mLastFilterGeneration = filter_generation;
+	return getViewModelItem()->passedFilter(filter_generation);
 }
 
 void LLFolderViewItem::refresh()
 {
-	if(!getViewModelItem()) return;
+	LLFolderViewModelItem& vmi = *getViewModelItem();
 
-	mLabel = getViewModelItem()->getDisplayName();
+	mLabel = vmi.getDisplayName();
 
 	setToolTip(mLabel);
-	mIcon = getViewModelItem()->getIcon();
-	mIconOpen = getViewModelItem()->getIconOpen();
-	mIconOverlay = getViewModelItem()->getIconOverlay();
+	mIcon = vmi.getIcon();
+	mIconOpen = vmi.getIconOpen();
+	mIconOverlay = vmi.getIconOverlay();
 
 	if (mRoot->useLabelSuffix())
 	{
-		mLabelStyle = getViewModelItem()->getLabelStyle();
-		mLabelSuffix = getViewModelItem()->getLabelSuffix();
+		mLabelStyle = vmi.getLabelStyle();
+		mLabelSuffix = vmi.getLabelSuffix();
 	}
 
-	std::string searchable_label(mLabel);
-	searchable_label.append(mLabelSuffix);
-	LLStringUtil::toUpper(searchable_label);
+	//TODO RN: make sure this logic still fires
+	//std::string searchable_label(mLabel);
+	//searchable_label.append(mLabelSuffix);
+	//LLStringUtil::toUpper(searchable_label);
 
-	if (mSearchableLabel.compare(searchable_label))
-	{
-		mSearchableLabel.assign(searchable_label);
-		dirtyFilter();
-		// some part of label has changed, so overall width has potentially changed, and sort order too
-		if (mParentFolder)
-		{
-			mParentFolder->requestSort();
-			mParentFolder->requestArrange();
-		}
-	}
+	//if (mSearchableLabel.compare(searchable_label))
+	//{
+	//	mSearchableLabel.assign(searchable_label);
+	//	vmi.dirtyFilter();
+	//	// some part of label has changed, so overall width has potentially changed, and sort order too
+	//	if (mParentFolder)
+	//	{
+	//		mParentFolder->requestSort();
+	//		mParentFolder->requestArrange();
+	//	}
+	//}
 
 	mLabelWidthDirty = true;
-	dirtyFilter();
-}
-
-// This function is called when items are added or view filters change. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::filterFromRoot( void )
-{
-	LLFolderViewItem* root = getRoot();
-
-	root->filter(*((LLFolderView*)root)->getFilter());
-}
-
-// This function is called when the folder view is dirty. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::arrangeFromRoot()
-{
-	LLFolderViewItem* root = getRoot();
-
-	S32 height = 0;
-	S32 width = 0;
-	S32 total_height = root->arrange( &width, &height, 0 );
-
-	LLSD params;
-	params["action"] = "size_changes";
-	params["height"] = total_height;
-	getParent()->notifyParent(params);
+	vmi.dirtyFilter();
 }
 
 // Utility function for LLFolderView
@@ -313,7 +263,7 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
 	}
 	if(set_selection)
 	{
-		setSelectionFromRoot(this, TRUE, take_keyboard_focus);
+		getRoot()->setSelection(this, TRUE, take_keyboard_focus);
 		if(root)
 		{
 			root->scrollToShowSelection();
@@ -321,22 +271,6 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
 	}		
 }
 
-// This function clears the currently selected item, and records the
-// specified selected item appropriately for display and use in the
-// UI. If open is TRUE, then folders are opened up along the way to
-// the selection.
-void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
-											BOOL openitem,
-											BOOL take_keyboard_focus)
-{
-	getRoot()->setSelection(selection, openitem, take_keyboard_focus);
-}
-
-// helper function to change the selection from the root.
-void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected)
-{
-	getRoot()->changeSelection(selection, selected);
-}
 
 std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const
 {
@@ -347,18 +281,13 @@ std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const
 // addToFolder() returns TRUE if it succeeds. FALSE otherwise
 BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 {
-	if (!folder)
-	{
-		return FALSE;
-	}
-	mParentFolder = folder;
 	return folder->addItem(this);
 }
 
 
 // Finds width and height of this object and its children.  Also
 // makes sure that this view and its children are the right size.
-S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
+S32 LLFolderViewItem::arrange( S32* width, S32* height )
 {
 	const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	S32 indentation = p.folder_indentation();
@@ -390,41 +319,6 @@ S32 LLFolderViewItem::getItemHeight()
 	return mItemHeight;
 }
 
-void LLFolderViewItem::filter( LLFolderViewFilter& filter)
-{
-	const BOOL previous_passed_filter = mPassedFilter;
-	const BOOL passed_filter = filter.check(this);
-
-	// If our visibility will change as a result of this filter, then
-	// we need to be rearranged in our parent folder
-	if (mParentFolder)
-	{
-		if (getVisible() != passed_filter
-			||	previous_passed_filter != passed_filter )
-			mParentFolder->requestArrange();
-	}
-
-	setFiltered(passed_filter, filter.getCurrentGeneration());
-	//TODO RN: create interface for string highlighting
-	//mStringMatchOffset = filter.getStringMatchOffset(this);
-	filter.decrementFilterCount();
-
-	if (getRoot()->getDebugFilters())
-	{
-		mStatusText = llformat("%d", mLastFilterGeneration);
-	}
-}
-
-void LLFolderViewItem::dirtyFilter()
-{
-	mLastFilterGeneration = -1;
-	// bubble up dirty flag all the way to root
-	if (getParentFolder())
-	{
-		getParentFolder()->setCompletedFilterGeneration(-1, TRUE);
-	}
-}
-
 // *TODO: This can be optimized a lot by simply recording that it is
 // selected in the appropriate places, and assuming that set selection
 // means 'deselect' for a leaf item. Do this optimization after
@@ -469,45 +363,31 @@ void LLFolderViewItem::selectItem(void)
 {
 	if (mIsSelected == FALSE)
 	{
-		if (getViewModelItem())
-		{
-			getViewModelItem()->selectItem();
-		}
+		getViewModelItem()->selectItem();
 		mIsSelected = TRUE;
 	}
 }
 
 BOOL LLFolderViewItem::isMovable()
 {
-	if( getViewModelItem() )
-	{
-		return getViewModelItem()->isItemMovable();
-	}
-	else
-	{
-		return TRUE;
-	}
+	return getViewModelItem()->isItemMovable();
 }
 
 BOOL LLFolderViewItem::isRemovable()
 {
-	if( getViewModelItem() )
-	{
-		return getViewModelItem()->isItemRemovable();
-	}
-	else
-	{
-		return TRUE;
-	}
+	return getViewModelItem()->isItemRemovable();
 }
 
 void LLFolderViewItem::destroyView()
 {
+	getRoot()->removeFromSelectionList(this);
+
 	if (mParentFolder)
 	{
 		// removeView deletes me
-		mParentFolder->removeView(this);
+		mParentFolder->extractItem(this);
 	}
+	delete this;
 }
 
 // Call through to the viewed object and return true if it can be
@@ -519,58 +399,36 @@ BOOL LLFolderViewItem::remove()
 	{
 		return FALSE;
 	}
-	if(getViewModelItem())
-	{
-		return getViewModelItem()->removeItem();
-	}
-	return TRUE;
+	return getViewModelItem()->removeItem();
 }
 
 // Build an appropriate context menu for the item.
 void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
-	if(getViewModelItem())
-	{
-		getViewModelItem()->buildContextMenu(menu, flags);
-	}
+	getViewModelItem()->buildContextMenu(menu, flags);
 }
 
 void LLFolderViewItem::openItem( void )
 {
-	if( getViewModelItem() )
-	{
-		getViewModelItem()->openItem();
-	}
+	getViewModelItem()->openItem();
 }
 
 void LLFolderViewItem::rename(const std::string& new_name)
 {
 	if( !new_name.empty() )
 	{
-		if( getViewModelItem() )
-		{
-			getViewModelItem()->renameItem(new_name);
+		getViewModelItem()->renameItem(new_name);
 
-			if(mParentFolder)
-			{
-				mParentFolder->requestSort();
-			}
+		if(mParentFolder)
+		{
+			mParentFolder->requestSort();
 		}
 	}
 }
 
-const std::string& LLFolderViewItem::getSearchableLabel() const
-{
-	return mSearchableLabel;
-}
-
 const std::string& LLFolderViewItem::getName( void ) const
 {
-	if(getViewModelItem())
-	{
-		return getViewModelItem()->getName();
-	}
-	return LLStringUtil::null;
+	return getViewModelItem()->getName();
 }
 
 // LLView functionality
@@ -578,7 +436,7 @@ BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
 {
 	if(!mIsSelected)
 	{
-		setSelectionFromRoot(this, FALSE);
+		getRoot()->setSelection(this, FALSE);
 	}
 	make_ui_sound("UISndClick");
 	return TRUE;
@@ -599,7 +457,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
 	{
 		if(mask & MASK_CONTROL)
 		{
-			changeSelectionFromRoot(this, !mIsSelected);
+			getRoot()->changeSelection(this, !mIsSelected);
 		}
 		else if (mask & MASK_SHIFT)
 		{
@@ -607,7 +465,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
 		}
 		else
 		{
-			setSelectionFromRoot(this, FALSE);
+			getRoot()->setSelection(this, FALSE);
 		}
 		make_ui_sound("UISndClick");
 	}
@@ -646,14 +504,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 
 				// *TODO: push this into listener and remove
 				// dependency on llagent
-				if (getViewModelItem())
-				{
-					src = getViewModelItem()->getDragSource();
-				}
-				else
-				{
-					src = LLToolDragAndDrop::SOURCE_VIEWER;
-				}
+				src = getViewModelItem()->getDragSource();
 
 				can_drag = root->startDrag(src);
 				if (can_drag)
@@ -695,10 +546,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 
 BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
 {
-	if (getViewModelItem())
-	{
-		getViewModelItem()->openItem();
-	}
+	getViewModelItem()->openItem();
 	return TRUE;
 }
 
@@ -715,7 +563,7 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
 		//...then select
 		if(mask & MASK_CONTROL)
 		{
-			changeSelectionFromRoot(this, !mIsSelected);
+			getRoot()->changeSelection(this, !mIsSelected);
 		}
 		else if (mask & MASK_SHIFT)
 		{
@@ -723,7 +571,7 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
 		}
 		else
 		{
-			setSelectionFromRoot(this, FALSE);
+			getRoot()->setSelection(this, FALSE);
 		}
 	}
 
@@ -748,21 +596,17 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 										 EAcceptance* accept,
 										 std::string& tooltip_msg)
 {
-	BOOL accepted = FALSE;
 	BOOL handled = FALSE;
-	if(getViewModelItem())
+	BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+	handled = accepted;
+	if (accepted)
 	{
-		accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
-		handled = accepted;
-		if (accepted)
-		{
-			mDragAndDropTarget = TRUE;
-			*accept = ACCEPT_YES_MULTI;
-		}
-		else
-		{
-			*accept = ACCEPT_NO;
-		}
+		mDragAndDropTarget = TRUE;
+		*accept = ACCEPT_YES_MULTI;
+	}
+	else
+	{
+		*accept = ACCEPT_NO;
 	}
 	if(mParentFolder && !handled)
 	{
@@ -781,17 +625,17 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 
 void LLFolderViewItem::draw()
 {
-	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+	static LLUIColor sFgColor 			= LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+	static LLUIColor sHighlightBgColor 	= LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+	static LLUIColor sHighlightFgColor 	= LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
 	static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
-	static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
-	static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
-	static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
-	static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
-	static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
+	static LLUIColor sFilterBGColor 	= LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+	static LLUIColor sFilterTextColor 	= LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+	static LLUIColor sSuffixColor 		= LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
+	static LLUIColor sLibraryColor 		= LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
+	static LLUIColor sLinkColor 		= LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
 	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
-	static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+	static LLUIColor sMouseOverColor 	= LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 
 	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	const S32 TOP_PAD = default_params.item_top_pad;
@@ -929,29 +773,12 @@ void LLFolderViewItem::draw()
 	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
 	//TODO RN: implement this in terms of getColor()
 	//if (highlight_link) color = sLinkColor;
-	//if (getViewModelItem() && gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
+	//if (gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
 
 	F32 right_x  = 0;
 	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
 	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
 
-	//--------------------------------------------------------------------------------//
-	// Highlight filtered text
-	//
-	if (getRoot()->getDebugFilters())
-	{
-		if (!getFiltered() && !getViewModelItem()->hasChildren())
-		{
-			color.mV[VALPHA] *= 0.5f;
-		}
-		LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? 
-			LLColor4(0.5f, 0.8f, 0.5f, 1.f) : 
-			LLColor4(0.8f, 0.5f, 0.5f, 1.f);
-		LLFontGL::getFontMonospace()->renderUTF8(mStatusText, 0, text_left, y, filter_color,
-												 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-												 S32_MAX, S32_MAX, &right_x, FALSE );
-		text_left = right_x;
-	}
 	//--------------------------------------------------------------------------------//
 	// Draw the actual label text
 	//
@@ -997,6 +824,22 @@ void LLFolderViewItem::draw()
 	//}
 }
 
+const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
+{
+	return getRoot()->getFolderViewModel();
+}
+
+LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
+{
+	return getRoot()->getFolderViewModel();
+}
+
+S32 LLFolderViewItem::getLastFilterGeneration() const
+{
+	return getViewModelItem()->getLastFilterGeneration();
+}
+
+
 
 ///----------------------------------------------------------------------------
 /// Class LLFolderViewFolder
@@ -1010,10 +853,7 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
 	mTargetHeight(0.f),
 	mAutoOpenCountdown(0.f),
 	mLastArrangeGeneration( -1 ),
-	mLastCalculatedWidth(0),
-	mCompletedFilterGeneration(-1),
-	mMostFilteredDescendantGeneration(-1),
-	mPassedFolderFilter(FALSE)
+	mLastCalculatedWidth(0)
 {
 }
 
@@ -1025,25 +865,9 @@ LLFolderViewFolder::~LLFolderViewFolder( void )
 	gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
 }
 
-void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
-{
-	mPassedFolderFilter = filtered;
-	mLastFilterGeneration = filter_generation;
-}
-
-bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
-{
-	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
-}
-
 // addToFolder() returns TRUE if it succeeds. FALSE otherwise
 BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
 {
-	if (!folder)
-	{
-		return FALSE;
-	}
-	mParentFolder = folder;
 	return folder->addFolder(this);
 }
 
@@ -1051,7 +875,7 @@ static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
 
 // Finds width and height of this object and its children. Also
 // makes sure that this view and its children are the right size.
-S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
+S32 LLFolderViewFolder::arrange( S32* width, S32* height )
 {
 	// sort before laying out contents
 	getRoot()->getFolderViewModel()->sort(this);
@@ -1060,7 +884,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 
 	// evaluate mHasVisibleChildren
 	mHasVisibleChildren = false;
-	if (hasFilteredDescendants(filter_generation))
+	if (getViewModelItem()->descendantsPassedFilter())
 	{
 		// We have to verify that there's at least one child that's not filtered out
 		bool found = false;
@@ -1068,7 +892,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 		for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
 		{
 			LLFolderViewItem* itemp = (*iit);
-			found = (itemp->getFiltered(filter_generation));
+			found = itemp->passedFilter();
 			if (found)
 				break;
 		}
@@ -1078,9 +902,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 			for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
 			{
 				LLFolderViewFolder* folderp = (*fit);
-				found = ( (folderp->getFiltered(filter_generation)
-									 ||	(folderp->getFilteredFolder(filter_generation) 
-										 && folderp->hasFilteredDescendants(filter_generation))));
+				found = folderp->passedFilter();
 				if (found)
 					break;
 			}
@@ -1090,7 +912,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 	}
 
 	// calculate height as a single item (without any children), and reshapes rectangle to match
-	LLFolderViewItem::arrange( width, height, filter_generation );
+	LLFolderViewItem::arrange( width, height );
 
 	// clamp existing animated height so as to never get smaller than a single item
 	mCurHeight = llmax((F32)*height, mCurHeight);
@@ -1113,16 +935,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 			for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
 			{
 				LLFolderViewFolder* folderp = (*fit);
-				if (getRoot()->getDebugFilters())
-				{
-					folderp->setVisible(TRUE);
-				}
-				else
-				{
-					folderp->setVisible( folderp->getFiltered(filter_generation)
-											||	(folderp->getFilteredFolder(filter_generation) 
-												&& folderp->hasFilteredDescendants(filter_generation))); // passed filter or has descendants that passed filter
-				}
+				folderp->setVisible(folderp->passedFilter()); // passed filter or has descendants that passed filter
 
 				if (folderp->getVisible())
 				{
@@ -1130,7 +943,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 					S32 child_height = 0;
 					S32 child_top = parent_item_height - llround(running_height);
 
-					target_height += folderp->arrange( &child_width, &child_height, filter_generation );
+					target_height += folderp->arrange( &child_width, &child_height );
 
 					running_height += (F32)child_height;
 					*width = llmax(*width, child_width);
@@ -1141,14 +954,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 				iit != mItems.end(); ++iit)
 			{
 				LLFolderViewItem* itemp = (*iit);
-				if (getRoot()->getDebugFilters())
-				{
-					itemp->setVisible(TRUE);
-				}
-				else
-				{
-					itemp->setVisible(itemp->getFiltered(filter_generation));
-				}
+				itemp->setVisible(itemp->passedFilter());
 
 				if (itemp->getVisible())
 				{
@@ -1156,7 +962,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
 					S32 child_height = 0;
 					S32 child_top = parent_item_height - llround(running_height);
 
-					target_height += itemp->arrange( &child_width, &child_height, filter_generation );
+					target_height += itemp->arrange( &child_width, &child_height );
 					// don't change width, as this item is as wide as its parent folder by construction
 					itemp->reshape( itemp->getRect().getWidth(), child_height);
 
@@ -1234,234 +1040,21 @@ void LLFolderViewFolder::requestSort()
 	getViewModelItem()->requestSort();
 }
 
-void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
-{
-	//mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
-	mCompletedFilterGeneration = generation;
-	// only aggregate up if we are a lower (older) value
-	if (recurse_up
-		&& mParentFolder
-		&& generation < mParentFolder->getCompletedFilterGeneration())
-	{
-		mParentFolder->setCompletedFilterGeneration(generation, TRUE);
-	}
-}
+//TODO RN: get height resetting working
+//void LLFolderViewFolder::setPassedFilter(BOOL passed, BOOL passed_folder, S32 filter_generation)
+//{
+//	// if this folder is now filtered, but wasn't before
+//	// (it just passed)
+//	if (passed && !passedFilter(filter_generation))
+//	{
+//		// reset current height, because last time we drew it
+//		// it might have had more visible items than now
+//		mCurHeight = 0.f;
+//	}
+//
+//	LLFolderViewItem::setPassedFilter(passed, passed_folder, filter_generation);
+//}
 
-void LLFolderViewFolder::filter( LLFolderViewFilter& filter)
-{
-	S32 filter_generation = filter.getCurrentGeneration();
-	// if failed to pass filter newer than must_pass_generation
-	// you will automatically fail this time, so we only
-	// check against items that have passed the filter
-	S32 must_pass_generation = filter.getFirstRequiredGeneration();
-	
-	bool autoopen_folders = filter.showAllResults();
-
-	// if we have already been filtered against this generation, skip out
-	if (getCompletedFilterGeneration() >= filter_generation)
-	{
-		return;
-	}
-
-	// filter folder itself
-	if (getLastFilterGeneration() < filter_generation)
-	{
-		if (getLastFilterGeneration() >= must_pass_generation	// folder has been compared to a valid precursor filter
-			&& !mPassedFilter)									// and did not pass the filter
-		{
-			// go ahead and flag this folder as done
-			mLastFilterGeneration = filter_generation;			
-			//TODO RN: create interface for string highlighting
-			//mStringMatchOffset = std::string::npos;
-		}
-		else // filter self only on first pass through
-		{
-			// filter against folder rules
-			filterFolder(filter);
-			// and then item rules
-			LLFolderViewItem::filter( filter );
-		}
-	}
-
-	if (getRoot()->getDebugFilters())
-	{
-		mStatusText = llformat("%d", mLastFilterGeneration);
-		mStatusText += llformat("(%d)", mCompletedFilterGeneration);
-		mStatusText += llformat("+%d", mMostFilteredDescendantGeneration);
-	}
-
-	// all descendants have been filtered later than must pass generation
-	// but none passed
-	if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation))
-	{
-		// don't traverse children if we've already filtered them since must_pass_generation
-		// and came back with nothing
-		return;
-	}
-
-	// we entered here with at least one filter iteration left
-	// check to see if we have any more before continuing on to children
-	if (filter.getFilterCount() < 0)
-	{
-		return;
-	}
-
-	// now query children
-	for (folders_t::iterator iter = mFolders.begin();
-		 iter != mFolders.end();
-		 ++iter)
-	{
-		LLFolderViewFolder* folder = (*iter);
-		// have we run out of iterations this frame?
-		if (filter.getFilterCount() < 0)
-		{
-			break;
-		}
-
-		// mMostFilteredDescendantGeneration might have been reset
-		// in which case we need to update it even for folders that
-		// don't need to be filtered anymore
-		if (folder->getCompletedFilterGeneration() >= filter_generation)
-		{
-			// track latest generation to pass any child items
-			if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getFirstSuccessGeneration()))
-			{
-				mMostFilteredDescendantGeneration = filter_generation;
-				requestArrange();
-			}
-			// just skip it, it has already been filtered
-			continue;
-		}
-
-		// update this folders filter status (and children)
-		folder->filter( filter );
-
-		// track latest generation to pass any child items
-		if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation))
-		{
-			mMostFilteredDescendantGeneration = filter_generation;
-			requestArrange();
-			if (getRoot()->needsAutoSelect() && autoopen_folders)
-			{
-				folder->setOpenArrangeRecursively(TRUE);
-			}
-		}
-	}
-
-	for (items_t::iterator iter = mItems.begin();
-		 iter != mItems.end();
-		 ++iter)
-	{
-		LLFolderViewItem* item = (*iter);
-		if (filter.getFilterCount() < 0)
-		{
-			break;
-		}
-		if (item->getLastFilterGeneration() >= filter_generation)
-		{
-			if (item->getFiltered())
-			{
-				mMostFilteredDescendantGeneration = filter_generation;
-				requestArrange();
-			}
-			continue;
-		}
-
-		if (item->getLastFilterGeneration() >= must_pass_generation && 
-			!item->getFiltered(must_pass_generation))
-		{
-			// failed to pass an earlier filter that was a subset of the current one
-			// go ahead and flag this item as done
-			item->setFiltered(FALSE, filter_generation);
-			continue;
-		}
-
-		item->filter( filter );
-
-		if (item->getFiltered(filter.getFirstSuccessGeneration()))
-		{
-			mMostFilteredDescendantGeneration = filter_generation;
-			requestArrange();
-		}
-	}
-
-	// if we didn't use all filter iterations
-	// that means we filtered all of our descendants
-	// instead of exhausting the filter count for this frame
-	if (filter.getFilterCount() > 0)
-	{
-		// flag this folder as having completed filter pass for all descendants
-		setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/);
-	}
-}
-
-void LLFolderViewFolder::filterFolder(LLFolderViewFilter& filter)
-{
-	const BOOL previous_passed_filter = mPassedFolderFilter;
-	const BOOL passed_filter = filter.checkFolder(this);
-
-	// If our visibility will change as a result of this filter, then
-	// we need to be rearranged in our parent folder
-	if (mParentFolder)
-	{
-		if (getVisible() != passed_filter
-			|| previous_passed_filter != passed_filter )
-		{
-			mParentFolder->requestArrange();
-		}
-	}
-
-	setFilteredFolder(passed_filter, filter.getCurrentGeneration());
-	filter.decrementFilterCount();
-
-	if (getRoot()->getDebugFilters())
-	{
-		mStatusText = llformat("%d", mLastFilterGeneration);
-	}
-}
-
-void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
-{
-	// if this folder is now filtered, but wasn't before
-	// (it just passed)
-	if (filtered && !mPassedFilter)
-	{
-		// reset current height, because last time we drew it
-		// it might have had more visible items than now
-		mCurHeight = 0.f;
-	}
-
-	LLFolderViewItem::setFiltered(filtered, filter_generation);
-}
-
-void LLFolderViewFolder::dirtyFilter()
-{
-	// we're a folder, so invalidate our completed generation
-	setCompletedFilterGeneration(-1, FALSE);
-	LLFolderViewItem::dirtyFilter();
-}
-
-BOOL LLFolderViewFolder::getFiltered() 
-{ 
-	return getFilteredFolder(getRoot()->getFilter()->getFirstSuccessGeneration())
-		&& LLFolderViewItem::getFiltered(); 
-}
-
-BOOL LLFolderViewFolder::getFiltered(S32 filter_generation) 
-{
-	return getFilteredFolder(filter_generation) && LLFolderViewItem::getFiltered(filter_generation);
-}
-
-BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)
-{ 
-	return mMostFilteredDescendantGeneration >= filter_generation; 
-}
-
-
-BOOL LLFolderViewFolder::hasFilteredDescendants()
-{
-	return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getFirstSuccessGeneration();
-}
 
 // Passes selection information on to children and record selection
 // information if necessary.
@@ -1824,39 +1417,7 @@ void LLFolderViewFolder::destroyView()
 		folderp->destroyView(); // removes entry from mFolders
 	}
 
-	if (mParentFolder)
-	{
-		mParentFolder->removeView(this);
-	}
-}
-
-// remove the specified item (and any children) if possible. Return
-// TRUE if the item was deleted.
-BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item)
-{
-	if(item->remove())
-	{
-		return TRUE;
-	}
-	return FALSE;
-}
-
-// simply remove the view (and any children) Don't bother telling the
-// listeners.
-void LLFolderViewFolder::removeView(LLFolderViewItem* item)
-{
-	if (!item || item->getParentFolder() != this)
-	{
-		return;
-	}
-	// deselect without traversing hierarchy
-	if (item->isSelected())
-	{
-		item->deselectItem();
-	}
-	getRoot()->removeFromSelectionList(item);
-	extractItem(item);
-	delete item;
+	LLFolderViewItem::destroyView();
 }
 
 // extractItem() removes the specified item from the folder, but
@@ -1882,7 +1443,7 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
 		mItems.erase(it);
 	}
 	//item has been removed, need to update filter
-	dirtyFilter();
+	getViewModelItem()->dirtyFilter();
 	//because an item is going away regardless of filter status, force rearrange
 	requestArrange();
 	removeChild(item);
@@ -1890,31 +1451,28 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
 
 BOOL LLFolderViewFolder::isMovable()
 {
-	if( getViewModelItem() )
+	if( !(getViewModelItem()->isItemMovable()) )
 	{
-		if( !(getViewModelItem()->isItemMovable()) )
-		{
-			return FALSE;
-		}
+		return FALSE;
+	}
 
-		for (items_t::iterator iter = mItems.begin();
-			iter != mItems.end();)
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		if(!(*iit)->isMovable())
 		{
-			items_t::iterator iit = iter++;
-			if(!(*iit)->isMovable())
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
+	}
 
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		if(!(*fit)->isMovable())
 		{
-			folders_t::iterator fit = iter++;
-			if(!(*fit)->isMovable())
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
 	}
 	return TRUE;
@@ -1923,31 +1481,28 @@ BOOL LLFolderViewFolder::isMovable()
 
 BOOL LLFolderViewFolder::isRemovable()
 {
-	if( getViewModelItem() )
+	if( !(getViewModelItem()->isItemRemovable()) )
 	{
-		if( !(getViewModelItem()->isItemRemovable()) )
-		{
-			return FALSE;
-		}
+		return FALSE;
+	}
 
-		for (items_t::iterator iter = mItems.begin();
-			iter != mItems.end();)
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		if(!(*iit)->isRemovable())
 		{
-			items_t::iterator iit = iter++;
-			if(!(*iit)->isRemovable())
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
+	}
 
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		if(!(*fit)->isRemovable())
 		{
-			folders_t::iterator fit = iter++;
-			if(!(*fit)->isRemovable())
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
 	}
 	return TRUE;
@@ -1956,6 +1511,12 @@ BOOL LLFolderViewFolder::isRemovable()
 // this is an internal method used for adding items to folders. 
 BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 {
+	if (item->getParentFolder())
+	{
+		item->getParentFolder()->extractItem(item);
+	}
+	item->setParentFolder(this);
+
 	mItems.push_back(item);
 	
 	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
@@ -1963,12 +1524,14 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	
 	addChild(item);
 	
-	item->dirtyFilter();
+	item->getViewModelItem()->dirtyFilter();
 
 	// Handle sorting
 	requestArrange();
 	requestSort();
 
+	getViewModelItem()->addChild(item->getViewModelItem());
+
 	//TODO RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
 	//// Traverse parent folders and update creation date and resort, if necessary
 	//LLFolderViewFolder* parentp = this;
@@ -1989,16 +1552,23 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 // this is an internal method used for adding items to folders. 
 BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 {
+	if (folder->mParentFolder)
+	{
+		folder->mParentFolder->extractItem(folder);
+	}
+	folder->mParentFolder = this;
 	mFolders.push_back(folder);
 	folder->setOrigin(0, 0);
 	folder->reshape(getRect().getWidth(), 0);
 	folder->setVisible(FALSE);
 	addChild( folder );
-	folder->dirtyFilter();
+	folder->getViewModelItem()->dirtyFilter();
 	// rearrange all descendants too, as our indentation level might have changed
 	folder->requestArrange();
 	requestSort();
 
+	getViewModelItem()->addChild(folder->getViewModelItem());
+
 	return TRUE;
 }
 
@@ -2027,16 +1597,13 @@ void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType r
 {
 	BOOL was_open = isOpen();
 	mIsOpen = openitem;
-	if (getViewModelItem())
+	if(!was_open && openitem)
 	{
-		if(!was_open && openitem)
-		{
-			getViewModelItem()->openItem();
-		}
-		else if(was_open && !openitem)
-		{
-			getViewModelItem()->closeItem();
-		}
+		getViewModelItem()->openItem();
+	}
+	else if(was_open && !openitem)
+	{
+		getViewModelItem()->closeItem();
 	}
 
 	if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
@@ -2068,7 +1635,7 @@ BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
 													EAcceptance* accept,
 													std::string& tooltip_msg)
 {
-	BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
+	BOOL accepted = mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
 	if (accepted) 
 	{
 		mDragAndDropTarget = TRUE;
@@ -2156,7 +1723,7 @@ BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
 													   EAcceptance* accept,
 													   std::string& tooltip_msg)
 {
-	BOOL accepted = getViewModelItem() && getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+	BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
 	
 	if (accepted) 
 	{
@@ -2259,7 +1826,7 @@ BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 		}
 		else
 		{
-			setSelectionFromRoot(this, FALSE);
+			getRoot()->setSelection(this, FALSE);
 			toggleOpen();
 		}
 		handled = TRUE;
@@ -2293,16 +1860,6 @@ void LLFolderViewFolder::draw()
 	mExpanderHighlighted = FALSE;
 }
 
-BOOL	LLFolderViewFolder::potentiallyVisible()
-{
-	// folder should be visible by it's own filter status
-	return LLFolderViewItem::potentiallyVisible() 	
-		// or one or more of its descendants have passed the minimum filter requirement
-		|| hasFilteredDescendants()
-		// or not all of its descendants have been checked against minimum filter requirement
-		|| getCompletedFilterGeneration() < getRoot()->getFilter()->getFirstSuccessGeneration();
-}
-
 // this does prefix traversal, as folders are listed above their contents
 LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
 {
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index fd2948f34e..7e48969826 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -35,6 +35,7 @@ class LLFolderViewModelItem;
 class LLFolderViewFolder;
 class LLFolderViewFunctor;
 class LLFolderViewFilter;
+class LLFolderViewModelInterface;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLFolderViewItem
@@ -78,8 +79,6 @@ public:
 	static const F32 FOLDER_CLOSE_TIME_CONSTANT;
 	static const F32 FOLDER_OPEN_TIME_CONSTANT;
 
-	const std::string& getSearchableLabel() { return mSearchableLabel; }
-	
 private:
 	BOOL						mIsSelected;
 
@@ -90,7 +89,6 @@ protected:
 	LLFolderViewItem(const Params& p);
 
 	std::string					mLabel;
-	std::string					mSearchableLabel;
 	S32							mLabelWidth;
 	bool						mLabelWidthDirty;
 	LLFolderViewFolder*			mParentFolder;
@@ -106,8 +104,7 @@ protected:
 	BOOL						mHasVisibleChildren;
 	S32							mIndentation;
 	S32							mItemHeight;
-	BOOL						mPassedFilter;
-	S32							mLastFilterGeneration;
+
 	//TODO RN: create interface for string highlighting
 	//std::string::size_type		mStringMatchOffset;
 	F32							mControlLabelRotation;
@@ -115,9 +112,6 @@ protected:
 	BOOL						mDragAndDropTarget;
 	bool						mIsMouseOverTitle;
 
-	// helper function to change the selection from the root.
-	void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
-
 	// this is an internal method used for adding items to folders. A
 	// no-op at this level, but reimplemented in derived classes.
 	virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
@@ -130,39 +124,20 @@ public:
 
 	virtual void openItem( void );
 
-	// This function clears the currently selected item, and records
-	// the specified selected item appropriately for display and use
-	// in the UI. If open is TRUE, then folders are opened up along
-	// the way to the selection.
-	void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
-		BOOL take_keyboard_focus = TRUE);
-
-	// This function is called when the folder view is dirty. It's
-	// implemented here but called by derived classes when folding the
-	// views.
-	void arrangeFromRoot();
-	void filterFromRoot( void );
-	
 	void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
 
 	virtual ~LLFolderViewItem( void );
 
 	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-	enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
 	virtual BOOL addToFolder(LLFolderViewFolder* folder);
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
-	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+	virtual S32 arrange( S32* width, S32* height );
 	virtual S32 getItemHeight();
 
-	// applies filters to control visibility of items
-	virtual void filter( LLFolderViewFilter& filter);
-
 	// updates filter serial number and optionally propagated value up to root
-	S32		getLastFilterGeneration() { return mLastFilterGeneration; }
-
-	virtual void	dirtyFilter();
+	S32		getLastFilterGeneration() const;
 
 	// If 'selection' is 'this' then note that otherwise ignore.
 	// Returns TRUE if this item ends up being selected.
@@ -213,8 +188,6 @@ public:
 	// viewed. This method will ask the viewed object itself.
 	const std::string& getName( void ) const;
 
-	const std::string& getSearchableLabel( void ) const;
-
 	// This method returns the label displayed on the view. This
 	// method was primarily added to allow sorting on the folder
 	// contents possible before the entire view has been constructed.
@@ -224,12 +197,17 @@ public:
 	LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
 	const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
 
+	void setParentFolder(LLFolderViewFolder* parent) { mParentFolder = parent; }
+
 	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
 	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
 
 	const LLFolderViewModelItem* getViewModelItem( void ) const { return mListener; }
 	LLFolderViewModelItem* getViewModelItem( void ) { return mListener; }
 
+	const LLFolderViewModelInterface* getFolderViewModel( void ) const;
+	LLFolderViewModelInterface* getFolderViewModel( void );
+
 	// just rename the object.
 	void rename(const std::string& new_name);
 
@@ -239,15 +217,11 @@ public:
 	virtual BOOL isOpen() const { return FALSE; }
 
 	virtual LLFolderView*	getRoot();
+	virtual const LLFolderView*	getRoot() const;
 	BOOL			isDescendantOf( const LLFolderViewFolder* potential_ancestor );
 	S32				getIndentation() { return mIndentation; }
 
-	virtual BOOL	potentiallyVisible(); // is the item definitely visible or we haven't made up our minds yet?
-	virtual BOOL	potentiallyHidden(); // did this item not pass the filter or do we not know yet?
-
-	virtual BOOL	getFiltered();
-	virtual BOOL	getFiltered(S32 filter_generation);
-	virtual void	setFiltered(BOOL filtered, S32 filter_generation);
+	virtual BOOL	passedFilter(S32 filter_generation = -1);
 
 	// refresh information from the object being viewed.
 	virtual void refresh();
@@ -305,7 +279,6 @@ protected:
 	F32			mAutoOpenCountdown;
 	S32			mLastArrangeGeneration;
 	S32			mLastCalculatedWidth;
-	S32			mCompletedFilterGeneration;
 	S32			mMostFilteredDescendantGeneration;
 	bool		mNeedsSort;
 	bool		mPassedFolderFilter;
@@ -322,8 +295,6 @@ public:
 
 	virtual ~LLFolderViewFolder( void );
 
-	virtual BOOL	potentiallyVisible();
-
 	LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
 	LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE  );
 
@@ -332,34 +303,17 @@ public:
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
-	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+	virtual S32 arrange( S32* width, S32* height );
 
 	BOOL needsArrange();
 
-	virtual void	setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
-	virtual S32		getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
-
-	BOOL hasFilteredDescendants(S32 filter_generation);
-	BOOL hasFilteredDescendants();
-
-	// applies filters to control visibility of items
-	virtual void filter( LLFolderViewFilter& filter);
-	virtual void setFiltered(BOOL filtered, S32 filter_generation);
-	virtual BOOL getFiltered();
-	virtual BOOL getFiltered(S32 filter_generation);
-
-	virtual void dirtyFilter();
-	
-	// folder-specific filtering (filter status propagates top down instead of bottom up)
-	void filterFolder(LLFolderViewFilter& filter);
-	void setFilteredFolder(bool filtered, S32 filter_generation);
-	bool getFilteredFolder(S32 filter_generation);
+	bool descendantsPassedFilter(S32 filter_generation = -1);
 
 	// Passes selection information on to children and record
 	// selection information if necessary.
 	// Returns TRUE if this object (or a child) ends up being selected.
 	// If 'openitem' is TRUE then folders are opened up along the way to the selection.
-	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
+	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus = TRUE);
 
 	// This method is used to change the selection of an item.
 	// Recursively traverse all children; if 'selection' is 'this' then change
@@ -385,14 +339,6 @@ public:
 	//virtual BOOL removeRecursively(BOOL single_item);
 	//virtual BOOL remove();
 
-	// remove the specified item (and any children) if
-	// possible. Return TRUE if the item was deleted.
-	BOOL removeItem(LLFolderViewItem* item);
-
-	// simply remove the view (and any children) Don't bother telling
-	// the listeners.
-	void removeView(LLFolderViewItem* item);
-
 	// extractItem() removes the specified item from the folder, but
 	// doesn't delete it.
 	virtual void extractItem( LLFolderViewItem* item );
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 74c8bb92ef..0216ba2a07 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -72,9 +72,9 @@ public:
 	// +-------------------------------------------------------------------+
 	// + Execution And Results
 	// +-------------------------------------------------------------------+
-	virtual bool 				check(const LLFolderViewItem* item) = 0;
+	virtual bool 				check(const LLFolderViewModelItem* item) = 0;
 	virtual bool				check(const LLInventoryItem* item) = 0;
-	virtual bool				checkFolder(const LLFolderViewFolder* folder) const = 0;
+	virtual bool				checkFolder(const LLFolderViewModelItem* folder) const = 0;
 	virtual bool				checkFolder(const LLUUID& folder_id) const = 0;
 
 	virtual void 				setEmptyLookupMessage(const std::string& message) = 0;
@@ -126,6 +126,8 @@ public:
 
 	virtual bool contentsReady() = 0;
 	virtual void setFolderView(LLFolderView* folder_view) = 0;
+	virtual LLFolderViewFilter* getFilter() = 0;
+	virtual const LLFolderViewFilter* getFilter() const = 0;
 };
 
 class LLFolderViewModelCommon : public LLFolderViewModelInterface
@@ -152,20 +154,82 @@ protected:
 
 };
 
+template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
+class LLFolderViewModel : public LLFolderViewModelCommon
+{
+public:
+	LLFolderViewModel(){}
+	virtual ~LLFolderViewModel() {}
+	
+	typedef SORT_TYPE		SortType;
+	typedef ITEM_TYPE		ItemType;
+	typedef FOLDER_TYPE		FolderType;
+	typedef FILTER_TYPE		FilterType;
+	
+	virtual SortType& getSorter()					 { return mSorter; }
+	virtual const SortType& getSorter() const 		 { return mSorter; }
+	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
+
+	virtual FilterType* getFilter() 				 { return &mFilter; }
+	virtual const FilterType* getFilter() const		 { return &mFilter; }
+	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
+
+	// TODO RN: remove this and put all filtering logic in view model
+	// add getStatusText and isFiltering()
+	virtual bool contentsReady()					{ return true; }
+
+	struct ViewModelCompare
+	{
+		ViewModelCompare(const SortType& sorter)
+		:	mSorter(sorter)
+		{}
+		
+		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		const SortType& mSorter;
+	};
+
+	void sort(LLFolderViewFolder* folder)
+	{
+		if (needsSort(folder->getViewModelItem()))
+		{
+			folder->sortFolders(ViewModelCompare(getSorter()));
+			folder->sortItems(ViewModelCompare(getSorter()));
+			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
+			folder->requestArrange();
+		}
+	}
+
+	//TODO RN: fix this
+	void filter(LLFolderViewFolder* folder)
+	{
+		
+	}
+
+protected:
+	SortType		mSorter;
+	FilterType		mFilter;
+};
+
 // This is am abstract base class that users of the folderview classes
 // would use to bridge the folder view with the underlying data
 class LLFolderViewModelItem
 {
 public:
-	LLFolderViewModelItem()
-	:	mFolderViewItem(NULL)
-	{}
-
 	virtual ~LLFolderViewModelItem( void ) {};
 
 	virtual void update() {}	//called when drawing
 	virtual const std::string& getName() const = 0;
 	virtual const std::string& getDisplayName() const = 0;
+	virtual const std::string& getSearchableName() const = 0;
 
 	virtual LLPointer<LLUIImage> getIcon() const = 0;
 	virtual LLPointer<LLUIImage> getIconOpen() const { return getIcon(); }
@@ -198,12 +262,23 @@ public:
 
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
 	
+	virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
+
+	virtual void filter( LLFolderViewFilter& filter) = 0;
+	virtual bool passedFilter(S32 filter_generation = -1) = 0;
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
+	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) = 0;
+	virtual void dirtyFilter() = 0;
+
+	virtual S32	getLastFilterGeneration() const = 0;
+
 	// This method should be called when a drag begins. returns TRUE
 	// if the drag can begin, otherwise FALSE.
 	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
 	
 	virtual bool hasChildren() const = 0;
+	virtual void addChild(LLFolderViewModelItem* child) = 0;
 
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
@@ -217,10 +292,12 @@ public:
 	virtual void requestSort() = 0;
 	virtual S32 getSortVersion() = 0;
 	virtual void setSortVersion(S32 version) = 0;
+	virtual void setParent(LLFolderViewModelItem* parent) = 0;
+
 protected:
+
 	friend class LLFolderViewItem;
-	void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
-	LLFolderViewItem*	mFolderViewItem;
+	virtual void setFolderViewItem(LLFolderViewItem* folder_view_item) = 0;
 
 };
 
@@ -228,95 +305,48 @@ class LLFolderViewModelItemCommon : public LLFolderViewModelItem
 {
 public:
 	LLFolderViewModelItemCommon()
-	:	mSortVersion(-1)
+	:	mSortVersion(-1),
+		mPassedFilter(false),
+		mPassedFolderFilter(false),
+		mFolderViewItem(NULL),
+		mLastFilterGeneration(-1),
+		mMostFilteredDescendantGeneration(-1)
 	{}
 
 	void requestSort() { mSortVersion = -1; }
 	S32 getSortVersion() { return mSortVersion; }
 	void setSortVersion(S32 version) { mSortVersion = version;}
 
-protected:
-
-	S32 mSortVersion;
-};
-
-template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
-class LLFolderViewModel : public LLFolderViewModelCommon
-{
-public:
-	LLFolderViewModel(){}
-	virtual ~LLFolderViewModel() {}
-	
-	typedef SORT_TYPE		SortType;
-	typedef ITEM_TYPE		ItemType;
-	typedef FOLDER_TYPE		FolderType;
-	typedef FILTER_TYPE		FilterType;
-	
-	virtual SortType& getSorter()					 { return mSorter; }
-	virtual const SortType& getSorter() const 		 { return mSorter; }
-	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
-	virtual FilterType& getFilter() 				 { return mFilter; }
-	virtual const FilterType& getFilter() const		 { return mFilter; }
-	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
-
-	// TODO RN: remove this and put all filtering logic in view model
-	// add getStatusText and isFiltering()
-	virtual bool contentsReady()					{ return true; }
-
-	struct ViewModelCompare
+	S32	getLastFilterGeneration() const { return mLastFilterGeneration; }
+	void dirtyFilter()
 	{
-		ViewModelCompare(const SortType& sorter)
-		:	mSorter(sorter)
-		{}
-		
-		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
+		mLastFilterGeneration = -1;
+		// bubble up dirty flag all the way to root
+		if (mParent)
 		{
-			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+			mParent->dirtyFilter();
 		}
+	}
+	virtual void addChild(LLFolderViewModelItem* child) { mChildren.push_back(child); child->setParent(this); }
 
-		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
-		{
-			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
-		}
+protected:
+	virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
 
-		const SortType& mSorter;
-	};
+	S32						mSortVersion;
+	bool					mPassedFilter;
+	bool					mPassedFolderFilter;
 
-	void sort(LLFolderViewFolder* folder)
-	{
-		if (needsSort(folder->getViewModelItem()))
-		{
-			folder->sortFolders(ViewModelCompare(getSorter()));
-			folder->sortItems(ViewModelCompare(getSorter()));
-			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
-			folder->requestArrange();
-		}
-	}
+	S32						mLastFilterGeneration;
+	S32						mMostFilteredDescendantGeneration;
 
-	//TODO RN: fix this
-	void filter(LLFolderViewFolder* folder)
-	{
-		/*FilterType& filter = getFilter();
-		for (std::list<LLFolderViewItem*>::const_iterator it = folder->getItemsBegin(), end_it = folder->getItemsEnd();
-			it != end_it;
-			++it)
-		{
-			LLFolderViewItem* child_item = *it;
-			child_item->setFiltered(filter.checkFolder(static_cast<ItemType*>(child_item->getViewModelItem())), filter.getCurrentGeneration());
-		}
 
-		for (std::list<LLFolderViewFolder*>::const_iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
-			it != end_it;
-			++it)
-		{
-			LLFolderViewItem* child_folder = *it;
-			child_folder->setFiltered(filter.check(static_cast<ItemType*>(child_folder->getViewModelItem())), filter.getCurrentGeneration());
-		}*/
-	}
+	typedef std::list<LLFolderViewModelItem*> child_list_t;
+	child_list_t			mChildren;
+	LLFolderViewModelItem*	mParent;
 
-protected:
-	SortType		mSorter;
-	FilterType		mFilter;
+	void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
+	LLFolderViewItem*		mFolderViewItem;
 };
 
+
 #endif
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 70a174a140..45a2bffa6b 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1545,6 +1545,10 @@ void LLItemBridge::buildDisplayName() const
 	{
 		mDisplayName.assign(LLStringUtil::null);
 	}
+
+	mSearchableName.assign(mDisplayName);
+	mSearchableName.append(getLabelSuffix());
+	LLStringUtil::toUpper(mSearchableName);
 }
 
 LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
@@ -1850,11 +1854,9 @@ void LLFolderBridge::buildDisplayName() const
 		LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
 	}
 
-	//if (mDisplayName.empty())
-	//{
-	//	S32 foo;
-	//	foo = 0;
-	//}
+	mSearchableName.assign(mDisplayName);
+	mSearchableName.append(getLabelSuffix());
+	LLStringUtil::toUpper(mSearchableName);
 }
 
 
@@ -4000,7 +4002,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			LLFolderViewItem* fv_item =   active_panel->getItemByID(inv_item->getUUID());
 			if (!fv_item) return false;
 
-			accept = filter->check(fv_item);
+			accept = filter->check(fv_item->getViewModelItem());
 		}
 
 		if (accept && drop)
@@ -4222,7 +4224,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 				LLFolderViewItem* fv_item =   active_panel->getItemByID(inv_item->getUUID());
 				if (!fv_item) return false;
 
-				accept = filter->check(fv_item);
+				accept = filter->check(fv_item->getViewModelItem());
 			}
 
 			if (accept && drop)
@@ -4319,7 +4321,7 @@ bool check_item(const LLUUID& item_id,
 	LLFolderViewItem* fv_item = active_panel->getItemByID(item_id);
 	if (!fv_item) return false;
 
-	return filter->check(fv_item);
+	return filter->check(fv_item->getViewModelItem());
 }
 
 // +=================================================+
@@ -6126,7 +6128,7 @@ void LLLinkFolderBridge::gotoItem()
 				model->fetchDescendentsOf(cat_uuid);
 			}
 			base_folder->setOpen(TRUE);
-			mRoot->setSelectionFromRoot(base_folder,TRUE);
+			mRoot->setSelection(base_folder,TRUE);
 			mRoot->scrollToShowSelection();
 		}
 	}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 26789627f7..b0582d003d 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -88,6 +88,8 @@ public:
 	//--------------------------------------------------------------------
 	virtual const std::string& getName() const;
 	virtual const std::string& getDisplayName() const;
+	const std::string& getSearchableName() const { return mSearchableName; }
+
 	virtual PermissionMask getPermissionMask() const;
 	virtual LLFolderType::EType getPreferredType() const;
 	virtual time_t getCreationDate() const;
@@ -174,6 +176,7 @@ protected:
 	bool						mIsLink;
 	LLTimer						mTimeSinceRequestStart;
 	mutable std::string			mDisplayName;
+	mutable std::string			mSearchableName;
 
 	void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
 	virtual void buildDisplayName() const {}
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index c13bb5123e..c7e0136368 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -71,35 +71,35 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
     mFilterOps(p.filter_ops),
 	mOrder(p.sort_order),
 	mFilterSubString(p.substring),
-	mLastSuccessGeneration(0),
-	mLastFailGeneration(S32_MAX),
+	mCurrentGeneration(0),
+	mFirstRequiredGeneration(0),
 	mFirstSuccessGeneration(0),
 	mFilterCount(0)
 {
-	mNextFilterGeneration = mLastSuccessGeneration + 1;
+	mNextFilterGeneration = mCurrentGeneration + 1;
 
 	// copy mFilterOps into mDefaultFilterOps
 	markDefault();
 }
 
-bool LLInventoryFilter::check(const LLFolderViewItem* item) 
+bool LLInventoryFilter::check(const LLFolderViewModelItem* item) 
 {
+	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item);
 	// Clipboard cut items are *always* filtered so we need this value upfront
-	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 	const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
 
 	// If it's a folder and we're showing all folders, return automatically.
-	const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
+	const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;;
 	if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
 	{
 		return passed_clipboard;
 	}
 
-	std::string::size_type string_offset = mFilterSubString.size() ?   item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
+	std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos;
 
-	const BOOL passed_filtertype = checkAgainstFilterType(item);
-	const BOOL passed_permissions = checkAgainstPermissions(item);
-	const BOOL passed_filterlink = checkAgainstFilterLinks(item);
+	const BOOL passed_filtertype = checkAgainstFilterType(listener);
+	const BOOL passed_permissions = checkAgainstPermissions(listener);
+	const BOOL passed_filterlink = checkAgainstFilterLinks(listener);
 	const BOOL passed = (passed_filtertype &&
 						 passed_permissions &&
 						 passed_filterlink &&
@@ -117,27 +117,19 @@ bool LLInventoryFilter::check(const LLInventoryItem* item)
 	const bool passed_permissions = checkAgainstPermissions(item);
 	const BOOL passed_clipboard = checkAgainstClipboard(item->getUUID());
 	const bool passed = (passed_filtertype 
-						&& passed_permissions
-						&& passed_clipboard 
-						&&	(mFilterSubString.size() == 0 || string_offset !=  std::string::npos));
+		&& passed_permissions
+		&& passed_clipboard 
+		&&	(mFilterSubString.size() == 0 || string_offset !=  std::string::npos));
 
 	return passed;
 }
 
-bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
+bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
 {
-	if (!folder)
-	{
-		llwarns << "The filter can not be checked on an invalid folder." << llendl;
-		llassert(false); // crash in development builds
-		return false;
-	}
-
-	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(folder->getViewModelItem());
+	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item);
 	if (!listener)
 	{
-		llwarns << "Folder view event listener not found." << llendl;
-		llassert(false); // crash in development builds
+		llerrs << "Folder view event listener not found." << llendl;
 		return false;
 	}
 
@@ -179,9 +171,8 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 	return passed_clipboard;
 }
 
-bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const
 {
-	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 	if (!listener) return FALSE;
 
 	LLInventoryType::EType object_type = listener->getInventoryType();
@@ -347,13 +338,12 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
 	return true;
 }
 
-bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewModelItemInventory* listener) const
 {
-	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 	if (!listener) return FALSE;
 
 	PermissionMask perm = listener->getPermissionMask();
-	const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getViewModelItem());
+	const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(listener);
 	if (bridge && bridge->isLink())
 	{
 		const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID());
@@ -375,9 +365,8 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) con
 	return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
 }
 
-bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewModelItemInventory* listener) const
 {
-	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
 	if (!listener) return TRUE;
 
 	const LLUUID object_id = listener->getUUID();
@@ -740,7 +729,7 @@ void LLInventoryFilter::resetDefault()
 void LLInventoryFilter::setModified(EFilterModified behavior)
 {
 	mFilterText.clear();
-	mLastSuccessGeneration = mNextFilterGeneration++;
+	mCurrentGeneration = mNextFilterGeneration++;
 
 	if (mFilterModified == FILTER_NONE)
 	{
@@ -753,33 +742,21 @@ void LLInventoryFilter::setModified(EFilterModified behavior)
 		mFilterModified = FILTER_RESTART;
 	}
 
-	if (isNotDefault())
-	{
-		// if not keeping current filter results, update last valid as well
-		switch(mFilterModified)
-		{
-			case FILTER_RESTART:
-				mLastFailGeneration = mLastSuccessGeneration;
-				mFirstSuccessGeneration = mLastSuccessGeneration;
-				break;
-			case FILTER_LESS_RESTRICTIVE:
-				mLastFailGeneration = mLastSuccessGeneration;
-				break;
-			case FILTER_MORE_RESTRICTIVE:
-				mFirstSuccessGeneration = mLastSuccessGeneration;
-				// must have passed either current filter generation (meaningless, as it hasn't been run yet)
-				// or some older generation, so keep the value
-				mLastFailGeneration = llmin(mLastFailGeneration,  mLastSuccessGeneration);
-				break;
-			default:
-				llerrs << "Bad filter behavior specified" << llendl;
-		}
-	}
-	else
+	// if not keeping current filter results, update last valid as well
+	switch(mFilterModified)
 	{
-		// shortcut disabled filters to show everything immediately
-		mLastFailGeneration = 0;
-		mFirstSuccessGeneration = S32_MAX;
+		case FILTER_RESTART:
+			mFirstRequiredGeneration = mCurrentGeneration;
+			mFirstSuccessGeneration = mCurrentGeneration;
+			break;
+		case FILTER_LESS_RESTRICTIVE:
+			mFirstRequiredGeneration = mCurrentGeneration;
+			break;
+		case FILTER_MORE_RESTRICTIVE:
+			mFirstSuccessGeneration = mCurrentGeneration;
+			break;
+		default:
+			llerrs << "Bad filter behavior specified" << llendl;
 	}
 }
 
@@ -1101,7 +1078,7 @@ void LLInventoryFilter::decrementFilterCount()
 
 S32 LLInventoryFilter::getCurrentGeneration() const 
 { 
-	return mLastSuccessGeneration;
+	return mCurrentGeneration;
 }
 S32 LLInventoryFilter::getFirstSuccessGeneration() const
 { 
@@ -1109,7 +1086,7 @@ S32 LLInventoryFilter::getFirstSuccessGeneration() const
 }
 S32 LLInventoryFilter::getFirstRequiredGeneration() const
 { 
-	return mLastFailGeneration; 
+	return mFirstRequiredGeneration; 
 }
 
 void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 5b92c21a85..af245a9c3b 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -186,16 +186,10 @@ public:
 	// +-------------------------------------------------------------------+
 	// + Execution And Results
 	// +-------------------------------------------------------------------+
-	bool 				check(const LLFolderViewItem* item);
+	bool				check(const LLFolderViewModelItem* listener);
 	bool				check(const LLInventoryItem* item);
-	bool				checkFolder(const LLFolderViewFolder* folder) const;
+	bool				checkFolder(const LLFolderViewModelItem* listener) const;
 	bool				checkFolder(const LLUUID& folder_id) const;
-	bool 				checkAgainstFilterType(const LLFolderViewItem* item) const;
-	bool 				checkAgainstFilterType(const LLInventoryItem* item) const;
-	bool 				checkAgainstPermissions(const LLFolderViewItem* item) const;
-	bool 				checkAgainstPermissions(const LLInventoryItem* item) const;
-	bool 				checkAgainstFilterLinks(const LLFolderViewItem* item) const;
-	bool				checkAgainstClipboard(const LLUUID& object_id) const;
 
 	bool				showAllResults() const;
 
@@ -260,6 +254,12 @@ public:
 
 private:
 	bool				areDateLimitsSet();
+	bool 				checkAgainstFilterType(const class LLFolderViewModelItemInventory* listener) const;
+	bool 				checkAgainstFilterType(const LLInventoryItem* item) const;
+	bool 				checkAgainstPermissions(const class LLFolderViewModelItemInventory* listener) const;
+	bool 				checkAgainstPermissions(const LLInventoryItem* item) const;
+	bool 				checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;
+	bool				checkAgainstClipboard(const LLUUID& object_id) const;
 
 	U32						mOrder;
 
@@ -270,8 +270,8 @@ private:
 	std::string				mFilterSubStringOrig;
 	const std::string		mName;
 
-	S32						mLastSuccessGeneration;
-	S32						mLastFailGeneration;
+	S32						mCurrentGeneration;
+	S32						mFirstRequiredGeneration;
 	S32						mFirstSuccessGeneration;
 	S32						mNextFilterGeneration;
 
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 1e494c3ef1..ff461236a2 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -983,7 +983,7 @@ void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
 
 void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
 {
-	if (item->getFiltered())
+	if (item->passedFilter())
 	{
 		item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 	}
@@ -991,12 +991,12 @@ void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
 
 void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
 {
-	if (folder->getFiltered() && folder->getParentFolder())
+	if (folder->LLFolderViewItem::passedFilter() && folder->getParentFolder())
 	{
 		folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 	}
 	// if this folder didn't pass the filter, and none of its descendants did
-	else if (!folder->getFiltered() && !folder->hasFilteredDescendants())
+	else if (!folder->getViewModelItem()->passedFilter() && !folder->getViewModelItem()->descendantsPassedFilter())
 	{
 		folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO);
 	}
@@ -1004,7 +1004,7 @@ void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
 
 void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
 {
-	if (item->getFiltered() && !mItemSelected)
+	if (item->passedFilter() && !mItemSelected)
 	{
 		item->getRoot()->setSelection(item, FALSE, FALSE);
 		if (item->getParentFolder())
@@ -1017,7 +1017,7 @@ void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
 
 void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
 {
-	if (folder->getFiltered() && !mItemSelected)
+	if (folder->LLFolderViewItem::passedFilter() && !mItemSelected)
 	{
 		folder->getRoot()->setSelection(folder, FALSE, FALSE);
 		if (folder->getParentFolder())
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 74492e0005..aba4c088ab 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -254,18 +254,16 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 	
 	// Scroller
-	{
-		LLRect scroller_view_rect = getRect();
-		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
-		LLScrollContainer::Params scroller_params(params.scroll());
-		scroller_params.rect(scroller_view_rect);
-		mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
-		addChild(mScroller);
-		mScroller->addChild(mFolderRoot);
-		mFolderRoot->setScrollContainer(mScroller);
-		mFolderRoot->setFollowsAll();
-		mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
-	}
+	LLRect scroller_view_rect = getRect();
+	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+	LLScrollContainer::Params scroller_params(params.scroll());
+	scroller_params.rect(scroller_view_rect);
+	mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+	addChild(mScroller);
+	mScroller->addChild(mFolderRoot);
+	mFolderRoot->setScrollContainer(mScroller);
+	mFolderRoot->setFollowsAll();
+	mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
 
 	// Set up the callbacks from the inventory we're viewing, and then build everything.
 	mInventoryObserver = new LLInventoryPanelObserver(this);
@@ -344,12 +342,12 @@ void LLInventoryPanel::draw()
 
 const LLInventoryFilter* LLInventoryPanel::getFilter() const
 {
-	return &getFolderViewModel()->getFilter();
+	return getFolderViewModel()->getFilter();
 }
 
 LLInventoryFilter* LLInventoryPanel::getFilter()
 {
-	return &getFolderViewModel()->getFilter();
+	return getFolderViewModel()->getFilter();
 }
 
 void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
@@ -561,7 +559,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
 						if (new_parent != NULL)
 						{
 							// Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
-							view_item->getParentFolder()->extractItem(view_item);
 							view_item->addToFolder(new_parent);
 							addItemID(viewmodel_item->getUUID(), view_item);
 						}
@@ -1358,3 +1355,104 @@ void LLFolderViewModelItemInventory::requestSort()
 		mFolderViewItem->getParentFolder()->getViewModelItem()->requestSort();
 	}
 }
+
+bool LLFolderViewModelItemInventory::potentiallyVisible()
+{
+	return passedFilter() // we've passed the filter
+		|| getLastFilterGeneration() < mFolderViewItem->getRoot()->getFolderViewModel()->getFilter()->getFirstSuccessGeneration() // or we don't know yet
+		|| descendantsPassedFilter();
+}
+
+bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation) 
+{ 
+	if (filter_generation < 0) filter_generation = mFolderViewItem->getRoot()->getFolderViewModel()->getFilter()->getFirstSuccessGeneration();
+	return mPassedFolderFilter 
+		&& mLastFilterGeneration >= filter_generation
+		&& (mPassedFilter || descendantsPassedFilter(filter_generation));
+}
+
+bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation)
+{ 
+	if (filter_generation < 0) filter_generation = mFolderViewItem->getRoot()->getFolderViewModel()->getFilter()->getFirstSuccessGeneration();
+	return mMostFilteredDescendantGeneration >= filter_generation; 
+}
+
+void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation)
+{
+	mPassedFilter = passed;
+	mPassedFolderFilter = passed_folder;
+	mLastFilterGeneration = filter_generation;
+}
+
+void LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
+{
+	S32 filter_generation = filter.getCurrentGeneration();
+	S32 must_pass_generation = filter.getFirstRequiredGeneration();
+
+	// mMostFilteredDescendantGeneration might have been reset
+	// in which case we need to update it even for folders that
+	// don't need to be filtered anymore
+	if (item->getLastFilterGeneration() < filter_generation)
+	{
+		if (item->getLastFilterGeneration() >= must_pass_generation && 
+			!item->passedFilter(must_pass_generation))
+		{
+			// failed to pass an earlier filter that was a subset of the current one
+			// go ahead and flag this item as done
+			item->setPassedFilter(false, false, filter_generation);
+		}
+		else
+		{
+			//TODO RN:
+			item->filter( filter );
+		}
+	}
+
+	// track latest generation to pass any child items
+	if (item->passedFilter())
+	{
+		mMostFilteredDescendantGeneration = filter_generation;
+		//TODO RN: ensure this still happens
+		//requestArrange();
+	}
+}
+
+void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
+{
+	if(getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass
+		|| descendantsPassedFilter(filter.getFirstRequiredGeneration())) // or at least one descendant has passed the minimum requirement
+	{
+		// now query children
+		for (child_list_t::iterator iter = mChildren.begin();
+			iter != mChildren.end() && filter.getFilterCount() > 0;
+			++iter)
+		{
+			filterChildItem((*iter), filter);
+		}
+	}
+
+	// if we didn't use all filter iterations
+	// that means we filtered all of our descendants
+	// so filter ourselves now
+	if (filter.getFilterCount() > 0)
+	{
+		const BOOL previous_passed_filter = mPassedFilter;
+		const BOOL passed_filter = filter.check(this);
+		const BOOL passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) 
+								? filter.checkFolder(this)
+								: true;
+
+		// If our visibility will change as a result of this filter, then
+		// we need to be rearranged in our parent folder
+		LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
+		if (parent_folder && passed_filter != previous_passed_filter)
+		{
+			parent_folder->requestArrange();
+		}
+	
+		setPassedFilter(passed_filter, passed_filter_folder, filter.getCurrentGeneration());
+		//TODO RN: create interface for string highlighting
+		//mStringMatchOffset = filter.getStringMatchOffset(this);
+		filter.decrementFilterCount();
+	}
+}
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 645e2f6d76..35a3f9b5e1 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -62,6 +62,12 @@ public:
 	virtual EInventorySortGroup getSortGroup() const = 0;
 	virtual LLInventoryObject* getInventoryObject() const = 0;
 	virtual void requestSort();
+	virtual bool potentiallyVisible();
+	virtual bool passedFilter(S32 filter_generation = -1);
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1);
+	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
+	virtual void filter( LLFolderViewFilter& filter);
+	virtual void filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
 };
 
 class LLInventorySort
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 901c6379de..0b899d34f4 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -102,7 +102,7 @@ void LLCheckFolderState::doFolder(LLFolderViewFolder* folder)
 	// Counting only folders that pass the filter.
 	// The listener check allow us to avoid counting the folder view
 	// object itself because it has no listener assigned.
-	if (folder->hasFilteredDescendants() && folder->getViewModelItem())
+	if (folder->getViewModelItem()->descendantsPassedFilter())
 	{
 		if (folder->isOpen())
 		{
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index e3446fdb3a..33581160fd 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -227,7 +227,7 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
 	}
 	}
 
-        LLInventoryFilter* filter = getChild<LLInventoryPanel>("Recent   Items")->getFilter();
+        LLInventoryFilter* filter = findChild<LLInventoryPanel>("Recent   Items")->getFilter();
 		if (filter)
 		{
 			LLSD filterState;
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index da82d70f22..6a232a26f7 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -77,6 +77,7 @@ protected:
 	LLUUID mUUID;
 	std::string mName;
 	mutable std::string mDisplayName;
+	mutable std::string mSearchableName;
 	LLPanelObjectInventory* mPanel;
 	U32 mFlags;
 	LLAssetType::EType mAssetType;	
@@ -105,6 +106,8 @@ public:
 	// LLFolderViewModelItemInventory functionality
 	virtual const std::string& getName() const;
 	virtual const std::string& getDisplayName() const;
+	virtual const std::string& getSearchableName() const;
+
 	virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
 	/*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
 	virtual const LLUUID& getUUID() const { return mUUID; }
@@ -335,9 +338,17 @@ const std::string& LLTaskInvFVBridge::getDisplayName() const
 		}
 	}
 
+	mSearchableName.assign(mDisplayName + getLabelSuffix());
+
 	return mDisplayName;
 }
 
+const std::string& LLTaskInvFVBridge::getSearchableName() const
+{
+	return mSearchableName;
+}
+
+
 // BUG: No creation dates for task inventory
 time_t LLTaskInvFVBridge::getCreationDate() const
 {
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 194aa7f71b..b143240187 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -271,7 +271,7 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked()
 			if (outfit_folder)
 			{
 				outfit_folder->setOpen(!outfit_folder->isOpen());
-				root->setSelectionFromRoot(outfit_folder,TRUE);
+				root->setSelection(outfit_folder,TRUE);
 				root->scrollToShowSelection();
 			}
 		}
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 50d63911ad..654b18614a 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -623,10 +623,9 @@ void LLFloaterTexturePicker::draw()
 		LLFolderView* folder_view = mInventoryPanel->getRootFolder();
 		if (!folder_view) return;
 
-		LLInventoryFilter* filter = static_cast<LLInventoryFilter*>(folder_view->getFilter());
-		if (!filter) return;
+		LLInventoryFilter* filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
 
-		bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
+		bool is_filter_active = folder_view->getLastFilterGeneration() < filter->getCurrentGeneration() &&
 				filter->isNotDefault();
 
 		// After inventory panel filter is applied we have to update
@@ -637,8 +636,9 @@ void LLFloaterTexturePicker::draw()
 		if (!is_filter_active && !mSelectedItemPinned)
 		{
 			folder_view->setPinningSelectedItem(mSelectedItemPinned);
-			folder_view->dirtyFilter();
-			folder_view->arrangeFromRoot();
+			folder_view->getViewModelItem()->dirtyFilter();
+			//TODO RN: test
+			//folder_view->arrangeFromRoot();
 
 			mSelectedItemPinned = TRUE;
 		}
-- 
cgit v1.2.3


From 569c004057ef5da03e05bedf77d39159e5782458 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 27 Jun 2012 19:17:49 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose fixed crash on startup

---
 indra/newview/llfolderviewmodel.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 0216ba2a07..c5079712f5 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -310,7 +310,8 @@ public:
 		mPassedFolderFilter(false),
 		mFolderViewItem(NULL),
 		mLastFilterGeneration(-1),
-		mMostFilteredDescendantGeneration(-1)
+		mMostFilteredDescendantGeneration(-1),
+		mParent(NULL)
 	{}
 
 	void requestSort() { mSortVersion = -1; }
-- 
cgit v1.2.3


From e8fa07d6384c9eb2a0fb42b0e06abb6a0d5fdea9 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 28 Jun 2012 16:47:37 -0700
Subject: CHUI-82 : Fixed all icons to use the new Conv_*.png icons; please use
 those in the new UIs moving forward

---
 .../textures/icons/Conv_toolbar_add_person.png     | Bin 0 -> 322 bytes
 .../textures/icons/Conv_toolbar_arrow_ne.png       | Bin 0 -> 301 bytes
 .../textures/icons/Conv_toolbar_arrow_sw.png       | Bin 0 -> 293 bytes
 .../textures/icons/Conv_toolbar_call_log.png       | Bin 0 -> 546 bytes
 .../default/textures/icons/Conv_toolbar_close.png  | Bin 0 -> 262 bytes
 .../textures/icons/Conv_toolbar_collapse.png       | Bin 0 -> 663 bytes
 .../default/textures/icons/Conv_toolbar_expand.png | Bin 0 -> 662 bytes
 .../textures/icons/Conv_toolbar_hang_up.png        | Bin 0 -> 460 bytes
 .../textures/icons/Conv_toolbar_open_call.png      | Bin 0 -> 485 bytes
 .../default/textures/icons/Conv_toolbar_plus.png   | Bin 0 -> 195 bytes
 .../default/textures/icons/Conv_toolbar_sort.png   | Bin 0 -> 196 bytes
 indra/newview/skins/default/textures/textures.xml  |  14 ++++++++
 .../skins/default/xui/en/floater_im_container.xml  |  10 +++---
 .../skins/default/xui/en/floater_im_session.xml    |  36 ++++++++++-----------
 .../default/xui/en/panel_block_list_sidetray.xml   |   2 +-
 .../newview/skins/default/xui/en/panel_people.xml  |   8 ++---
 16 files changed, 42 insertions(+), 28 deletions(-)
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_close.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png
 create mode 100755 indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png

(limited to 'indra')

diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png
new file mode 100755
index 0000000000..f024c733f3
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png
new file mode 100755
index 0000000000..a19e720d42
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png
new file mode 100755
index 0000000000..7f3f42639d
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png
new file mode 100755
index 0000000000..2880eb766a
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png
new file mode 100755
index 0000000000..25a939d7f5
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png
new file mode 100755
index 0000000000..82baabde47
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png
new file mode 100755
index 0000000000..7d64abb042
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png
new file mode 100755
index 0000000000..f0da962c2d
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png
new file mode 100755
index 0000000000..0db001dcdb
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png
new file mode 100755
index 0000000000..0cf7edc2d4
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png
new file mode 100755
index 0000000000..a0c15a6d3e
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index eabcc68916..ce9474d5e5 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -160,7 +160,21 @@ with the same filename but different name
   <texture name="ComboButton_On" file_name="widgets/ComboButton_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
   <texture name="ComboButton_Off" file_name="widgets/ComboButton_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
   <texture name="ComboButton_UpOff" file_name="widgets/ComboButton_UpOff.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+
   <texture name="Container" file_name="containers/Container.png" preload="false" />
+
+  <texture name="Conv_toolbar_add_person" file_name="icons/Conv_toolbar_add_person.png" preload="false" />
+  <texture name="Conv_toolbar_arrow_ne" file_name="icons/Conv_toolbar_arrow_ne.png" preload="false" />
+  <texture name="Conv_toolbar_arrow_sw" file_name="icons/Conv_toolbar_arrow_sw.png" preload="false" />
+  <texture name="Conv_toolbar_call_log" file_name="icons/Conv_toolbar_call_log.png" preload="false" />
+  <texture name="Conv_toolbar_close" file_name="icons/Conv_toolbar_close.png" preload="false" />
+  <texture name="Conv_toolbar_collapse" file_name="icons/Conv_toolbar_collapse.png" preload="false" />
+  <texture name="Conv_toolbar_expand" file_name="icons/Conv_toolbar_expand.png" preload="false" />
+  <texture name="Conv_toolbar_hang_up" file_name="icons/Conv_toolbar_hang_up.png" preload="false" />
+  <texture name="Conv_toolbar_open_call" file_name="icons/Conv_toolbar_open_call.png" preload="false" />
+  <texture name="Conv_toolbar_plus" file_name="icons/Conv_toolbar_plus.png" preload="false" />
+  <texture name="Conv_toolbar_sort" file_name="icons/Conv_toolbar_sort.png" preload="false" />
+
   <texture name="Copy" file_name="icons/Copy.png" preload="false" />
   
   <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index ce40f44a64..8e434b5848 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -15,10 +15,10 @@
  width="680">
     <string
      name="collapse_icon"
-     value="TabIcon_Open_Off"/>
+     value="Conv_toolbar_collapse"/>
     <string
      name="expand_icon"
-     value="TabIcon_Close_Off"/>
+     value="Conv_toolbar_expand"/>
     <layout_stack
      animate="true" 
      follows="all"
@@ -53,7 +53,7 @@
                      follows="top|left"
                      height="25"
                      image_hover_unselected="Toolbar_Middle_Over"
-                     image_overlay="OptionsMenu_Off"
+                     image_overlay="Conv_toolbar_sort"
                      image_selected="Toolbar_Middle_Selected"
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
@@ -65,7 +65,7 @@
                      follows="top|left"
                      height="25"
                      image_hover_unselected="Toolbar_Middle_Over"
-                     image_overlay="AddItem_Off"
+                     image_overlay="Conv_toolbar_plus"
                      image_selected="Toolbar_Middle_Selected"
                       image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
@@ -84,7 +84,7 @@
                      follows="right|top"
                      height="25"
                      image_hover_unselected="Toolbar_Middle_Over"
-                     image_overlay="TabIcon_Open_Off"
+                     image_overlay="Conv_toolbar_collapse"
                      image_selected="Toolbar_Middle_Selected"
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 08bc46a506..32eb4ebdae 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -18,20 +18,20 @@
     <floater.string 
      name="NearbyChatTitle"
      value="Nearby Chat"/>
-    <floater.string name="call_btn_start">VoicePTT_Off</floater.string>
-    <floater.string name="call_btn_stop">VoicePTT_On</floater.string>
+    <floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string>
+    <floater.string name="call_btn_stop">Conv_toolbar_hang_up</floater.string>
     <floater.string
      name="collapse_icon"
-     value="TabIcon_Open_Off"/>
+     value="Conv_toolbar_collapse"/>
     <floater.string
      name="expand_icon"
-     value="TabIcon_Close_Off"/>
+     value="Conv_toolbar_expand"/>
     <floater.string
      name="tear_off_icon"
-     value="tearoffbox.tga"/>
+     value="Conv_toolbar_arrow_ne"/>
     <floater.string
      name="return_icon"
-     value="Icon_Dock_Foreground"/>
+     value="Conv_toolbar_arrow_sw"/>
     <view
         follows="all"
         layout="topleft"
@@ -52,10 +52,10 @@
                  menu_filename="menu_im_session_showmodes.xml"
                  follows="top|left"
                  height="25"
-                 image_hover_unselected="Toolbar_Left_Over"
-                 image_overlay="OptionsMenu_Off"
-                 image_selected="Toolbar_Left_Selected"
-                 image_unselected="Toolbar_Left_Off"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_sort"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  left="5"
                  name="view_options_btn"
@@ -66,7 +66,7 @@
                  follows="top|left"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="AddItem_Off"
+                 image_overlay="Conv_toolbar_add_person"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
@@ -77,10 +77,10 @@
              <button
                  follows="top|left"
                  height="25"
-                 image_hover_unselected="Toolbar_Right_Over"
-                 image_overlay="VoicePTT_Off"
-                 image_selected="Toolbar_Right_Selected"
-                 image_unselected="Toolbar_Right_Off"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_open_call"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  top="5"
                  left_pad="4"
@@ -90,7 +90,7 @@
                  follows="right|top"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Icon_Close_Foreground"
+                 image_overlay="Conv_toolbar_close"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
@@ -102,7 +102,7 @@
                  follows="right|top"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="TabIcon_Open_Off"
+                 image_overlay="Conv_toolbar_collapse"
                  image_selected="Toolbar_Middle_Selected"
              	 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
@@ -114,7 +114,7 @@
                  follows="right|top"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="tearoffbox.tga"
+                 image_overlay="Conv_toolbar_arrow_ne"
                  image_selected="Toolbar_Middle_Selected"
              	 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index f466504938..24f7d44cce 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -49,7 +49,7 @@
           follows="right"
           height="25"
           image_hover_unselected="Toolbar_Middle_Over"
-          image_overlay="Inv_Underpants"
+          image_overlay="Conv_toolbar_sort"
           image_selected="Toolbar_Middle_Selected"
           image_unselected="Toolbar_Middle_Off"
           layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 38a996547c..09156b41b5 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -122,7 +122,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Inv_Underpants"
+                 image_overlay="Conv_toolbar_sort"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
@@ -270,7 +270,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Inv_Underpants"
+                 image_overlay="Conv_toolbar_sort"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
@@ -425,7 +425,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Inv_Underpants"
+                 image_overlay="Conv_toolbar_sort"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
@@ -533,7 +533,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Inv_Underpants"
+                 image_overlay="Conv_toolbar_sort"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-- 
cgit v1.2.3


From 71deb6d500238900bf7bf62cf957a68c063ade56 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 29 Jun 2012 11:59:14 -0700
Subject: CHUI-164 : Fix crash when removing ad-hoc conversation. Turns out
 that sessions uuids are not constant so I shouldn't use them as index in the
 conversation list. More complete fix to follow.

---
 indra/newview/llimconversation.cpp     |  2 +-
 indra/newview/llimfloatercontainer.cpp | 34 ++++++++++++++++++++--------------
 indra/newview/llimfloatercontainer.h   |  2 +-
 3 files changed, 22 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index c734c3edd2..d7ef65edb6 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -359,7 +359,7 @@ void LLIMConversation::onClose(bool app_quitting)
 		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
 		if (im_box)
 		{
-            im_box->removeConversationListItem(mSessionID);
+            im_box->removeConversationListItem(mSessionID,this);
         }
     }
 }
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 34a9758c52..85cc8cf38b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -416,19 +416,14 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 		// Check if the item has changed
 		if (item->hasSameValues(name,floaterp))
 		{
-			// If it hasn't, nothing to do -> exit
+			// If it hasn't changed, nothing to do -> exit
 			return;
 		}
-		// If it has, remove it: it'll be recreated anew further down
-		removeConversationListItem(uuid,false);
 	}
 	
-	// Reverse find and clean up: we need to make sure that no other uuid is pointing to that same floater
-	LLUUID found_id = LLUUID::null;
-	if (findConversationItem(floaterp,found_id))
-	{
-		removeConversationListItem(found_id,false);
-	}
+	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
+	// and nothing wrong will happen removing it if it doesn't exist
+	removeConversationListItem(uuid,floaterp,false);
 
 	// Create a conversation item
 	LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, this);
@@ -451,21 +446,32 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 	return;
 }
 
-void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id, bool change_focus)
+void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id, LLFloater* floaterp, bool change_focus)
 {
+	// Reverse find : we need to find the item that point to that floater
+	// Note : the session UUID actually might change so we cannot really use it here
+	// *TODO : Change the structure so that we use the floaterp and not the uuid as a map index
+	LLUUID found_id = LLUUID::null;
+	if (!findConversationItem(floaterp,found_id))
+	{
+		// If the floater wasn't found, we trust the passed id
+		// Note: in most cases, the id doesn't correspond to any conversation either
+		found_id = session_id;
+	}
+
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(session_id);
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(found_id);
 	if (widget_it != mConversationsWidgets.end())
 	{
 		LLFolderViewItem* widget = widget_it->second;
 		delete widget;
 	}
-
+	
 	// Suppress the conversation items and widgets from their respective maps
-	mConversationsItems.erase(session_id);
-	mConversationsWidgets.erase(session_id);
+	mConversationsItems.erase(found_id);
+	mConversationsWidgets.erase(found_id);
 
 	// Reposition the leftover conversation items
 	LLRect panel_rect = mConversationsListPanel->getRect();
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 2a8cbf3e1c..181aaa38a8 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -186,7 +186,7 @@ private:
 	
 	// CHUI-137 : Temporary implementation of conversations list
 public:
-	void removeConversationListItem(const LLUUID& session_id, bool change_focus = true);
+	void removeConversationListItem(const LLUUID& session_id, LLFloater* floaterp, bool change_focus = true);
 	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
 	bool findConversationItem(LLFloater* floaterp, LLUUID& uuid);
 private:
-- 
cgit v1.2.3


From 5eab95955fec4d3dcb8b2f98c6c084d227e70b8c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 29 Jun 2012 14:29:56 -0700
Subject: CHUI-164 : Fix conversation list index using handle to floater rather
 than uuid. Simplify the code accordingly (suppress hacks).

---
 indra/newview/llimconversation.cpp     |  2 +-
 indra/newview/llimfloatercontainer.cpp | 48 +++++++++++++---------------------
 indra/newview/llimfloatercontainer.h   | 12 ++++-----
 3 files changed, 25 insertions(+), 37 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index d7ef65edb6..dc68c5cea1 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -359,7 +359,7 @@ void LLIMConversation::onClose(bool app_quitting)
 		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
 		if (im_box)
 		{
-            im_box->removeConversationListItem(mSessionID,this);
+            im_box->removeConversationListItem(this);
         }
     }
 }
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 85cc8cf38b..261b5f33a2 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -293,9 +293,9 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	if (visible)
 	{
 		// Make sure we have the Nearby Chat present when showing the conversation container
-		LLUUID nearbychat_uuid = LLUUID::null;	// Hacky but true: the session id for nearby chat is null
-		conversations_items_map::iterator item_it = mConversationsItems.find(nearbychat_uuid);
-		if (item_it == mConversationsItems.end())
+		LLUUID nearbychat_uuid = LLUUID::null;	// Hacky but true: the session id for nearby chat is always null
+		LLFloater* floaterp = findConversationItem(nearbychat_uuid);
+		if (floaterp == NULL)
 		{
 			// If not found, force the creation of the nearby chat conversation panel
 			// *TODO: find a way to move this to XML as a default panel or something like that
@@ -407,14 +407,14 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
 // CHUI-137 : Temporary implementation of conversations list
 void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp)
 {
-	// Check if the item is not already in the list, exit if it is and has the same name and points to the same floater (nothing to do)
+	// Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do)
 	// Note: this happens often, when reattaching a torn off conversation for instance
-	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
+	conversations_items_map::iterator item_it = mConversationsItems.find(floaterp);
 	if (item_it != mConversationsItems.end())
 	{
 		LLConversationItem* item = item_it->second;
 		// Check if the item has changed
-		if (item->hasSameValues(name,floaterp))
+		if (item->hasSameValues(name,uuid))
 		{
 			// If it hasn't changed, nothing to do -> exit
 			return;
@@ -423,15 +423,15 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 	
 	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
 	// and nothing wrong will happen removing it if it doesn't exist
-	removeConversationListItem(uuid,floaterp,false);
+	removeConversationListItem(floaterp,false);
 
 	// Create a conversation item
 	LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, this);
-	mConversationsItems[uuid] = item;
+	mConversationsItems[floaterp] = item;
 
 	// Create a widget from it
 	LLFolderViewItem* widget = createConversationItemWidget(item);
-	mConversationsWidgets[uuid] = widget;
+	mConversationsWidgets[floaterp] = widget;
 
 	// Add it to the UI
 	widget->setVisible(TRUE);
@@ -446,23 +446,12 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 	return;
 }
 
-void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id, LLFloater* floaterp, bool change_focus)
+void LLIMFloaterContainer::removeConversationListItem(LLFloater* floaterp, bool change_focus)
 {
-	// Reverse find : we need to find the item that point to that floater
-	// Note : the session UUID actually might change so we cannot really use it here
-	// *TODO : Change the structure so that we use the floaterp and not the uuid as a map index
-	LLUUID found_id = LLUUID::null;
-	if (!findConversationItem(floaterp,found_id))
-	{
-		// If the floater wasn't found, we trust the passed id
-		// Note: in most cases, the id doesn't correspond to any conversation either
-		found_id = session_id;
-	}
-
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(found_id);
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(floaterp);
 	if (widget_it != mConversationsWidgets.end())
 	{
 		LLFolderViewItem* widget = widget_it->second;
@@ -470,8 +459,8 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id,
 	}
 	
 	// Suppress the conversation items and widgets from their respective maps
-	mConversationsItems.erase(found_id);
-	mConversationsWidgets.erase(found_id);
+	mConversationsItems.erase(floaterp);
+	mConversationsWidgets.erase(floaterp);
 
 	// Reposition the leftover conversation items
 	LLRect panel_rect = mConversationsListPanel->getRect();
@@ -500,20 +489,19 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& session_id,
 	return;
 }
 
-bool LLIMFloaterContainer::findConversationItem(LLFloater* floaterp, LLUUID& uuid)
+LLFloater* LLIMFloaterContainer::findConversationItem(LLUUID& uuid)
 {
-	bool found = false;
+	LLFloater* floaterp = NULL;
 	for (conversations_items_map::iterator item_it = mConversationsItems.begin(); item_it != mConversationsItems.end(); ++item_it)
 	{
 		LLConversationItem* item = item_it->second;
-		uuid = item_it->first;
-		if (item->hasSameValue(floaterp))
+		if (item->hasSameValue(uuid))
 		{
-			found = true;
+			floaterp = item_it->first;
 			break;
 		}
 	}
-	return found;
+	return floaterp;
 }
 
 LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 181aaa38a8..2bbd371e8f 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -48,8 +48,8 @@ class LLIMFloaterContainer;
 // CHUI-137 : Temporary implementation of conversations list
 class LLConversationItem;
 
-typedef std::map<LLUUID, LLConversationItem*> conversations_items_map;
-typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
+typedef std::map<LLFloater*, LLConversationItem*> conversations_items_map;
+typedef std::map<LLFloater*, LLFolderViewItem*> conversations_widgets_map;
 
 // Conversation items: we hold a list of those and create an LLFolderViewItem widget for each  
 // that we tuck into the mConversationsListPanel. 
@@ -113,8 +113,8 @@ public:
 							void* cargo_data,
 							std::string& tooltip_msg) { return FALSE; }
 	
-	bool hasSameValues(std::string name, LLFloater* floaterp) { return ((name == mName) && (floaterp == mFloater)); }
-	bool hasSameValue(LLFloater* floaterp) { return (floaterp == mFloater); }
+	bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
+	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
 private:
 	std::string mName;
 	const LLUUID mUUID;
@@ -186,9 +186,9 @@ private:
 	
 	// CHUI-137 : Temporary implementation of conversations list
 public:
-	void removeConversationListItem(const LLUUID& session_id, LLFloater* floaterp, bool change_focus = true);
+	void removeConversationListItem(LLFloater* floaterp, bool change_focus = true);
 	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
-	bool findConversationItem(LLFloater* floaterp, LLUUID& uuid);
+	LLFloater* findConversationItem(LLUUID& uuid);
 private:
 	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 	// Conversation list data
-- 
cgit v1.2.3


From cd7d499ea779178d49be65d37e852712f82c3c90 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 28 Jun 2012 17:22:00 +0300
Subject: CHUI-168 FIXED, CHUI-183 FIXED Supress of a resizable and dragging
 and hide a title for the docked floater

---
 indra/newview/llimconversation.cpp | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index dc68c5cea1..acdd7ba46a 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -250,14 +250,16 @@ void LLIMConversation::updateHeaderAndToolbar()
 	bool is_expanded = is_hosted || is_participant_list_visible;
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
 
-	// The button (>>) should be disabled for torn off P2P conversations.
-	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat);
-
+	// toggle floater's drag handle and title visibility
 	if (mDragHandle)
 	{
-		// toggle floater's drag handle and title visibility
-		mDragHandle->setVisible(!is_hosted);
+		mDragHandle->setTitleVisible(!is_hosted);
+		setCanDrag(!is_hosted);
 	}
+	setCanResize(!is_hosted);
+
+	// The button (>>) should be disabled for torn off P2P conversations.
+	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat);
 
 	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
 
@@ -347,6 +349,8 @@ void LLIMConversation::onOpen(const LLSD& key)
 		host_floater->collapseMessagesPane(false);
 	}
 
+	setCanResize(TRUE);
+
 	updateHeaderAndToolbar();
 }
 
-- 
cgit v1.2.3


From ed7173c987cf4a5de2f3c9b9d792e5ac4006e833 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 28 Jun 2012 23:29:58 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose filtering mostly
 working

---
 indra/newview/llfolderview.cpp                     | 124 ++++++++++-----------
 indra/newview/llfolderviewitem.cpp                 |   5 +-
 indra/newview/llinventorybridge.cpp                |  47 ++++----
 indra/newview/llinventorybridge.h                  |   3 +
 indra/newview/llinventorypanel.cpp                 |  37 ++++--
 indra/newview/llinventorypanel.h                   |  18 ++-
 indra/newview/llpanelmarketplaceinboxinventory.cpp |   1 +
 .../newview/llpanelmarketplaceoutboxinventory.cpp  |   1 +
 indra/newview/llplacesinventorybridge.cpp          |   5 +
 indra/newview/llplacesinventorybridge.h            |   1 +
 indra/newview/llplacesinventorypanel.cpp           |   1 +
 11 files changed, 135 insertions(+), 108 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index a37fc7714b..0f7809d4b4 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -182,7 +182,6 @@ LLFolderView::LLFolderView(const Params& p)
 	mAutoSelectOverride(FALSE),
 	mNeedsAutoRename(FALSE),
 	mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME),	// This gets overridden by a pref immediately
-	mFilter(new LLInventoryFilter(LLInventoryFilter::Params().name(p.title))),
 	mShowSelectionContext(FALSE),
 	mShowSingleSelection(FALSE),
 	mArrangeGeneration(0),
@@ -288,9 +287,6 @@ LLFolderView::~LLFolderView( void )
 	mItems.clear();
 	mFolders.clear();
 
-	delete mFilter;
-	mFilter = NULL;
-
 	delete mViewModel;
 	mViewModel = NULL;
 }
@@ -302,6 +298,9 @@ BOOL LLFolderView::canFocusChildren() const
 
 BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 {
+	LLFolderViewFolder::addFolder(folder);
+
+	mFolders.remove(folder);
 	// enforce sort order of My Inventory followed by Library
 	if (((LLFolderViewModelItemInventory*)folder->getViewModelItem())->getUUID() == gInventory.getLibraryRootFolderID())
 	{
@@ -311,12 +310,7 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 	{
 		mFolders.insert(mFolders.begin(), folder);
 	}
-	folder->setOrigin(0, 0);
-	folder->reshape(getRect().getWidth(), 0);
-	folder->setVisible(FALSE);
-	addChild( folder );
-	folder->getViewModelItem()->dirtyFilter();
-	folder->requestArrange();
+
 	return TRUE;
 }
 
@@ -717,7 +711,7 @@ void LLFolderView::draw()
 	}
 	else if (mShowEmptyMessage)
 	{
-		if (!mViewModel->contentsReady() || getLastFilterGeneration() < mFilter->getFirstSuccessGeneration())
+		if (!mViewModel->contentsReady() || getLastFilterGeneration() < getFolderViewModel()->getFilter()->getFirstSuccessGeneration())
 		{
 			// TODO RN: Get this from filter
 			mStatusText = LLTrans::getString("Searching");
@@ -952,37 +946,36 @@ void LLFolderView::openSelectedItems( void )
 {
 	if(getVisible() && getEnabled())
 	{
-		// TODO RN: move to LLFolderViewModelInventory
-		//if (mSelectedItems.size() == 1)
-		//{
-		//	mSelectedItems.front()->openItem();
-		//}
-		//else
-		//{
-		//	LLMultiPreview* multi_previewp = new LLMultiPreview();
-		//	LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-		//	selected_items_t::iterator item_it;
-		//	for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-		//	{
-		//		// IT_{OBJECT,ATTACHMENT} creates LLProperties
-		//		// floaters; others create LLPreviews.  Put
-		//		// each one in the right type of container.
-		//		LLFolderViewModelItemInventory* listener = (*item_it)->getViewModelItem();
-		//		bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
-		//		if (is_prop)
-		//			LLFloater::setFloaterHost(multi_propertiesp);
-		//		else
-		//			LLFloater::setFloaterHost(multi_previewp);
-		//		(*item_it)->openItem();
-		//	}
-
-		//	LLFloater::setFloaterHost(NULL);
-		//	// *NOTE: LLMulti* will safely auto-delete when open'd
-		//	// without any children.
-		//	multi_previewp->openFloater(LLSD());
-		//	multi_propertiesp->openFloater(LLSD());
-		//}
+		if (mSelectedItems.size() == 1)
+		{
+			mSelectedItems.front()->openItem();
+		}
+		else
+		{
+			LLMultiPreview* multi_previewp = new LLMultiPreview();
+			LLMultiProperties* multi_propertiesp = new LLMultiProperties();
+
+			selected_items_t::iterator item_it;
+			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+			{
+				// IT_{OBJECT,ATTACHMENT} creates LLProperties
+				// floaters; others create LLPreviews.  Put
+				// each one in the right type of container.
+				LLFolderViewModelItemInventory* listener = static_cast<LLFolderViewModelItemInventory*>((*item_it)->getViewModelItem());
+				bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
+				if (is_prop)
+					LLFloater::setFloaterHost(multi_propertiesp);
+				else
+					LLFloater::setFloaterHost(multi_previewp);
+				listener->openItem();
+			}
+
+			LLFloater::setFloaterHost(NULL);
+			// *NOTE: LLMulti* will safely auto-delete when open'd
+			// without any children.
+			multi_previewp->openFloater(LLSD());
+			multi_propertiesp->openFloater(LLSD());
+		}
 	}
 }
 
@@ -990,28 +983,27 @@ void LLFolderView::propertiesSelectedItems( void )
 {
 	if(getVisible() && getEnabled())
 	{
-		// TODO RN: move to LLFolderViewModelInventory
-		//if (mSelectedItems.size() == 1)
-		//{
-		//	LLFolderViewItem* folder_item = mSelectedItems.front();
-		//	if(!folder_item) return;
-		//	folder_item->getViewModelItem()->showProperties();
-		//}
-		//else
-		//{
-		//	LLMultiProperties* multi_propertiesp = new LLMultiProperties();
+		if (mSelectedItems.size() == 1)
+		{
+			LLFolderViewItem* folder_item = mSelectedItems.front();
+			if(!folder_item) return;
+			folder_item->getViewModelItem()->showProperties();
+		}
+		else
+		{
+			LLMultiProperties* multi_propertiesp = new LLMultiProperties();
 
-		//	LLFloater::setFloaterHost(multi_propertiesp);
+			LLFloater::setFloaterHost(multi_propertiesp);
 
-		//	selected_items_t::iterator item_it;
-		//	for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-		//	{
-		//		(*item_it)->getViewModelItem()->showProperties();
-		//	}
+			selected_items_t::iterator item_it;
+			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+			{
+				(*item_it)->getViewModelItem()->showProperties();
+			}
 
-		//	LLFloater::setFloaterHost(NULL);
-		//	multi_propertiesp->openFloater(LLSD());
-		//}
+			LLFloater::setFloaterHost(NULL);
+			multi_propertiesp->openFloater(LLSD());
+		}
 	}
 }
 
@@ -1943,11 +1935,11 @@ void LLFolderView::doIdle()
 	
 	LLFastTimer t2(FTM_INVENTORY);
 
-	if (mFilter->isModified() && mFilter->isNotDefault())
+	if (getFolderViewModel()->getFilter()->isModified() && getFolderViewModel()->getFilter()->isNotDefault())
 	{
 		mNeedsAutoSelect = TRUE;
 	}
-	mFilter->clearModified();
+	getFolderViewModel()->getFilter()->clearModified();
 
 	// filter to determine visibility before arranging
 	filter(*(getFolderViewModel()->getFilter()));
@@ -1958,7 +1950,7 @@ void LLFolderView::doIdle()
 		LLFastTimer t3(FTM_AUTO_SELECT);
 		// select new item only if a filtered item not currently selected
 		LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
-		if (!mAutoSelectOverride && (!selected_itemp || selected_itemp->passedFilter()))
+		if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->getViewModelItem()->potentiallyVisible()))
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
@@ -1968,7 +1960,7 @@ void LLFolderView::doIdle()
 
 		// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
 		// Used by LLPlacesFolderView.
-		if (mFilter->showAllResults())
+		if (getFolderViewModel()->getFilter()->showAllResults())
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
@@ -1979,7 +1971,7 @@ void LLFolderView::doIdle()
 		scrollToShowSelection();
 	}
 
-	BOOL filter_finished = getLastFilterGeneration() >= mFilter->getCurrentGeneration() 
+	BOOL filter_finished = getLastFilterGeneration() >= getFolderViewModel()->getFilter()->getCurrentGeneration() 
 						&& mViewModel->contentsReady();
 	if (filter_finished 
 		|| gFocusMgr.childHasKeyboardFocus(inventory_panel) 
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index f65a13be1e..685a4cbf49 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -123,7 +123,10 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mListener(p.listener),
 	mIsMouseOverTitle(false)
 {
-	mListener->setFolderViewItem(this);
+	if (mListener)
+	{
+		mListener->setFolderViewItem(this);
+	}
 }
 
 BOOL LLFolderViewItem::postBuild()
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 45a2bffa6b..002278601a 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1026,6 +1026,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 										   LLAssetType::EType actual_asset_type,
 										   LLInventoryType::EType inv_type,
 										   LLInventoryPanel* inventory,
+										   LLFolderViewModelInventory* view_model,
 										   LLFolderView* root,
 										   const LLUUID& uuid,
 										   U32 flags)
@@ -1151,12 +1152,13 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 		default:
 			llinfos << "Unhandled asset type (llassetstorage.h): "
 					<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << llendl;
-			break;
+			break;	
 	}
 
 	if (new_listener)
 	{
 		new_listener->mInvType = inv_type;
+		new_listener->setRootViewModel(view_model);
 	}
 
 	return new_listener;
@@ -1332,6 +1334,7 @@ LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset
 														LLAssetType::EType actual_asset_type,
 														LLInventoryType::EType inv_type,
 														LLInventoryPanel* inventory,
+														LLFolderViewModelInventory* view_model,
 														LLFolderView* root,
 														const LLUUID& uuid,
 														U32 flags /* = 0x00 */) const
@@ -1340,6 +1343,7 @@ LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset
 									   actual_asset_type,
 									   inv_type,
 									   inventory,
+									   view_model,
 									   root,
 									   uuid,
 									   flags);
@@ -6472,41 +6476,30 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(
 	LLAssetType::EType actual_asset_type,
 	LLInventoryType::EType inv_type,
 	LLInventoryPanel* inventory,
+	LLFolderViewModelInventory* view_model,
 	LLFolderView* root,
 	const LLUUID& uuid,
 	U32 flags /*= 0x00*/ ) const
 {
 	LLInvFVBridge* new_listener = NULL;
-	switch(asset_type)
+	if (asset_type == LLAssetType::AT_CATEGORY 
+		&& actual_asset_type != LLAssetType::AT_LINK_FOLDER)
 	{
-	case LLAssetType::AT_CATEGORY:
-		if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
-		{
-			// *TODO: Create a link folder handler instead if it is necessary
-			new_listener = LLInventoryFVBridgeBuilder::createBridge(
-				asset_type,
-				actual_asset_type,
-				inv_type,
-				inventory,
-				root,
-				uuid,
-				flags);
-			break;
-		}
 		new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid);
-		break;
-	default:
-		new_listener = LLInventoryFVBridgeBuilder::createBridge(
-			asset_type,
-			actual_asset_type,
-			inv_type,
-			inventory,
-			root,
-			uuid,
-			flags);
+		new_listener->setRootViewModel(view_model);
+	}
+	else
+	{
+		new_listener = LLInventoryFVBridgeBuilder::createBridge(asset_type,
+																actual_asset_type,
+																inv_type,
+																inventory,
+																view_model,
+																root,
+																uuid,
+																flags);
 	}
 	return new_listener;
-
 }
 
 // EOF
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index b0582d003d..e235d9cf5f 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -66,6 +66,7 @@ public:
 									   LLAssetType::EType actual_asset_type,
 									   LLInventoryType::EType inv_type,
 									   LLInventoryPanel* inventory,
+									   LLFolderViewModelInventory* view_model,
 									   LLFolderView* root,
 									   const LLUUID& uuid,
 									   U32 flags = 0x00);
@@ -196,6 +197,7 @@ public:
 										LLAssetType::EType actual_asset_type,
 										LLInventoryType::EType inv_type,
 										LLInventoryPanel* inventory,
+										LLFolderViewModelInventory* view_model,
 										LLFolderView* root,
 										const LLUUID& uuid,
 										U32 flags = 0x00) const;
@@ -645,6 +647,7 @@ public:
 		LLAssetType::EType actual_asset_type,
 		LLInventoryType::EType inv_type,
 		LLInventoryPanel* inventory,
+		LLFolderViewModelInventory* view_model,
 		LLFolderView* root,
 		const LLUUID& uuid,
 		U32 flags = 0x00) const;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index aba4c088ab..73e20fc684 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -234,6 +234,7 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
 																	LLAssetType::AT_CATEGORY,
 																	LLInventoryType::IT_CATEGORY,
 																	this,
+																	&mInventoryViewModel,
 																	NULL,
 																	root_id);
 	
@@ -672,7 +673,7 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
 	p.parent_panel = this;
 	p.tool_tip = p.name;
 	p.listener = bridge;
-	p.view_model = new LLFolderViewModelInventory();
+	p.view_model = &mInventoryViewModel;
 	p.use_label_suffix = useLabelSuffix;
 	p.allow_multiselect = mAllowMultiSelect;
 	p.show_empty_message = mShowEmptyMessage;
@@ -736,6 +737,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   																			objectp->getType(),
   																			LLInventoryType::IT_CATEGORY,
   																			this,
+																			&mInventoryViewModel,
   																			mFolderRoot,
   																			objectp->getUUID());
   			if (new_listener)
@@ -751,6 +753,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   																			item->getActualType(),
   																			item->getInventoryType(),
   																			this,
+																			&mInventoryViewModel,
   																			mFolderRoot,
   																			item->getUUID(),
   																			item->getFlags());
@@ -1130,7 +1133,6 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
 	if (!floater_inventory)
 	{
 		llwarns << "Could not find My Inventory floater" << llendl;
-
 		return FALSE;
 	}
 
@@ -1347,25 +1349,27 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
 void LLFolderViewModelItemInventory::requestSort()
 {
 	LLFolderViewModelItemCommon::requestSort();
-	//TODO RN: need better way to get to root viewmodel, also consider reflecting hierarchy in viewmodel space as well
-	if (static_cast<LLFolderViewModelInventory*>(mFolderViewItem->getRoot()->getFolderViewModel())->getSorter().isByDate())
+	if (mRootViewModel->getSorter().isByDate())
 	{
 		// sort by date potentially affects parent folders which use a date
 		// derived from newest item in them
-		mFolderViewItem->getParentFolder()->getViewModelItem()->requestSort();
+		if (mParent)
+		{
+			mParent->requestSort();
+		}
 	}
 }
 
 bool LLFolderViewModelItemInventory::potentiallyVisible()
 {
 	return passedFilter() // we've passed the filter
-		|| getLastFilterGeneration() < mFolderViewItem->getRoot()->getFolderViewModel()->getFilter()->getFirstSuccessGeneration() // or we don't know yet
+		|| getLastFilterGeneration() < mRootViewModel->getFilter()->getFirstSuccessGeneration() // or we don't know yet
 		|| descendantsPassedFilter();
 }
 
 bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation) 
 { 
-	if (filter_generation < 0) filter_generation = mFolderViewItem->getRoot()->getFolderViewModel()->getFilter()->getFirstSuccessGeneration();
+	if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
 	return mPassedFolderFilter 
 		&& mLastFilterGeneration >= filter_generation
 		&& (mPassedFilter || descendantsPassedFilter(filter_generation));
@@ -1373,7 +1377,7 @@ bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation)
 
 bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation)
 { 
-	if (filter_generation < 0) filter_generation = mFolderViewItem->getRoot()->getFolderViewModel()->getFilter()->getFirstSuccessGeneration();
+	if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
 	return mMostFilteredDescendantGeneration >= filter_generation; 
 }
 
@@ -1419,8 +1423,9 @@ void LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite
 
 void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 {
-	if(getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass
-		|| descendantsPassedFilter(filter.getFirstRequiredGeneration())) // or at least one descendant has passed the minimum requirement
+	if(!mChildren.empty()
+		&& (getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass
+			|| descendantsPassedFilter(filter.getFirstRequiredGeneration()))) // or at least one descendant has passed the minimum requirement
 	{
 		// now query children
 		for (child_list_t::iterator iter = mChildren.begin();
@@ -1456,3 +1461,15 @@ void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 		filter.decrementFilterCount();
 	}
 }
+
+LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
+{
+	return &mInventoryViewModel;
+}
+
+
+const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
+{
+	return &mInventoryViewModel;
+}
+
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 35a3f9b5e1..55edf386d5 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -42,11 +42,19 @@
 class LLInvFVBridge;
 class LLInventoryFVBridgeBuilder;
 class LLInvPanelComplObserver;
+class LLFolderViewModelInventory;
 
 class LLFolderViewModelItemInventory
 	:	public LLFolderViewModelItemCommon
 {
 public:
+	LLFolderViewModelItemInventory()
+	:	mRootViewModel(NULL)
+	{}
+	void setRootViewModel(LLFolderViewModelInventory* root_view_model)
+	{
+		mRootViewModel = root_view_model;
+	}
 	virtual const LLUUID& getUUID() const = 0;
 	virtual time_t getCreationDate() const = 0;	// UTC seconds
 	virtual void setCreationDate(time_t creation_date_utc) = 0;
@@ -68,6 +76,8 @@ public:
 	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
 	virtual void filter( LLFolderViewFilter& filter);
 	virtual void filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+protected:
+	LLFolderViewModelInventory* mRootViewModel;
 };
 
 class LLInventorySort
@@ -243,8 +253,8 @@ public:
 	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
 	void updateSelection();
 	 	
-	LLFolderViewModelInventory* getFolderViewModel() { return &mViewModel; }
-	const LLFolderViewModelInventory* getFolderViewModel() const { return &mViewModel; }
+	LLFolderViewModelInventory* getFolderViewModel();
+	const LLFolderViewModelInventory* getFolderViewModel() const;
 
 protected:
 	void openStartFolderOrMyInventory(); // open the first level of inventory
@@ -262,8 +272,8 @@ protected:
 	LLFolderView*				mFolderRoot;
 	LLScrollContainer*			mScroller;
 
-	LLFolderViewModelInventory	mViewModel;
-	
+	LLFolderViewModelInventory	mInventoryViewModel;
+
 	std::map<LLUUID, LLFolderViewItem*> mItemMap;
 	/**
 	 * Pointer to LLInventoryFVBridgeBuilder.
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index f3096e862d..6e5a522297 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -111,6 +111,7 @@ void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& para
 																	LLAssetType::AT_CATEGORY,
 																	LLInventoryType::IT_CATEGORY,
 																	this,
+																	&mInventoryViewModel,
 																	NULL,
 																	root_id);
 	
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
index 783eeb11b8..2885dd6266 100644
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
@@ -77,6 +77,7 @@ void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par
 																	LLAssetType::AT_CATEGORY,
 																	LLInventoryType::IT_CATEGORY,
 																	this,
+																	&mInventoryViewModel,
 																	NULL,
 																	root_id);
 	
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index 97c5d531d2..af29ab7ea9 100644
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -151,6 +151,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 	LLAssetType::EType actual_asset_type,
 	LLInventoryType::EType inv_type,
 	LLInventoryPanel* inventory,
+	LLFolderViewModelInventory* view_model,
 	LLFolderView* root,
 	const LLUUID& uuid,
 	U32 flags/* = 0x00*/) const
@@ -164,6 +165,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 			llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl;
 		}
 		new_listener = new LLPlacesLandmarkBridge(inv_type, inventory, root, uuid, flags);
+		new_listener->setRootViewModel(view_model);
 		break;
 	case LLAssetType::AT_CATEGORY:
 		if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
@@ -174,12 +176,14 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 				actual_asset_type,
 				inv_type,
 				inventory,
+				view_model,
 				root,
 				uuid,
 				flags);
 			break;
 		}
 		new_listener = new LLPlacesFolderBridge(inv_type, inventory, root, uuid);
+		new_listener->setRootViewModel(view_model);
 		break;
 	default:
 		new_listener = LLInventoryFVBridgeBuilder::createBridge(
@@ -187,6 +191,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 			actual_asset_type,
 			inv_type,
 			inventory,
+			view_model,
 			root,
 			uuid,
 			flags);
diff --git a/indra/newview/llplacesinventorybridge.h b/indra/newview/llplacesinventorybridge.h
index 52beacef9c..791502990b 100644
--- a/indra/newview/llplacesinventorybridge.h
+++ b/indra/newview/llplacesinventorybridge.h
@@ -89,6 +89,7 @@ public:
 											LLAssetType::EType actual_asset_type,
 											LLInventoryType::EType inv_type,
 											LLInventoryPanel* inventory,
+											LLFolderViewModelInventory* view_model,
 											LLFolderView* root,
 											const LLUUID& uuid,
 											U32 flags = 0x00) const;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 1c2d75d88c..d95d5eac19 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -87,6 +87,7 @@ void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par
 													LLAssetType::AT_CATEGORY,
 													LLInventoryType::IT_CATEGORY,
 													this,
+													&mInventoryViewModel,
 													NULL,
 													root_id);
 	p.parent_panel = this;
-- 
cgit v1.2.3


From 604bbb22783d2460384e340592ca1781908f6dd8 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 28 Jun 2012 23:30:36 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose cleaned up ownership
 of viewmodel more filtering fixes

---
 indra/newview/llfolderview.h             |  1 -
 indra/newview/llfolderviewitem.h         |  1 -
 indra/newview/llinventoryfilter.cpp      | 17 +++++++----------
 indra/newview/llpanelmaininventory.cpp   | 24 ++++++++++++------------
 indra/newview/llpanelobjectinventory.cpp |  2 +-
 indra/newview/llpanelobjectinventory.h   |  2 ++
 6 files changed, 22 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index d261a5967d..8a0317f840 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -302,7 +302,6 @@ protected:
 	LLFrameTimer					mAutoOpenTimer;
 	LLFrameTimer					mSearchTimer;
 	std::string						mSearchString;
-	LLFolderViewFilter*				mFilter;
 	BOOL							mShowSelectionContext;
 	BOOL							mShowSingleSelection;
 	LLFrameTimer					mMultiSelectionFadeTimer;
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 7e48969826..a3c92a55e8 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -281,7 +281,6 @@ protected:
 	S32			mLastCalculatedWidth;
 	S32			mMostFilteredDescendantGeneration;
 	bool		mNeedsSort;
-	bool		mPassedFolderFilter;
 
 public:
 	typedef enum e_recurse_type
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index c7e0136368..08f1e541b5 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -95,16 +95,13 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
 		return passed_clipboard;
 	}
 
-	std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos;
+	std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : 0;
 
-	const BOOL passed_filtertype = checkAgainstFilterType(listener);
-	const BOOL passed_permissions = checkAgainstPermissions(listener);
-	const BOOL passed_filterlink = checkAgainstFilterLinks(listener);
-	const BOOL passed = (passed_filtertype &&
-						 passed_permissions &&
-						 passed_filterlink &&
-						 passed_clipboard &&
-						 (mFilterSubString.size() == 0 || string_offset !=  std::string::npos));
+	BOOL passed = string_offset !=  std::string::npos;
+	passed = passed && checkAgainstFilterType(listener);
+	passed = passed && checkAgainstPermissions(listener);
+	passed = passed && checkAgainstFilterLinks(listener);
+	passed = passed && passed_clipboard;
 
 	return passed;
 }
@@ -595,7 +592,7 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
 
 void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
 {
-	static LLCachedControl<U32> s_last_logoff(gSavedSettings, "LastLogoff", 0);
+	static LLCachedControl<U32> s_last_logoff(gSavedPerAccountSettings, "LastLogoff", 0);
 	if (sl && !isSinceLogoff())
 	{
 		setDateRange(s_last_logoff(), time_max());
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 33581160fd..6cef1f877b 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -222,21 +222,21 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
 			if (p.validateBlock(false))
 			{
 				LLParamSDParser().writeSD(filterState, p);
-			filterRoot[filter->getName()] = filterState;
+				filterRoot[filter->getName()] = filterState;
+			}
 		}
 	}
-	}
 
-        LLInventoryFilter* filter = findChild<LLInventoryPanel>("Recent   Items")->getFilter();
-		if (filter)
-		{
-			LLSD filterState;
-			LLInventoryFilter::Params p;
-			filter->toParams(p);
-			LLParamSDParser parser;
-			parser.writeSD(filterState, p);
-			filterRoot[filter->getName()] = filterState;
-		}
+	LLInventoryFilter* filter = findChild<LLInventoryPanel>("Recent Items")->getFilter();
+	if (filter)
+	{
+		LLSD filterState;
+		LLInventoryFilter::Params p;
+		filter->toParams(p);
+		LLParamSDParser parser;
+		parser.writeSD(filterState, p);
+		filterRoot[filter->getName()] = filterState;
+	}
 
 	std::ostringstream filterSaveName;
 	filterSaveName << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, FILTERS_FILENAME);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 6a232a26f7..d0b9072ade 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1562,7 +1562,7 @@ void LLPanelObjectInventory::reset()
 	p.tool_tip= LLTrans::getString("PanelContentsTooltip");
 	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
 	p.folder_indentation = -14; // subtract space normally reserved for folder expanders
-	p.view_model = new LLFolderViewModelInventory();
+	p.view_model = &mInventoryViewModel;
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
 	//TODO RN: make this happen by manipulating filter object directly
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 607b705f7f..7e857f8b31 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -29,6 +29,7 @@
 
 #include "llvoinventorylistener.h"
 #include "llpanel.h"
+#include "llinventorypanel.h" // for LLFolderViewModelInventory
 
 #include "llinventory.h"
 
@@ -94,6 +95,7 @@ private:
 	BOOL mHaveInventory;
 	BOOL mIsInventoryEmpty;
 	BOOL mInventoryNeedsUpdate;
+	LLFolderViewModelInventory	mInventoryViewModel;	
 };
 
 #endif // LL_LLPANELOBJECTINVENTORY_H
-- 
cgit v1.2.3


From 07afce2ac86c4c66e8b094ecf977ee5ec5566671 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 29 Jun 2012 09:44:22 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose fixed build

---
 indra/newview/llfolderview.cpp | 48 +++++++++++++++++++++---------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 0f7809d4b4..e007c58497 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -981,30 +981,30 @@ void LLFolderView::openSelectedItems( void )
 
 void LLFolderView::propertiesSelectedItems( void )
 {
-	if(getVisible() && getEnabled())
-	{
-		if (mSelectedItems.size() == 1)
-		{
-			LLFolderViewItem* folder_item = mSelectedItems.front();
-			if(!folder_item) return;
-			folder_item->getViewModelItem()->showProperties();
-		}
-		else
-		{
-			LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-			LLFloater::setFloaterHost(multi_propertiesp);
-
-			selected_items_t::iterator item_it;
-			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-			{
-				(*item_it)->getViewModelItem()->showProperties();
-			}
-
-			LLFloater::setFloaterHost(NULL);
-			multi_propertiesp->openFloater(LLSD());
-		}
-	}
+	//if(getVisible() && getEnabled())
+	//{
+	//	if (mSelectedItems.size() == 1)
+	//	{
+	//		LLFolderViewItem* folder_item = mSelectedItems.front();
+	//		if(!folder_item) return;
+	//		folder_item->getViewModelItem()->showProperties();
+	//	}
+	//	else
+	//	{
+	//		LLMultiProperties* multi_propertiesp = new LLMultiProperties();
+
+	//		LLFloater::setFloaterHost(multi_propertiesp);
+
+	//		selected_items_t::iterator item_it;
+	//		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+	//		{
+	//			(*item_it)->getViewModelItem()->showProperties();
+	//		}
+
+	//		LLFloater::setFloaterHost(NULL);
+	//		multi_propertiesp->openFloater(LLSD());
+	//	}
+	//}
 }
 
 void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type)
-- 
cgit v1.2.3


From 062cae9a4880f7672df7f6189e01b2bff15f42f1 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 29 Jun 2012 15:44:08 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose cleaned up some stale
 TODOs worked on getting initial inventory display to work consistently

---
 indra/newview/llfolderview.cpp           |  2 +-
 indra/newview/llfolderviewmodel.h        | 13 +++---------
 indra/newview/llinventoryfilter.cpp      |  3 +--
 indra/newview/llinventorypanel.cpp       | 34 ++++++++++++++++++++++++--------
 indra/newview/llinventorypanel.h         |  4 ++--
 indra/newview/llpanelobjectinventory.cpp |  2 +-
 indra/newview/lltexturectrl.cpp          |  2 +-
 7 files changed, 35 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index e007c58497..5844c58e09 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -713,7 +713,6 @@ void LLFolderView::draw()
 	{
 		if (!mViewModel->contentsReady() || getLastFilterGeneration() < getFolderViewModel()->getFilter()->getFirstSuccessGeneration())
 		{
-			// TODO RN: Get this from filter
 			mStatusText = LLTrans::getString("Searching");
 		}
 		else
@@ -981,6 +980,7 @@ void LLFolderView::openSelectedItems( void )
 
 void LLFolderView::propertiesSelectedItems( void )
 {
+	//TODO RN: get working again
 	//if(getVisible() && getEnabled())
 	//{
 	//	if (mSelectedItems.size() == 1)
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index c5079712f5..5304613219 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -122,7 +122,6 @@ public:
 	virtual void requestSortAll() = 0;
 
 	virtual void sort(class LLFolderViewFolder*) = 0;
-	virtual void filter(class LLFolderViewFolder*) = 0;
 
 	virtual bool contentsReady() = 0;
 	virtual void setFolderView(LLFolderView* folder_view) = 0;
@@ -208,12 +207,6 @@ public:
 		}
 	}
 
-	//TODO RN: fix this
-	void filter(LLFolderViewFolder* folder)
-	{
-		
-	}
-
 protected:
 	SortType		mSorter;
 	FilterType		mFilter;
@@ -264,7 +257,7 @@ public:
 	
 	virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
 
-	virtual void filter( LLFolderViewFilter& filter) = 0;
+	virtual bool filter( LLFolderViewFilter& filter) = 0;
 	virtual bool passedFilter(S32 filter_generation = -1) = 0;
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
 	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) = 0;
@@ -306,8 +299,8 @@ class LLFolderViewModelItemCommon : public LLFolderViewModelItem
 public:
 	LLFolderViewModelItemCommon()
 	:	mSortVersion(-1),
-		mPassedFilter(false),
-		mPassedFolderFilter(false),
+		mPassedFilter(true),
+		mPassedFolderFilter(true),
 		mFolderViewItem(NULL),
 		mLastFilterGeneration(-1),
 		mMostFilteredDescendantGeneration(-1),
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 08f1e541b5..6a33130322 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -159,7 +159,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 		// (e.g. versus in-world object contents).
 		const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
 		if (!cat)
-			return false;
+			return folder_id.isNull();
 		LLFolderType::EType cat_type = cat->getPreferredType();
 		if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0))
 			return false;
@@ -1091,7 +1091,6 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
 	mEmptyLookupMessage = message;
 }
 
-// TODO RN: turn this into a param and move to llfolderviewmodelinterface
 std::string LLInventoryFilter::getEmptyLookupMessage() const
 {
 	LLStringUtil::format_map_t args;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 73e20fc684..e4cabcc988 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1388,10 +1388,12 @@ void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_fo
 	mLastFilterGeneration = filter_generation;
 }
 
-void LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
+bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
 {
+	bool passed_filter_before = item->passedFilter();
 	S32 filter_generation = filter.getCurrentGeneration();
 	S32 must_pass_generation = filter.getFirstRequiredGeneration();
+	bool changed = false;
 
 	// mMostFilteredDescendantGeneration might have been reset
 	// in which case we need to update it even for folders that
@@ -1407,22 +1409,37 @@ void LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite
 		}
 		else
 		{
-			//TODO RN:
-			item->filter( filter );
+			changed |= item->filter( filter );
 		}
 	}
 
 	// track latest generation to pass any child items
 	if (item->passedFilter())
 	{
-		mMostFilteredDescendantGeneration = filter_generation;
-		//TODO RN: ensure this still happens
-		//requestArrange();
+		LLFolderViewModelItemInventory* view_model = this;
+		
+		while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation)
+		{
+			view_model->mMostFilteredDescendantGeneration = filter_generation;
+			view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent);
+		}
+	}
+
+	changed |= (item->passedFilter() != passed_filter_before);
+	if (changed)
+	{
+		//TODO RN: ensure this still happens, but without dependency on folderview
+		LLFolderViewFolder* parent = mFolderViewItem->getParentFolder();
+		if (parent) parent->requestArrange();
 	}
+
+	return changed;
 }
 
-void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
+bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 {
+	bool changed = false;
+
 	if(!mChildren.empty()
 		&& (getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass
 			|| descendantsPassedFilter(filter.getFirstRequiredGeneration()))) // or at least one descendant has passed the minimum requirement
@@ -1432,7 +1449,7 @@ void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 			iter != mChildren.end() && filter.getFilterCount() > 0;
 			++iter)
 		{
-			filterChildItem((*iter), filter);
+			changed |= filterChildItem((*iter), filter);
 		}
 	}
 
@@ -1460,6 +1477,7 @@ void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 		//mStringMatchOffset = filter.getStringMatchOffset(this);
 		filter.decrementFilterCount();
 	}
+	return changed;
 }
 
 LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 55edf386d5..3195d9a369 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -74,8 +74,8 @@ public:
 	virtual bool passedFilter(S32 filter_generation = -1);
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1);
 	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
-	virtual void filter( LLFolderViewFilter& filter);
-	virtual void filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+	virtual bool filter( LLFolderViewFilter& filter);
+	virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
 protected:
 	LLFolderViewModelInventory* mRootViewModel;
 };
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index d0b9072ade..450e1f7ed0 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1566,7 +1566,7 @@ void LLPanelObjectInventory::reset()
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
 	//TODO RN: make this happen by manipulating filter object directly
-	//mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+	static_cast<LLInventoryFilter*>(mFolders->getFolderViewModel()->getFilter())->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
 	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
 	if (hasFocus())
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 654b18614a..61a0331b72 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -637,7 +637,7 @@ void LLFloaterTexturePicker::draw()
 		{
 			folder_view->setPinningSelectedItem(mSelectedItemPinned);
 			folder_view->getViewModelItem()->dirtyFilter();
-			//TODO RN: test
+			//TODO RN: test..still works without this?
 			//folder_view->arrangeFromRoot();
 
 			mSelectedItemPinned = TRUE;
-- 
cgit v1.2.3


From 38eb726ca8ecbc52f9afe2181474074a8bc59211 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 2 Jul 2012 15:27:19 +0300
Subject: CHUI-103 FIXED (Implement changes to compact chat view)  Change
 coloration

---
 indra/newview/llchathistory.cpp | 47 ++++++++++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index dcd6d25888..80be753d9e 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -734,17 +734,23 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	}
 
 	LLColor4 txt_color = LLUIColorTable::instance().getColor("White");
+	LLColor4 name_color(txt_color);
+
 	LLViewerChat::getChatColor(chat,txt_color);
 	LLFontGL* fontp = LLViewerChat::getChatFont();	
 	std::string font_name = LLFontGL::nameFromFont(fontp);
 	std::string font_size = LLFontGL::sizeFromFont(fontp);
 
-	LLStyle::Params style_params;
-	style_params.color(txt_color);
-	style_params.readonly_color(txt_color);
-	style_params.font.name(font_name);
-	style_params.font.size(font_size);	
-	style_params.font.style(input_append_params.font.style);
+	LLStyle::Params body_message_params;
+	body_message_params.color(txt_color);
+	body_message_params.readonly_color(txt_color);
+	body_message_params.font.name(font_name);
+	body_message_params.font.size(font_size);
+	body_message_params.font.style(input_append_params.font.style);
+
+	LLStyle::Params name_params(body_message_params);
+	name_params.color(name_color);
+	name_params.readonly_color(name_color);
 
 	std::string prefix = chat.mText.substr(0, 4);
 
@@ -767,7 +773,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC)
 	{
 		delimiter = LLStringUtil::null;
-		style_params.font.style = "ITALIC";
+		name_params.font.style = "ITALIC";
 	}
 
 	bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
@@ -775,18 +781,20 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	if (message_from_log)
 	{
 		txt_color = LLColor4::grey;
-		style_params.color(txt_color);
-		style_params.readonly_color(txt_color);
+		body_message_params.color(txt_color);
+		body_message_params.readonly_color(txt_color);
+		name_params.color(txt_color);
+		name_params.readonly_color(txt_color);
 	}
 
 	bool prependNewLineState = mEditor->getText().size() != 0;
 
-	// show timestamps and names in the compact mode
+	// compact mode: show a timestamp and name
 	if (use_plain_text_chat_history)
 	{
 		square_brackets = chat.mFromName == SYSTEM_FROM;
 
-		LLStyle::Params timestamp_style(style_params);
+		LLStyle::Params timestamp_style(body_message_params);
 
 		// out of the timestamp
 		if (args["show_time"].asBoolean())
@@ -804,7 +812,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
         // out the opening square bracket (if need)
 		if (square_brackets)
 		{
-			mEditor->appendText("[", prependNewLineState, style_params);
+			mEditor->appendText("[", prependNewLineState, body_message_params);
 			prependNewLineState = false;
 		}
 
@@ -819,7 +827,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 
 				// set the link for the object name to be the objectim SLapp
 				// (don't let object names with hyperlinks override our objectim Url)
-				LLStyle::Params link_params(style_params);
+				LLStyle::Params link_params(body_message_params);
 				LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
 				link_params.color = link_color;
 				link_params.readonly_color = link_color;
@@ -831,7 +839,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			}
 			else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
 			{
-				LLStyle::Params link_params(style_params);
+				LLStyle::Params link_params(body_message_params);
 				link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));
 
 				if (from_me)
@@ -852,7 +860,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			else
 			{
 				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
-						prependNewLineState, style_params);
+						prependNewLineState, body_message_params);
 				prependNewLineState = false;
 			}
 		}
@@ -880,7 +888,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		}
 		else
 		{
-			view = getHeader(chat, style_params, args);
+			view = getHeader(chat, name_params, args);
 			if (mEditor->getText().size() == 0)
 				p.top_pad = 0;
 			else
@@ -909,6 +917,9 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		mIsLastMessageFromLog = message_from_log;
 	}
 
+	// body of the message processing
+
+	// notify processing
 	if (chat.mNotifId.notNull())
 	{
 		LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId);
@@ -932,6 +943,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			mEditor->appendWidget(params, "\n", false);
 		}
 	}
+
+	// usual messages showing
 	else
 	{
 		std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
@@ -959,7 +972,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			message += "]";
 		}
 
-		mEditor->appendText(message, prependNewLineState, style_params);
+		mEditor->appendText(message, prependNewLineState, body_message_params);
 		prependNewLineState = false;
 	}
 
-- 
cgit v1.2.3


From f22e5df8b6890aab659916361d42479ca3825be9 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Mon, 2 Jul 2012 17:46:34 +0300
Subject: CHUI-172 WIP Fixed drawing the nearby chat toast contents. Fixed
 warnings when creating a nearby chat toast.

---
 indra/newview/llchatitemscontainerctrl.cpp | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 477bdb3967..61772b4bb7 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -96,8 +96,15 @@ void	LLNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_p
 {
 	LLPanel::reshape(width, height,called_from_parent);
 
-	LLUICtrl* msg_text = getChild<LLUICtrl>("msg_text", false);
-	LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
+	// reshape() may be called from LLView::initFromParams() before the children are created.
+	// We call findChild() instead of getChild() here to avoid creating dummy controls.
+	LLUICtrl* msg_text = findChild<LLUICtrl>("msg_text", false);
+	LLUICtrl* icon = findChild<LLUICtrl>("avatar_icon", false);
+
+	if (!msg_text || !icon)
+	{
+		return;
+	}
 
 	LLRect msg_text_rect = msg_text->getRect();
 	LLRect avatar_rect = icon->getRect();
@@ -355,6 +362,8 @@ BOOL	LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
 }
 void LLNearbyChatToastPanel::draw()
 {
+	LLPanel::draw();
+
 	if(mIsDirty)
 	{
 		LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon", false);
-- 
cgit v1.2.3


From 1bd52dfbdc3607bbd9ea86c715ce63b17d5a557f Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 2 Jul 2012 17:57:29 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose refactored source
 files, moving logic into llfolderviewmodel*.cpp filter logic tweaks purging
 and moving inventory now properly cleans up view model

---
 indra/newview/CMakeLists.txt                 |   3 +
 indra/newview/llfolderview.cpp               |  27 +---
 indra/newview/llfolderviewitem.cpp           |  19 +--
 indra/newview/llfolderviewitem.h             |  10 +-
 indra/newview/llfolderviewmodel.cpp          |  54 +++++++
 indra/newview/llfolderviewmodel.h            |  25 ++-
 indra/newview/llfolderviewmodelinventory.cpp | 225 +++++++++++++++++++++++++++
 indra/newview/llfolderviewmodelinventory.h   | 107 +++++++++++++
 indra/newview/llinventoryfilter.cpp          |  24 ---
 indra/newview/llinventorypanel.cpp           | 201 +-----------------------
 indra/newview/llinventorypanel.h             |  78 +---------
 indra/newview/lltexturectrl.cpp              |   4 +-
 12 files changed, 429 insertions(+), 348 deletions(-)
 create mode 100644 indra/newview/llfolderviewmodel.cpp
 create mode 100644 indra/newview/llfolderviewmodelinventory.cpp
 create mode 100644 indra/newview/llfolderviewmodelinventory.h

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 4f447fd35b..dee37bd5e8 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -253,6 +253,8 @@ set(viewer_SOURCE_FILES
     llfloaterworldmap.cpp
     llfolderview.cpp
     llfolderviewitem.cpp
+    llfolderviewmodel.cpp
+    llfolderviewmodelinventory.cpp
     llfollowcam.cpp
     llfriendcard.cpp
     llgesturelistener.cpp
@@ -809,6 +811,7 @@ set(viewer_HEADER_FILES
     llfloaterworldmap.h
     llfolderview.h
     llfolderviewmodel.h
+    llfolderviewmodelinventory.h
     llfolderviewitem.h
     llfollowcam.h
     llfriendcard.h
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 5844c58e09..90c78d98b0 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -259,7 +259,7 @@ LLFolderView::LLFolderView(const Params& p)
 	menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
 	mPopupMenuHandle = menu->getHandle();
 
-	mListener->openItem();
+	mViewModelItem->openItem();
 }
 
 // Destroys the object
@@ -363,11 +363,7 @@ void LLFolderView::filter( LLFolderViewFilter& filter )
 	LLFastTimer t2(FTM_FILTER);
 	filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
 
-	if (getLastFilterGeneration() < filter.getCurrentGeneration())
-	{
-		mMinWidth = 0;
-		getViewModelItem()->filter(filter);
-	}
+	getViewModelItem()->filter(filter);
 }
 
 void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -706,20 +702,11 @@ void LLFolderView::draw()
 
 	if (hasVisibleChildren())
 	{
-		mStatusText.clear();
 		mStatusTextBox->setVisible( FALSE );
 	}
 	else if (mShowEmptyMessage)
 	{
-		if (!mViewModel->contentsReady() || getLastFilterGeneration() < getFolderViewModel()->getFilter()->getFirstSuccessGeneration())
-		{
-			mStatusText = LLTrans::getString("Searching");
-		}
-		else
-		{
-			mStatusText = getFolderViewModel()->getFilter()->getEmptyLookupMessage();
-		}
-		mStatusTextBox->setValue(mStatusText);
+		mStatusTextBox->setValue(getFolderViewModel()->getStatusText());
 		mStatusTextBox->setVisible( TRUE );
 		
 		// firstly reshape message textbox with current size. This is necessary to
@@ -1971,7 +1958,7 @@ void LLFolderView::doIdle()
 		scrollToShowSelection();
 	}
 
-	BOOL filter_finished = getLastFilterGeneration() >= getFolderViewModel()->getFilter()->getCurrentGeneration() 
+	BOOL filter_finished = getViewModelItem()->passedFilter()
 						&& mViewModel->contentsReady();
 	if (filter_finished 
 		|| gFocusMgr.childHasKeyboardFocus(inventory_panel) 
@@ -2264,9 +2251,3 @@ S32 LLFolderView::getItemHeight()
 	}
 	return 0;
 }
-
-//TODO RN: move to llfolderviewmodel.cpp file
-bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
-{
-	return item->getSortVersion() < mTargetSortVersion;
-}
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 685a4cbf49..ac389c9189 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -120,12 +120,12 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mDragAndDropTarget(FALSE),
 	mLabel(p.name),
 	mRoot(p.root),
-	mListener(p.listener),
+	mViewModelItem(p.listener),
 	mIsMouseOverTitle(false)
 {
-	if (mListener)
+	if (mViewModelItem)
 	{
-		mListener->setFolderViewItem(this);
+		mViewModelItem->setFolderViewItem(this);
 	}
 }
 
@@ -138,8 +138,8 @@ BOOL LLFolderViewItem::postBuild()
 // Destroys the object
 LLFolderViewItem::~LLFolderViewItem( void )
 {
-	delete mListener;
-	mListener = NULL;
+	delete mViewModelItem;
+	mViewModelItem = NULL;
 }
 
 LLFolderView* LLFolderViewItem::getRoot()
@@ -837,12 +837,6 @@ LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
 	return getRoot()->getFolderViewModel();
 }
 
-S32 LLFolderViewItem::getLastFilterGeneration() const
-{
-	return getViewModelItem()->getLastFilterGeneration();
-}
-
-
 
 ///----------------------------------------------------------------------------
 /// Class LLFolderViewFolder
@@ -1446,6 +1440,7 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
 		mItems.erase(it);
 	}
 	//item has been removed, need to update filter
+	getViewModelItem()->removeChild(item->getViewModelItem());
 	getViewModelItem()->dirtyFilter();
 	//because an item is going away regardless of filter status, force rearrange
 	requestArrange();
@@ -1638,7 +1633,7 @@ BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
 													EAcceptance* accept,
 													std::string& tooltip_msg)
 {
-	BOOL accepted = mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
+	BOOL accepted = mViewModelItem->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
 	if (accepted) 
 	{
 		mDragAndDropTarget = TRUE;
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index a3c92a55e8..581ec7239e 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -92,13 +92,12 @@ protected:
 	S32							mLabelWidth;
 	bool						mLabelWidthDirty;
 	LLFolderViewFolder*			mParentFolder;
-	LLFolderViewModelItem*		mListener;
+	LLFolderViewModelItem*		mViewModelItem;
 	BOOL						mIsCurSelection;
 	BOOL						mSelectPending;
 	LLFontGL::StyleFlags		mLabelStyle;
 	std::string					mLabelSuffix;
 	LLUIImagePtr				mIcon;
-	std::string					mStatusText;
 	LLUIImagePtr				mIconOpen;
 	LLUIImagePtr				mIconOverlay;
 	BOOL						mHasVisibleChildren;
@@ -136,9 +135,6 @@ public:
 	virtual S32 arrange( S32* width, S32* height );
 	virtual S32 getItemHeight();
 
-	// updates filter serial number and optionally propagated value up to root
-	S32		getLastFilterGeneration() const;
-
 	// If 'selection' is 'this' then note that otherwise ignore.
 	// Returns TRUE if this item ends up being selected.
 	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
@@ -202,8 +198,8 @@ public:
 	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
 	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
 
-	const LLFolderViewModelItem* getViewModelItem( void ) const { return mListener; }
-	LLFolderViewModelItem* getViewModelItem( void ) { return mListener; }
+	const LLFolderViewModelItem* getViewModelItem( void ) const { return mViewModelItem; }
+	LLFolderViewModelItem* getViewModelItem( void ) { return mViewModelItem; }
 
 	const LLFolderViewModelInterface* getFolderViewModel( void ) const;
 	LLFolderViewModelInterface* getFolderViewModel( void );
diff --git a/indra/newview/llfolderviewmodel.cpp b/indra/newview/llfolderviewmodel.cpp
new file mode 100644
index 0000000000..92db84156e
--- /dev/null
+++ b/indra/newview/llfolderviewmodel.cpp
@@ -0,0 +1,54 @@
+/** 
+ * @file llfolderviewmodel.cpp
+ * @brief Implementation of the view model collection of classes.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfolderviewmodel.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+
+bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
+{
+	return item->getSortVersion() < mTargetSortVersion;
+}
+
+std::string LLFolderViewModelCommon::getStatusText()
+{
+	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter()->getCurrentGeneration())
+	{
+		return LLTrans::getString("Searching");
+	}
+	else
+	{
+		return getFilter()->getEmptyLookupMessage();
+	}
+}
+
+void LLFolderViewModelCommon::filter()
+{
+	getFilter()->setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
+	mFolderView->getViewModelItem()->filter(*getFilter());
+}
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 5304613219..8a16ec3eff 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -28,6 +28,7 @@
 #include "lldarray.h"	// *TODO: convert to std::vector
 #include "llfoldertype.h"
 #include "llfontgl.h"	// just for StyleFlags enum
+#include "llfolderview.h"
 #include "llfolderviewitem.h"
 #include "llinventorytype.h"
 #include "llpermissionsflags.h"
@@ -122,11 +123,13 @@ public:
 	virtual void requestSortAll() = 0;
 
 	virtual void sort(class LLFolderViewFolder*) = 0;
+	virtual void filter() = 0;
 
 	virtual bool contentsReady() = 0;
 	virtual void setFolderView(LLFolderView* folder_view) = 0;
 	virtual LLFolderViewFilter* getFilter() = 0;
 	virtual const LLFolderViewFilter* getFilter() const = 0;
+	virtual std::string getStatusText() = 0;
 };
 
 class LLFolderViewModelCommon : public LLFolderViewModelInterface
@@ -142,6 +145,8 @@ public:
 		// sort everything
 		mTargetSortVersion++;
 	}
+	virtual std::string getStatusText();
+	virtual void filter();
 
 	void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
 
@@ -177,6 +182,7 @@ public:
 	// add getStatusText and isFiltering()
 	virtual bool contentsReady()					{ return true; }
 
+
 	struct ViewModelCompare
 	{
 		ViewModelCompare(const SortType& sorter)
@@ -272,6 +278,7 @@ public:
 	
 	virtual bool hasChildren() const = 0;
 	virtual void addChild(LLFolderViewModelItem* child) = 0;
+	virtual void removeChild(LLFolderViewModelItem* child) = 0;
 
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
@@ -305,7 +312,9 @@ public:
 		mLastFilterGeneration(-1),
 		mMostFilteredDescendantGeneration(-1),
 		mParent(NULL)
-	{}
+	{
+		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
+	}
 
 	void requestSort() { mSortVersion = -1; }
 	S32 getSortVersion() { return mSortVersion; }
@@ -315,13 +324,23 @@ public:
 	void dirtyFilter()
 	{
 		mLastFilterGeneration = -1;
+
 		// bubble up dirty flag all the way to root
 		if (mParent)
 		{
 			mParent->dirtyFilter();
-		}
+		}	
+	}
+	virtual void addChild(LLFolderViewModelItem* child) 
+	{ 
+		mChildren.push_back(child); 
+		child->setParent(this); 
+	}
+	virtual void removeChild(LLFolderViewModelItem* child) 
+	{ 
+		mChildren.remove(child); 
+		child->setParent(NULL); 
 	}
-	virtual void addChild(LLFolderViewModelItem* child) { mChildren.push_back(child); child->setParent(this); }
 
 protected:
 	virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
new file mode 100644
index 0000000000..7ee1a10b15
--- /dev/null
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -0,0 +1,225 @@
+/* 
+ * @file llfolderviewmodelinventory.cpp
+ * @brief Implementation of the inventory-specific view model
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfolderviewmodelinventory.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventorypanel.h"
+
+//
+// class LLFolderViewModelInventory
+//
+static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort");
+
+void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
+{
+	LLFastTimer _(FTM_INVENTORY_SORT);
+
+	if (!needsSort(folder->getViewModelItem())) return;
+
+	LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem());
+	if (modelp->getUUID().isNull()) return;
+
+	for (std::list<LLFolderViewFolder*>::iterator it =   folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
+		it != end_it;
+		++it)
+	{
+		LLFolderViewFolder* child_folderp = *it;
+		sort(child_folderp);
+
+		if (child_folderp->getFoldersCount() > 0)
+		{
+			time_t most_recent_folder_time =
+				static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate();
+			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
+			if (most_recent_folder_time > modelp->getCreationDate())
+			{
+				modelp->setCreationDate(most_recent_folder_time);
+			}
+		}
+		if (child_folderp->getItemsCount() > 0)			
+		{
+			time_t most_recent_item_time =
+				static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate();
+
+			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
+			if (most_recent_item_time > modelp->getCreationDate())
+			{
+				modelp->setCreationDate(most_recent_item_time);
+			}
+		}
+	}
+	base_t::sort(folder);
+}
+
+bool LLFolderViewModelInventory::contentsReady()
+{
+	return !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
+}
+
+void LLFolderViewModelItemInventory::requestSort()
+{
+	LLFolderViewModelItemCommon::requestSort();
+	if (mRootViewModel->getSorter().isByDate())
+	{
+		// sort by date potentially affects parent folders which use a date
+		// derived from newest item in them
+		if (mParent)
+		{
+			mParent->requestSort();
+		}
+	}
+}
+
+bool LLFolderViewModelItemInventory::potentiallyVisible()
+{
+	return passedFilter() // we've passed the filter
+		|| getLastFilterGeneration() < mRootViewModel->getFilter()->getFirstSuccessGeneration() // or we don't know yet
+		|| descendantsPassedFilter();
+}
+
+bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation) 
+{ 
+	if (filter_generation < 0 && mRootViewModel) 
+		filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
+
+	return mPassedFolderFilter 
+		&& mLastFilterGeneration >= filter_generation
+		&& (mPassedFilter || descendantsPassedFilter(filter_generation));
+}
+
+bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation)
+{ 
+	if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
+	return mMostFilteredDescendantGeneration >= filter_generation; 
+}
+
+void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation)
+{
+	mPassedFilter = passed;
+	mPassedFolderFilter = passed_folder;
+	mLastFilterGeneration = filter_generation;
+}
+
+bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
+{
+	bool passed_filter_before = item->passedFilter();
+	S32 filter_generation = filter.getCurrentGeneration();
+	S32 must_pass_generation = filter.getFirstRequiredGeneration();
+
+	if (item->getLastFilterGeneration() < filter_generation)
+	{
+		if (item->getLastFilterGeneration() >= must_pass_generation 
+			&& !item->passedFilter(must_pass_generation))
+		{
+			// failed to pass an earlier filter that was a subset of the current one
+			// go ahead and flag this item as done
+			item->filter(filter);
+			if (item->passedFilter())
+			{
+				llerrs << "Invalid shortcut in inventory filtering!" << llendl;
+			}
+			item->setPassedFilter(false, false, filter_generation);
+		}
+		else
+		{
+			item->filter( filter );
+		}
+	}
+
+	// track latest generation to pass any child items, for each folder up to root
+	if (item->passedFilter())
+	{
+		LLFolderViewModelItemInventory* view_model = this;
+		
+		while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation)
+		{
+			view_model->mMostFilteredDescendantGeneration = filter_generation;
+			view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent);
+		}
+		
+		return !passed_filter_before;
+	}
+	else // !item->passedfilter()
+	{
+		return passed_filter_before;
+	}
+}
+
+bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
+{
+	bool changed = false;
+
+	if(!mChildren.empty()
+		&& (getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass
+			|| descendantsPassedFilter(filter.getFirstRequiredGeneration()))) // or at least one descendant has passed the minimum requirement
+	{
+		// now query children
+		for (child_list_t::iterator iter = mChildren.begin();
+			iter != mChildren.end() && filter.getFilterCount() > 0;
+			++iter)
+		{
+			changed |= filterChildItem((*iter), filter);
+		}
+	}
+
+	if (changed)
+	{
+		//TODO RN: ensure this still happens, but without dependency on folderview
+		LLFolderViewFolder* folder = static_cast<LLFolderViewFolder*>(mFolderViewItem);
+		folder->requestArrange();
+	}
+
+	// if we didn't use all filter iterations
+	// that means we filtered all of our descendants
+	// so filter ourselves now
+	if (filter.getFilterCount() > 0)
+	{
+		filter.decrementFilterCount();
+
+		const BOOL passed_filter = filter.check(this);
+		const BOOL passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) 
+								? filter.checkFolder(this)
+								: true;
+
+		setPassedFilter(passed_filter, passed_filter_folder, filter.getCurrentGeneration());
+		//TODO RN: create interface for string highlighting
+		//mStringMatchOffset = filter.getStringMatchOffset(this);
+	}
+	return changed;
+}
+
+LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
+{
+	return &mInventoryViewModel;
+}
+
+
+const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
+{
+	return &mInventoryViewModel;
+}
+
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
new file mode 100644
index 0000000000..a8fe3f57ea
--- /dev/null
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -0,0 +1,107 @@
+/** 
+ * @file llfolderviewmodelinventory.h
+ * @brief view model implementation specific to inventory
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFOLDERVIEWMODELINVENTORY_H
+#define LL_LLFOLDERVIEWMODELINVENTORY_H
+
+#include "llinventoryfilter.h"
+
+class LLFolderViewModelItemInventory
+	:	public LLFolderViewModelItemCommon
+{
+public:
+	LLFolderViewModelItemInventory()
+		:	mRootViewModel(NULL)
+	{}
+	void setRootViewModel(class LLFolderViewModelInventory* root_view_model)
+	{
+		mRootViewModel = root_view_model;
+	}
+	virtual const LLUUID& getUUID() const = 0;
+	virtual time_t getCreationDate() const = 0;	// UTC seconds
+	virtual void setCreationDate(time_t creation_date_utc) = 0;
+	virtual PermissionMask getPermissionMask() const = 0;
+	virtual LLFolderType::EType getPreferredType() const = 0;
+	virtual void showProperties(void) = 0;
+	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual.
+	virtual BOOL isUpToDate() const = 0;
+	virtual bool hasChildren() const = 0;
+	virtual LLInventoryType::EType getInventoryType() const = 0;
+	virtual void performAction(LLInventoryModel* model, std::string action)   = 0;
+	virtual LLWearableType::EType getWearableType() const = 0;
+	virtual EInventorySortGroup getSortGroup() const = 0;
+	virtual LLInventoryObject* getInventoryObject() const = 0;
+	virtual void requestSort();
+	virtual bool potentiallyVisible();
+	virtual bool passedFilter(S32 filter_generation = -1);
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1);
+	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
+	virtual bool filter( LLFolderViewFilter& filter);
+	virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+protected:
+	class LLFolderViewModelInventory* mRootViewModel;
+};
+
+class LLInventorySort
+{
+public:
+	LLInventorySort(U32 order = 0)
+		:	mSortOrder(order),
+		mByDate(false),
+		mSystemToTop(false),
+		mFoldersByName(false)
+	{
+		mByDate = (order & LLInventoryFilter::SO_DATE);
+		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+	}
+
+	bool isByDate() const { return mByDate; }
+	U32 getSortOrder() const { return mSortOrder; }
+
+	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
+private:
+	U32  mSortOrder;
+	bool mByDate;
+	bool mSystemToTop;
+	bool mFoldersByName;
+};
+
+class LLFolderViewModelInventory
+	:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter>
+{
+public:
+	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t;
+
+	virtual ~LLFolderViewModelInventory() {}
+
+	void sort(LLFolderViewFolder* folder);
+
+	bool contentsReady();
+
+};
+#endif // LL_LLFOLDERVIEWMODELINVENTORY_H
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 6a33130322..3f38d80a39 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -779,14 +779,12 @@ const std::string& LLInventoryFilter::getFilterText()
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION))
 	{
-		//filtered_types += " Animations,";
 		filtered_types += LLTrans::getString("Animations");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Animations,";
 		not_filtered_types += LLTrans::getString("Animations");
 
 		filtered_by_all_types = FALSE;
@@ -794,140 +792,120 @@ const std::string& LLInventoryFilter::getFilterText()
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD))
 	{
-		//filtered_types += " Calling Cards,";
 		filtered_types += LLTrans::getString("Calling Cards");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Calling Cards,";
 		not_filtered_types += LLTrans::getString("Calling Cards");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE))
 	{
-		//filtered_types += " Clothing,";
 		filtered_types +=  LLTrans::getString("Clothing");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Clothing,";
 		not_filtered_types +=  LLTrans::getString("Clothing");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE))
 	{
-		//filtered_types += " Gestures,";
 		filtered_types +=  LLTrans::getString("Gestures");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Gestures,";
 		not_filtered_types +=  LLTrans::getString("Gestures");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK))
 	{
-		//filtered_types += " Landmarks,";
 		filtered_types +=  LLTrans::getString("Landmarks");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Landmarks,";
 		not_filtered_types +=  LLTrans::getString("Landmarks");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
 	{
-		//filtered_types += " Notecards,";
 		filtered_types +=  LLTrans::getString("Notecards");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Notecards,";
 		not_filtered_types +=  LLTrans::getString("Notecards");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT))
 	{
-		//filtered_types += " Objects,";
 		filtered_types +=  LLTrans::getString("Objects");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Objects,";
 		not_filtered_types +=  LLTrans::getString("Objects");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_LSL))
 	{
-		//filtered_types += " Scripts,";
 		filtered_types +=  LLTrans::getString("Scripts");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Scripts,";
 		not_filtered_types +=  LLTrans::getString("Scripts");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND))
 	{
-		//filtered_types += " Sounds,";
 		filtered_types +=  LLTrans::getString("Sounds");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Sounds,";
 		not_filtered_types +=  LLTrans::getString("Sounds");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE))
 	{
-		//filtered_types += " Textures,";
 		filtered_types +=  LLTrans::getString("Textures");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Textures,";
 		not_filtered_types +=  LLTrans::getString("Textures");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT))
 	{
-		//filtered_types += " Snapshots,";
 		filtered_types +=  LLTrans::getString("Snapshots");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Snapshots,";
 		not_filtered_types +=  LLTrans::getString("Snapshots");
 		filtered_by_all_types = FALSE;
 	}
@@ -943,7 +921,6 @@ const std::string& LLInventoryFilter::getFilterText()
 		}
 		else
 		{
-			//mFilterText += "No ";
 			mFilterText += LLTrans::getString("No Filters");
 			mFilterText += not_filtered_types;
 		}
@@ -953,7 +930,6 @@ const std::string& LLInventoryFilter::getFilterText()
 
 	if (isSinceLogoff())
 	{
-		//mFilterText += " - Since Logoff";
 		mFilterText += LLTrans::getString("Since Logoff");
 	}
 	return mFilterText;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index e4cabcc988..b5fcf364dd 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -56,58 +56,6 @@ const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("Recent
 const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
 static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
 
-//
-// class LLFolderViewModelInventory
-//
-static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort");
-
-void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
-{
-	LLFastTimer _(FTM_INVENTORY_SORT);
-
-	if (!needsSort(folder->getViewModelItem())) return;
-
-	LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem());
-	if (modelp->getUUID().isNull()) return;
-
-	for (std::list<LLFolderViewFolder*>::iterator it =   folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
-		it != end_it;
-		++it)
-	{
-		LLFolderViewFolder* child_folderp = *it;
-		sort(child_folderp);
-
-		if (child_folderp->getFoldersCount() > 0)
-		{
-			time_t most_recent_folder_time =
-				static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate();
-			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
-			if (most_recent_folder_time > modelp->getCreationDate())
-			{
-				modelp->setCreationDate(most_recent_folder_time);
-			}
-		}
-		if (child_folderp->getItemsCount() > 0)			
-		{
-			time_t most_recent_item_time =
-				static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate();
-
-			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
-			if (most_recent_item_time > modelp->getCreationDate())
-			{
-				modelp->setCreationDate(most_recent_item_time);
-			}
-		}
-	}
-	base_t::sort(folder);
-}
-
-bool LLFolderViewModelInventory::contentsReady()
-{
-	return !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
-}
-
-
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInventoryPanelObserver
 //
@@ -580,8 +528,8 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			else if (!model_item && view_item)
 			{
 				// Remove the item's UI.
-				view_item->destroyView();
                 removeItemID(viewmodel_item->getUUID());
+				view_item->destroyView();
 			}
 		}
 	}
@@ -1344,150 +1292,3 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
 	// replace bridge builder to have necessary View bridges.
 	mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
 }
-
-
-void LLFolderViewModelItemInventory::requestSort()
-{
-	LLFolderViewModelItemCommon::requestSort();
-	if (mRootViewModel->getSorter().isByDate())
-	{
-		// sort by date potentially affects parent folders which use a date
-		// derived from newest item in them
-		if (mParent)
-		{
-			mParent->requestSort();
-		}
-	}
-}
-
-bool LLFolderViewModelItemInventory::potentiallyVisible()
-{
-	return passedFilter() // we've passed the filter
-		|| getLastFilterGeneration() < mRootViewModel->getFilter()->getFirstSuccessGeneration() // or we don't know yet
-		|| descendantsPassedFilter();
-}
-
-bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation) 
-{ 
-	if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
-	return mPassedFolderFilter 
-		&& mLastFilterGeneration >= filter_generation
-		&& (mPassedFilter || descendantsPassedFilter(filter_generation));
-}
-
-bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation)
-{ 
-	if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
-	return mMostFilteredDescendantGeneration >= filter_generation; 
-}
-
-void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation)
-{
-	mPassedFilter = passed;
-	mPassedFolderFilter = passed_folder;
-	mLastFilterGeneration = filter_generation;
-}
-
-bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
-{
-	bool passed_filter_before = item->passedFilter();
-	S32 filter_generation = filter.getCurrentGeneration();
-	S32 must_pass_generation = filter.getFirstRequiredGeneration();
-	bool changed = false;
-
-	// mMostFilteredDescendantGeneration might have been reset
-	// in which case we need to update it even for folders that
-	// don't need to be filtered anymore
-	if (item->getLastFilterGeneration() < filter_generation)
-	{
-		if (item->getLastFilterGeneration() >= must_pass_generation && 
-			!item->passedFilter(must_pass_generation))
-		{
-			// failed to pass an earlier filter that was a subset of the current one
-			// go ahead and flag this item as done
-			item->setPassedFilter(false, false, filter_generation);
-		}
-		else
-		{
-			changed |= item->filter( filter );
-		}
-	}
-
-	// track latest generation to pass any child items
-	if (item->passedFilter())
-	{
-		LLFolderViewModelItemInventory* view_model = this;
-		
-		while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation)
-		{
-			view_model->mMostFilteredDescendantGeneration = filter_generation;
-			view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent);
-		}
-	}
-
-	changed |= (item->passedFilter() != passed_filter_before);
-	if (changed)
-	{
-		//TODO RN: ensure this still happens, but without dependency on folderview
-		LLFolderViewFolder* parent = mFolderViewItem->getParentFolder();
-		if (parent) parent->requestArrange();
-	}
-
-	return changed;
-}
-
-bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
-{
-	bool changed = false;
-
-	if(!mChildren.empty()
-		&& (getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass
-			|| descendantsPassedFilter(filter.getFirstRequiredGeneration()))) // or at least one descendant has passed the minimum requirement
-	{
-		// now query children
-		for (child_list_t::iterator iter = mChildren.begin();
-			iter != mChildren.end() && filter.getFilterCount() > 0;
-			++iter)
-		{
-			changed |= filterChildItem((*iter), filter);
-		}
-	}
-
-	// if we didn't use all filter iterations
-	// that means we filtered all of our descendants
-	// so filter ourselves now
-	if (filter.getFilterCount() > 0)
-	{
-		const BOOL previous_passed_filter = mPassedFilter;
-		const BOOL passed_filter = filter.check(this);
-		const BOOL passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) 
-								? filter.checkFolder(this)
-								: true;
-
-		// If our visibility will change as a result of this filter, then
-		// we need to be rearranged in our parent folder
-		LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
-		if (parent_folder && passed_filter != previous_passed_filter)
-		{
-			parent_folder->requestArrange();
-		}
-	
-		setPassedFilter(passed_filter, passed_filter_folder, filter.getCurrentGeneration());
-		//TODO RN: create interface for string highlighting
-		//mStringMatchOffset = filter.getStringMatchOffset(this);
-		filter.decrementFilterCount();
-	}
-	return changed;
-}
-
-LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
-{
-	return &mInventoryViewModel;
-}
-
-
-const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
-{
-	return &mInventoryViewModel;
-}
-
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 3195d9a369..a62b97aa7d 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -31,6 +31,7 @@
 #include "llassetstorage.h"
 #include "lldarray.h"
 #include "llfolderviewitem.h"
+#include "llfolderviewmodelinventory.h"
 #include "llfloater.h"
 #include "llinventory.h"
 #include "llinventoryfilter.h"
@@ -42,83 +43,6 @@
 class LLInvFVBridge;
 class LLInventoryFVBridgeBuilder;
 class LLInvPanelComplObserver;
-class LLFolderViewModelInventory;
-
-class LLFolderViewModelItemInventory
-	:	public LLFolderViewModelItemCommon
-{
-public:
-	LLFolderViewModelItemInventory()
-	:	mRootViewModel(NULL)
-	{}
-	void setRootViewModel(LLFolderViewModelInventory* root_view_model)
-	{
-		mRootViewModel = root_view_model;
-	}
-	virtual const LLUUID& getUUID() const = 0;
-	virtual time_t getCreationDate() const = 0;	// UTC seconds
-	virtual void setCreationDate(time_t creation_date_utc) = 0;
-	virtual PermissionMask getPermissionMask() const = 0;
-	virtual LLFolderType::EType getPreferredType() const = 0;
-	virtual void showProperties(void) = 0;
-	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual.
-	virtual BOOL isUpToDate() const = 0;
-	virtual bool hasChildren() const = 0;
-	virtual LLInventoryType::EType getInventoryType() const = 0;
-	virtual void performAction(LLInventoryModel* model, std::string action)   = 0;
-	virtual LLWearableType::EType getWearableType() const = 0;
-	virtual EInventorySortGroup getSortGroup() const = 0;
-	virtual LLInventoryObject* getInventoryObject() const = 0;
-	virtual void requestSort();
-	virtual bool potentiallyVisible();
-	virtual bool passedFilter(S32 filter_generation = -1);
-	virtual bool descendantsPassedFilter(S32 filter_generation = -1);
-	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
-	virtual bool filter( LLFolderViewFilter& filter);
-	virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
-protected:
-	LLFolderViewModelInventory* mRootViewModel;
-};
-
-class LLInventorySort
-{
-public:
-	LLInventorySort(U32 order = 0)
-	:	mSortOrder(order),
-		mByDate(false),
-		mSystemToTop(false),
-		mFoldersByName(false)
-	{
-		mByDate = (order & LLInventoryFilter::SO_DATE);
-		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
-		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
-	}
-
-	bool isByDate() const { return mByDate; }
-	U32 getSortOrder() const { return mSortOrder; }
-
-	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
-private:
-	U32  mSortOrder;
-	bool mByDate;
-	bool mSystemToTop;
-	bool mFoldersByName;
-};
-
-class LLFolderViewModelInventory
-	:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter>
-{
-public:
-	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t;
-
-	virtual ~LLFolderViewModelInventory() {}
-
-	void sort(LLFolderViewFolder* folder);
-
-	bool contentsReady();
-
-};
-
 
 class LLInventoryPanel : public LLPanel
 {
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 61a0331b72..4a9e106687 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -623,9 +623,9 @@ void LLFloaterTexturePicker::draw()
 		LLFolderView* folder_view = mInventoryPanel->getRootFolder();
 		if (!folder_view) return;
 
-		LLInventoryFilter* filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
+		LLFolderViewFilter* filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
 
-		bool is_filter_active = folder_view->getLastFilterGeneration() < filter->getCurrentGeneration() &&
+		bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter->getCurrentGeneration() &&
 				filter->isNotDefault();
 
 		// After inventory panel filter is applied we have to update
-- 
cgit v1.2.3


From 7b4f24850b94aba41ee93c6f2901b012de2b7d30 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 2 Jul 2012 19:37:11 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose fixed build post merge

---
 indra/newview/llimfloatercontainer.h | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 2bbd371e8f..9615f3f44d 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -37,7 +37,7 @@
 #include "llgroupmgr.h"
 
 #include "llfolderviewitem.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 
 class LLButton;
 class LLLayoutPanel;
@@ -53,7 +53,7 @@ typedef std::map<LLFloater*, LLFolderViewItem*> conversations_widgets_map;
 
 // Conversation items: we hold a list of those and create an LLFolderViewItem widget for each  
 // that we tuck into the mConversationsListPanel. 
-class LLConversationItem : public LLFolderViewEventListener
+class LLConversationItem : public LLFolderViewModelItemCommon
 {
 public:
 	LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
@@ -62,6 +62,7 @@ public:
 	// Stub those things we won't really be using in this conversation context
 	virtual const std::string& getName() const { return mName; }
 	virtual const std::string& getDisplayName() const { return mName; }
+	virtual const std::string& getSearchableName() const { return mName; }
 	virtual const LLUUID& getUUID() const { return mUUID; }
 	virtual time_t getCreationDate() const { return 0; }
 	virtual PermissionMask getPermissionMask() const { return PERM_ALL; }
@@ -76,8 +77,8 @@ public:
 	virtual BOOL isItemRemovable( void ) const { return FALSE; }
 	virtual BOOL isItemInTrash( void) const { return FALSE; }
 	virtual BOOL removeItem() { return FALSE; }
-	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) { }
-	virtual void move( LLFolderViewEventListener* parent_listener ) { }
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
+	virtual void move( LLFolderViewModelItem* parent_listener ) { }
 	virtual BOOL isItemCopyable() const { return FALSE; }
 	virtual BOOL copyToClipboard() const { return FALSE; }
 	virtual BOOL cutToClipboard() const { return FALSE; }
@@ -86,10 +87,16 @@ public:
 	virtual void pasteLinkFromClipboard() { }
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
 	virtual BOOL isUpToDate() const { return TRUE; }
-	virtual BOOL hasChildren() const { return FALSE; }
+	virtual bool hasChildren() const { return FALSE; }
 	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
 	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
 
+	virtual bool potentiallyVisible() { return true; }
+	virtual bool filter( LLFolderViewFilter& filter) { return true; }
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
+	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) { }
+	virtual bool passedFilter(S32 filter_generation = -1) { return true; }
+
 	// The action callbacks
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual void openItem( void );
@@ -102,6 +109,7 @@ public:
 	
 	// This method should be called when a drag begins.
 	// Returns TRUE if the drag can begin, FALSE otherwise.
+	virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_PEOPLE; }
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const { return FALSE; }
 	
 	// This method will be called to determine if a drop can be
-- 
cgit v1.2.3


From 7d0150f12d8edcbd078ef570f7c64e44194e4335 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 2 Jul 2012 19:37:28 -0700
Subject: CHUI-101 WIP Make LLFolderView general purpose started to remove
 newview dependencies from llfolder*

---
 indra/newview/llfolderview.cpp               | 196 +++++++--------------------
 indra/newview/llfolderview.h                 |  12 +-
 indra/newview/llfolderviewitem.cpp           |  96 +------------
 indra/newview/llfolderviewitem.h             |   1 -
 indra/newview/llfolderviewmodel.h            |  13 +-
 indra/newview/llfolderviewmodelinventory.cpp |  81 +++++++++++
 indra/newview/llinventoryfunctions.cpp       |  88 +++++++++++-
 indra/newview/llinventoryfunctions.h         |   7 +
 indra/newview/llinventorypanel.cpp           |  13 +-
 indra/newview/llinventorypanel.h             |   2 +-
 indra/newview/llpanellandmarks.cpp           |   4 +-
 indra/newview/llpanelmaininventory.cpp       |   4 +-
 indra/newview/llpanelobjectinventory.cpp     |   2 +-
 13 files changed, 245 insertions(+), 274 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 90c78d98b0..6bc89cdbca 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -26,34 +26,25 @@
 
 #include "llviewerprecompiledheaders.h"
 
-#include "llfolderview.h"
 #include "llfolderview.h"
 
-#include "llcallbacklist.h"
-#include "llinventorybridge.h"
 #include "llclipboard.h" // *TODO: remove this once hack below gone.
-#include "llinventorypanel.h"
-#include "llfoldertype.h"
 #include "llkeyboard.h"
 #include "lllineeditor.h"
 #include "llmenugl.h"
 #include "llpanel.h"
-#include "llpreview.h"
 #include "llscrollcontainer.h" // hack to allow scrolling
-#include "lltooldraganddrop.h"
 #include "lltrans.h"
 #include "llui.h"
-#include "llviewertexture.h"
-#include "llviewertexturelist.h"
-#include "llviewerjointattachment.h"
-#include "llviewermenu.h"
 #include "lluictrlfactory.h"
-#include "llviewercontrol.h"
-#include "llviewerfoldertype.h"
-#include "llviewerwindow.h"
-#include "llvoavatar.h"
-#include "llfloaterproperties.h"
-#include "llnotificationsutil.h"
+
+// TODO RN: kill these
+// newview includes
+#include "llcallbacklist.h"			// per-frame on-idle
+#include "llfloaterproperties.h"	// showProperties
+#include "llviewerwindow.h"			// renamer popup handling
+#include "llpreview.h"				// openSelectedItems
+#include "llinventorypanel.h"		// idle loop for filtering, sort order declarations, etc.
 
 // Linden library includes
 #include "lldbstrings.h"
@@ -251,7 +242,7 @@ LLFolderView::LLFolderView(const Params& p)
 
 
 	// make the popup menu available
-	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
 	if (!menu)
 	{
 		menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
@@ -361,7 +352,7 @@ static LLFastTimer::DeclareTimer FTM_FILTER("Filter Folder View");
 void LLFolderView::filter( LLFolderViewFilter& filter )
 {
 	LLFastTimer t2(FTM_FILTER);
-	filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
+	filter.setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
 
 	getViewModelItem()->filter(filter);
 }
@@ -631,7 +622,7 @@ void LLFolderView::clearSelection()
 }
 
 std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const
-	{
+{
 	std::set<LLFolderViewItem*> selection;
 	std::copy(mSelectedItems.begin(), mSelectedItems.end(), std::inserter(selection, selection.begin()));
 	return selection;
@@ -695,7 +686,7 @@ void LLFolderView::draw()
 	}
 
 
-	if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout") || !mSearchString.size())
+	if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size())
 	{
 		mSearchString.clear();
 	}
@@ -767,14 +758,6 @@ void LLFolderView::closeRenamer( void )
 	}
 }
 
-void LLFolderView::removeSelectedItems( void )
-{
-	if (mSelectedItems.empty()) return;
-	LLSD args;
-	args["QUESTION"] = LLTrans::getString(mSelectedItems.size() > 1 ? "DeleteItems" :  "DeleteItem");
-	LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2));
-}
-
 bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
 {
 	LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
@@ -820,11 +803,8 @@ void LLFolderView::removeCutItems()
 	}
 }
 
-void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response)
+void LLFolderView::removeSelectedItems()
 {
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if (option != 0) return; // canceled
-
 	if(getVisible() && getEnabled())
 	{
 		// just in case we're removing the renaming item.
@@ -927,42 +907,44 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 	}
 }
 
+// TODO RN: abstract 
 // open the selected item.
 void LLFolderView::openSelectedItems( void )
 {
-	if(getVisible() && getEnabled())
-	{
-		if (mSelectedItems.size() == 1)
-		{
-			mSelectedItems.front()->openItem();
-		}
-		else
-		{
-			LLMultiPreview* multi_previewp = new LLMultiPreview();
-			LLMultiProperties* multi_propertiesp = new LLMultiProperties();
+	//TODO RN: get working again
+	//if(getVisible() && getEnabled())
+	//{
+	//	if (mSelectedItems.size() == 1)
+	//	{
+	//		mSelectedItems.front()->openItem();
+	//	}
+	//	else
+	//	{
+	//		LLMultiPreview* multi_previewp = new LLMultiPreview();
+	//		LLMultiProperties* multi_propertiesp = new LLMultiProperties();
 
-			selected_items_t::iterator item_it;
-			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-			{
-				// IT_{OBJECT,ATTACHMENT} creates LLProperties
-				// floaters; others create LLPreviews.  Put
-				// each one in the right type of container.
-				LLFolderViewModelItemInventory* listener = static_cast<LLFolderViewModelItemInventory*>((*item_it)->getViewModelItem());
-				bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
-				if (is_prop)
-					LLFloater::setFloaterHost(multi_propertiesp);
-				else
-					LLFloater::setFloaterHost(multi_previewp);
-				listener->openItem();
-			}
+	//		selected_items_t::iterator item_it;
+	//		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+	//		{
+	//			// IT_{OBJECT,ATTACHMENT} creates LLProperties
+	//			// floaters; others create LLPreviews.  Put
+	//			// each one in the right type of container.
+	//			LLFolderViewModelItemInventory* listener = static_cast<LLFolderViewModelItemInventory*>((*item_it)->getViewModelItem());
+	//			bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
+	//			if (is_prop)
+	//				LLFloater::setFloaterHost(multi_propertiesp);
+	//			else
+	//				LLFloater::setFloaterHost(multi_previewp);
+	//			listener->openItem();
+	//		}
 
-			LLFloater::setFloaterHost(NULL);
-			// *NOTE: LLMulti* will safely auto-delete when open'd
-			// without any children.
-			multi_previewp->openFloater(LLSD());
-			multi_propertiesp->openFloater(LLSD());
-		}
-	}
+	//		LLFloater::setFloaterHost(NULL);
+	//		// *NOTE: LLMulti* will safely auto-delete when open'd
+	//		// without any children.
+	//		multi_previewp->openFloater(LLSD());
+	//		multi_propertiesp->openFloater(LLSD());
+	//	}
+	//}
 }
 
 void LLFolderView::propertiesSelectedItems( void )
@@ -994,15 +976,6 @@ void LLFolderView::propertiesSelectedItems( void )
 	//}
 }
 
-void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type)
-{
-	LLFolderBridge *folder_bridge = LLFolderBridge::sSelf.get();
-
-	if (!folder_bridge) return;
-	LLViewerInventoryCategory *cat = folder_bridge->getCategory();
-	if (!cat) return;
-	cat->changeType(new_folder_type);
-}
 
 void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
 {
@@ -1521,7 +1494,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
 		}
 
 		//do text search
-		if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout"))
+		if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout"))
 		{
 			mSearchString.clear();
 		}
@@ -1831,81 +1804,6 @@ void LLFolderView::setShowSingleSelection(BOOL show)
 	}
 }
 
-bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
-{
-	std::string action = userdata.asString();
-	
-	if ("rename" == action)
-	{
-		startRenamingSelectedItem();
-		return true;
-	}
-	if ("delete" == action)
-	{
-		removeSelectedItems();
-		return true;
-	}
-	if (("copy" == action) || ("cut" == action))
-	{	
-		// Clear the clipboard before we start adding things on it
-		LLClipboard::instance().reset();
-	}
-
-	static const std::string change_folder_string = "change_folder_type_";
-	if (action.length() > change_folder_string.length() && 
-		(action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
-	{
-		LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
-		changeType(model, new_folder_type);
-		return true;
-	}
-
-
-	std::set<LLFolderViewItem*> selected_items = getSelectionList();
-
-	LLMultiPreview* multi_previewp = NULL;
-	LLMultiProperties* multi_propertiesp = NULL;
-
-	if (("task_open" == action  || "open" == action) && selected_items.size() > 1)
-	{
-		multi_previewp = new LLMultiPreview();
-		gFloaterView->addChild(multi_previewp);
-
-		LLFloater::setFloaterHost(multi_previewp);
-	
-	}
-	else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
-	{
-		multi_propertiesp = new LLMultiProperties();
-		gFloaterView->addChild(multi_propertiesp);
-
-		LLFloater::setFloaterHost(multi_propertiesp);
-	}
-
-	std::set<LLFolderViewItem*>::iterator set_iter;
-
-	for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
-	{
-		LLFolderViewItem* folder_item = *set_iter;
-		if(!folder_item) continue;
-		LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
-		if(!bridge) continue;
-		bridge->performAction(model, action);
-	}
-
-	LLFloater::setFloaterHost(NULL);
-	if (multi_previewp)
-	{
-		multi_previewp->openFloater(LLSD());
-	}
-	else if (multi_propertiesp)
-	{
-		multi_propertiesp->openFloater(LLSD());
-	}
-
-	return true;
-}
-
 static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
 static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
 
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index 8a0317f840..e098119293 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -39,20 +39,17 @@
 
 #include "lluictrl.h"
 #include "v4color.h"
-#include "lldarray.h"
 #include "stdenums.h"
 #include "lldepthstack.h"
 #include "lleditmenuhandler.h"
 #include "llfontgl.h"
 #include "llscrollcontainer.h"
 #include "lltooldraganddrop.h"
-#include "llviewertexture.h"
 
 class LLFolderViewModelInterface;
 class LLFolderViewFolder;
 class LLFolderViewItem;
 class LLFolderViewFilter;
-class LLInventoryModel;
 class LLPanel;
 class LLLineEditor;
 class LLMenuGL;
@@ -153,8 +150,9 @@ public:
 	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
 
 	virtual std::set<LLFolderViewItem*> getSelectionList() const;
+	S32 getNumSelectedItems() { return mSelectedItems.size(); }
 
-	// Make sure if ancestor is selected, descendents are not
+	// Make sure if ancestor is selected, descendants are not
 	void sanitizeSelection();
 	virtual void clearSelection();
 	void addToSelectionList(LLFolderViewItem* item);
@@ -173,9 +171,6 @@ public:
 	void openSelectedItems( void );
 	void propertiesSelectedItems( void );
 
-	// Change the folder type
-	void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
-
 	void autoOpenItem(LLFolderViewFolder* item);
 	void closeAutoOpenedFolders();
 	BOOL autoOpenTest(LLFolderViewFolder* item);
@@ -228,8 +223,6 @@ public:
 	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
 	bool getUseEllipses() { return mUseEllipses; }
 
-	bool doToSelected(LLInventoryModel* model, const LLSD& userdata);
-	
 	void	doIdle();						// Real idle routine
 	static void idle(void* user_data);		// static glue to doIdle()
 
@@ -270,7 +263,6 @@ protected:
 	
 	BOOL addNoOptions(LLMenuGL* menu) const;
 
-	void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response);
 
 protected:
 	LLHandle<LLView>					mPopupMenuHandle;
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 80893c3037..e84c765ac8 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -28,16 +28,9 @@
 #include "llfolderviewitem.h"
 
 // viewer includes
-#include "llfolderview.h"		// Items depend extensively on LLFolderViews
 #include "llfolderview.h"
 #include "llfolderviewmodel.h"
-#include "llviewerfoldertype.h"
-#include "llinventorybridge.h"	// for LLItemBridge in LLInventorySort::operator()
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
 #include "llpanel.h"
-#include "llviewercontrol.h"	// gSavedSettings
-#include "llviewerwindow.h"		// Argh, only for setCursor()
 
 // linden library includes
 #include "llclipboard.h"
@@ -529,11 +522,11 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 
 		if (can_drag)
 		{
-			gViewerWindow->setCursor(UI_CURSOR_ARROW);
+			getWindow()->setCursor(UI_CURSOR_ARROW);
 		}
 		else
 		{
-			gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
+			getWindow()->setCursor(UI_CURSOR_NOLOCKED);
 		}
 		return TRUE;
 	}
@@ -541,9 +534,9 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 	{
 		if (getRoot())
 		{
-		getRoot()->setShowSelectionContext(FALSE);
+			getRoot()->setShowSelectionContext(FALSE);
 		}
-		gViewerWindow->setCursor(UI_CURSOR_ARROW);
+		getWindow()->setCursor(UI_CURSOR_ARROW);
 		// let parent handle this then...
 		return FALSE;
 	}
@@ -2075,84 +2068,3 @@ LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* it
 	return result;
 }
 
-bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
-{
-	// ignore sort order for landmarks in the Favorites folder.
-	// they should be always sorted as in Favorites bar. See EXT-719
-	//TODO RN: fix sorting in favorites folder
-	//if (a->getSortGroup() == SG_ITEM
-	//	&& b->getSortGroup() == SG_ITEM
-	//	&& a->getInventoryType() == LLInventoryType::IT_LANDMARK
-	//	&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
-	//{
-
-	//	static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-
-	//	LLUUID a_uuid = a->getParentFolder()->getUUID();
-	//	LLUUID b_uuid = b->getParentFolder()->getUUID();
-
-	//	if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
-	//	{
-	//		// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
-	//		// or to LLInvFVBridge
-	//		LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a))->getItem();
-	//		LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b))->getItem();
-	//		if (!aitem || !bitem)
-	//			return false;
-	//		S32 a_sort = aitem->getSortField();
-	//		S32 b_sort = bitem->getSortField();
-	//		return a_sort < b_sort;
-	//	}
-	//}
-
-	// We sort by name if we aren't sorting by date
-	// OR if these are folders and we are sorting folders by name.
-	bool by_name = (!mByDate 
-		|| (mFoldersByName 
-		&& (a->getSortGroup() != SG_ITEM)));
-
-	if (a->getSortGroup() != b->getSortGroup())
-	{
-		if (mSystemToTop)
-		{
-			// Group order is System Folders, Trash, Normal Folders, Items
-			return (a->getSortGroup() < b->getSortGroup());
-		}
-		else if (mByDate)
-		{
-			// Trash needs to go to the bottom if we are sorting by date
-			if ( (a->getSortGroup() == SG_TRASH_FOLDER)
-				|| (b->getSortGroup() == SG_TRASH_FOLDER))
-			{
-				return (b->getSortGroup() == SG_TRASH_FOLDER);
-			}
-		}
-	}
-
-	if (by_name)
-	{
-		S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
-		if (0 == compare)
-		{
-			return (a->getCreationDate() > b->getCreationDate());
-		}
-		else
-		{
-			return (compare < 0);
-		}
-	}
-	else
-	{
-		time_t first_create = a->getCreationDate();
-		time_t second_create = b->getCreationDate();
-		if (first_create == second_create)
-		{
-			return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0);
-		}
-		else
-		{
-			return (first_create > second_create);
-		}
-	}
-}
-
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 581ec7239e..92923e82da 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -27,7 +27,6 @@
 #define LLFOLDERVIEWITEM_H
 
 #include "llview.h"
-#include "lldarray.h"  // *TODO: Eliminate, forward declare
 #include "lluiimage.h"
 
 class LLFolderView;
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 8a16ec3eff..98b7255137 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -22,18 +22,11 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
-#ifndef LLFOLDERVIEWEVENTLISTENER_H
-#define LLFOLDERVIEWEVENTLISTENER_H
+#ifndef LLFOLDERVIEWMODEL_H
+#define LLFOLDERVIEWMODEL_H
 
-#include "lldarray.h"	// *TODO: convert to std::vector
-#include "llfoldertype.h"
 #include "llfontgl.h"	// just for StyleFlags enum
 #include "llfolderview.h"
-#include "llfolderviewitem.h"
-#include "llinventorytype.h"
-#include "llpermissionsflags.h"
-#include "llpointer.h"
-#include "llwearabletype.h"
 #include "lltooldraganddrop.h"
 
 // These are grouping of inventory types.
@@ -362,4 +355,4 @@ protected:
 };
 
 
-#endif
+#endif // LLFOLDERVIEWMODEL_H
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 7ee1a10b15..99831c61bf 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -223,3 +223,84 @@ const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
 	return &mInventoryViewModel;
 }
 
+bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
+{
+	// ignore sort order for landmarks in the Favorites folder.
+	// they should be always sorted as in Favorites bar. See EXT-719
+	//TODO RN: fix sorting in favorites folder
+	//if (a->getSortGroup() == SG_ITEM
+	//	&& b->getSortGroup() == SG_ITEM
+	//	&& a->getInventoryType() == LLInventoryType::IT_LANDMARK
+	//	&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	//{
+
+	//	static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+
+	//	LLUUID a_uuid = a->getParentFolder()->getUUID();
+	//	LLUUID b_uuid = b->getParentFolder()->getUUID();
+
+	//	if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
+	//	{
+	//		// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
+	//		// or to LLInvFVBridge
+	//		LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a))->getItem();
+	//		LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b))->getItem();
+	//		if (!aitem || !bitem)
+	//			return false;
+	//		S32 a_sort = aitem->getSortField();
+	//		S32 b_sort = bitem->getSortField();
+	//		return a_sort < b_sort;
+	//	}
+	//}
+
+	// We sort by name if we aren't sorting by date
+	// OR if these are folders and we are sorting folders by name.
+	bool by_name = (!mByDate 
+		|| (mFoldersByName 
+		&& (a->getSortGroup() != SG_ITEM)));
+
+	if (a->getSortGroup() != b->getSortGroup())
+	{
+		if (mSystemToTop)
+		{
+			// Group order is System Folders, Trash, Normal Folders, Items
+			return (a->getSortGroup() < b->getSortGroup());
+		}
+		else if (mByDate)
+		{
+			// Trash needs to go to the bottom if we are sorting by date
+			if ( (a->getSortGroup() == SG_TRASH_FOLDER)
+				|| (b->getSortGroup() == SG_TRASH_FOLDER))
+			{
+				return (b->getSortGroup() == SG_TRASH_FOLDER);
+			}
+		}
+	}
+
+	if (by_name)
+	{
+		S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+		if (0 == compare)
+		{
+			return (a->getCreationDate() > b->getCreationDate());
+		}
+		else
+		{
+			return (compare < 0);
+		}
+	}
+	else
+	{
+		time_t first_create = a->getCreationDate();
+		time_t second_create = b->getCreationDate();
+		if (first_create == second_create)
+		{
+			return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0);
+		}
+		else
+		{
+			return (first_create > second_create);
+		}
+	}
+}
+
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index ff461236a2..07f3dd8ffb 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -45,7 +45,7 @@
 // newview includes
 #include "llappearancemgr.h"
 #include "llappviewer.h"
-//#include "llfirstuse.h"
+#include "llclipboard.h"
 #include "llfloaterinventory.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfocusmgr.h"
@@ -74,8 +74,10 @@
 #include "llsidepanelinventory.h"
 #include "lltabcontainer.h"
 #include "lltooldraganddrop.h"
+#include "lltrans.h"
 #include "lluictrlfactory.h"
 #include "llviewermessage.h"
+#include "llviewerfoldertype.h"
 #include "llviewerobjectlist.h"
 #include "llviewerregion.h"
 #include "llviewerwindow.h"
@@ -1044,3 +1046,87 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
 	}
 }
 
+void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action)
+{
+	if ("rename" == action)
+	{
+		root->startRenamingSelectedItem();
+		return;
+	}
+	if ("delete" == action)
+	{
+		LLSD args;
+		args["QUESTION"] = LLTrans::getString(root->getNumSelectedItems() > 1 ? "DeleteItems" :  "DeleteItem");
+		LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root));
+		return;
+	}
+	if (("copy" == action) || ("cut" == action))
+	{	
+		// Clear the clipboard before we start adding things on it
+		LLClipboard::instance().reset();
+	}
+
+	static const std::string change_folder_string = "change_folder_type_";
+	if (action.length() > change_folder_string.length() && 
+		(action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
+	{
+		LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
+		LLFolderViewModelItemInventory* inventory_item = static_cast<LLFolderViewModelItemInventory*>(root->getViewModelItem());
+		LLViewerInventoryCategory *cat = model->getCategory(inventory_item->getUUID());
+		if (!cat) return;
+		cat->changeType(new_folder_type);
+		return;
+	}
+
+
+	std::set<LLFolderViewItem*> selected_items = root->getSelectionList();
+
+	LLMultiPreview* multi_previewp = NULL;
+	LLMultiProperties* multi_propertiesp = NULL;
+
+	if (("task_open" == action  || "open" == action) && selected_items.size() > 1)
+	{
+		multi_previewp = new LLMultiPreview();
+		gFloaterView->addChild(multi_previewp);
+
+		LLFloater::setFloaterHost(multi_previewp);
+
+	}
+	else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
+	{
+		multi_propertiesp = new LLMultiProperties();
+		gFloaterView->addChild(multi_propertiesp);
+
+		LLFloater::setFloaterHost(multi_propertiesp);
+	}
+
+	std::set<LLFolderViewItem*>::iterator set_iter;
+
+	for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+	{
+		LLFolderViewItem* folder_item = *set_iter;
+		if(!folder_item) continue;
+		LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
+		if(!bridge) continue;
+		bridge->performAction(model, action);
+	}
+
+	LLFloater::setFloaterHost(NULL);
+	if (multi_previewp)
+	{
+		multi_previewp->openFloater(LLSD());
+	}
+	else if (multi_propertiesp)
+	{
+		multi_propertiesp->openFloater(LLSD());
+	}
+}
+
+void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, const LLSD& response, LLFolderView* root )
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (option == 0)
+	{
+		root->removeSelectedItems();
+	}
+}
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index c6b1da0417..d8d3d9bbbb 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -427,6 +427,13 @@ public:
 	static LLUUID sWearNewClothingTransactionID;	// wear all clothing in this transaction	
 };
 
+struct LLInventoryAction
+{
+	static void doToSelected(class LLInventoryModel* model, class LLFolderView* root, const std::string& action);
+
+	static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLFolderView* root);
+};
+
 
 #endif // LL_LLINVENTORYFUNCTIONS_H
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index b5fcf364dd..ef8c5dc1cf 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -44,6 +44,7 @@
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodelbackgroundfetch.h"
+#include "llpreview.h"
 #include "llsidepanelinventory.h"
 #include "llviewerattachmenu.h"
 #include "llviewerfoldertype.h"
@@ -926,11 +927,6 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 	}
 }
 
-void LLInventoryPanel::doToSelected(const LLSD& userdata)
-{
-	mFolderRoot->doToSelected(&gInventory, userdata);
-}
-
 void LLInventoryPanel::doCreate(const LLSD& userdata)
 {
 	menu_create_inventory_item(this, LLFolderBridge::sSelf.get(), userdata);
@@ -1260,6 +1256,13 @@ void LLInventoryPanel::updateSelection()
 	}
 }
 
+void LLInventoryPanel::doToSelected(const LLSD& userdata)
+{
+	LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString());
+
+	return;
+}
+
 
 /************************************************************************/
 /* Recent Inventory Panel related class                                 */
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index a62b97aa7d..58c1201e54 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -176,7 +176,7 @@ public:
 	LLFolderViewFolder* getFolderByID(const LLUUID& id);
 	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
 	void updateSelection();
-	 	
+
 	LLFolderViewModelInventory* getFolderViewModel();
 	const LLFolderViewModelInventory* getFolderViewModel() const;
 
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 0b899d34f4..faef923338 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -851,7 +851,7 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
 	}
 	else
 	{
-		mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(),command_name);
+		mCurrentSelectedList->doToSelected(command_name);
 	}
 }
 
@@ -896,7 +896,7 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
 	{
 		if(mCurrentSelectedList)
 		{
-			mCurrentSelectedList->getRootFolder()->doToSelected(&gInventory, userdata);
+			mCurrentSelectedList->doToSelected(userdata);
 		}
 	}
 }
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 6cef1f877b..fea27b37d3 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -294,7 +294,7 @@ BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
 
 void LLPanelMainInventory::doToSelected(const LLSD& userdata)
 {
-	getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
+	getPanel()->doToSelected(userdata);
 }
 
 void LLPanelMainInventory::closeAllFolders()
@@ -970,7 +970,7 @@ void LLPanelMainInventory::onTrashButtonClick()
 void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
 {
 	std::string command_name = userdata.asString();
-	getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
+	getActivePanel()->doToSelected(command_name);
 }
 
 void LLPanelMainInventory::saveTexture(const LLSD& userdata)
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 450e1f7ed0..002c0c1113 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1522,7 +1522,7 @@ BOOL LLPanelObjectInventory::postBuild()
 
 void LLPanelObjectInventory::doToSelected(const LLSD& userdata)
 {
-	mFolders->doToSelected(&gInventory, userdata);
+	LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString());
 }
 
 void LLPanelObjectInventory::clearContents()
-- 
cgit v1.2.3


From ad1f2eb5106a9ba0217ff1080d029f912ecc25e5 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Tue, 3 Jul 2012 22:31:58 +0300
Subject: CHUI-186 CHUI-187 FIX Removing a P2P convrsation from converstaion
 widget in the upper right corner when a new participant is added. End call
 prompt removed when adding a new participant to a P2P voice call. After
 adding a participant to a P2P voice conversation the resulting conference
 call is restarted voice invites to all participants.

---
 indra/newview/llavataractions.cpp    |  4 +-
 indra/newview/llavataractions.h      |  4 +-
 indra/newview/llimfloater.cpp        | 73 ++++++++++++++++++++----------------
 indra/newview/llimfloater.h          |  2 +-
 indra/newview/llpanelpeoplemenus.cpp |  2 +-
 5 files changed, 46 insertions(+), 39 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 21367c224d..56c9533e11 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -235,7 +235,7 @@ void LLAvatarActions::startCall(const LLUUID& id)
 }
 
 // static
-void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
+void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id)
 {
 	if (ids.size() == 0)
 	{
@@ -252,7 +252,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
 	// create the new ad hoc voice session
 	const std::string title = LLTrans::getString("conference-title");
 	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START,
-										   ids[0], id_array, true);
+										   ids[0], id_array, true, floater_id);
 	if (session_id == LLUUID::null)
 	{
 		return;
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 46830eb22c..259e87c336 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -82,9 +82,9 @@ public:
 	static void startCall(const LLUUID& id);
 
 	/**
-	 * Start an ad-hoc conference voice call with multiple users
+	 * Start an ad-hoc conference voice call with multiple users in a specific IM floater.
 	 */
-	static void startAdhocCall(const uuid_vec_t& ids);
+	static void startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
 
 	/**
 	 * Start conference chat with the given avatars in a specific IM floater.
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 9d3c0f98ce..536d0b9a23 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -322,7 +322,7 @@ BOOL LLIMFloater::postBuild()
 
 void LLIMFloater::onAddButtonClicked()
 {
-       LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::onAvatarPicked, this, _1, _2), TRUE, TRUE);
+       LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::addSessionParticipants, this, _1), TRUE, TRUE);
        if (!picker)
        {
                return;
@@ -337,25 +337,6 @@ void LLIMFloater::onAddButtonClicked()
        }
 }
 
-void LLIMFloater::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
-{
-       if (mIsP2PChat)
-       {
-               mStartConferenceInSameFloater = true;
-               onClose(false);
-
-               uuid_vec_t temp_ids;
-               temp_ids.push_back(mOtherParticipantUUID);
-               temp_ids.insert(temp_ids.end(), ids.begin(), ids.end());
-
-               LLAvatarActions::startConference(temp_ids, mSessionID);
-       }
-       else
-       {
-               inviteToSession(ids);
-       }
-}
-
 bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
 {
        if (!mSession
@@ -388,6 +369,44 @@ bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
        return true;
 }
 
+void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids)
+{
+	if (mIsP2PChat)
+	{
+		mStartConferenceInSameFloater = true;
+
+		uuid_vec_t temp_ids;
+
+		// Add the initial participant of a P2P session
+		temp_ids.push_back(mOtherParticipantUUID);
+		temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end());
+
+		LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+		// first check whether this is a voice session
+		bool is_voice_call = voice_channel != NULL && voice_channel->isActive();
+
+		// then we can close the current session
+		gIMMgr->leaveSession(mSessionID);
+		LLIMConversation::onClose(false);
+
+		// Start a new ad hoc voice call if we invite new participants to a P2P call,
+		// or start a text chat otherwise.
+		if (is_voice_call)
+		{
+			LLAvatarActions::startAdhocCall(temp_ids, mSessionID);
+		}
+		else
+		{
+			LLAvatarActions::startConference(temp_ids, mSessionID);
+		}
+	}
+	else
+	{
+		inviteToSession(uuids);
+	}
+}
+
 void LLIMFloater::boundVoiceChannel()
 {
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
@@ -1096,19 +1115,7 @@ bool LLIMFloater::dropPerson(LLUUID* person_id, bool drop)
 		res = canAddSelectedToChat(ids);
 		if(res && drop)
 		{
-			if (mIsP2PChat)
-			{
-				mStartConferenceInSameFloater = true;
-				onClose(false);
-
-				ids.push_back(mOtherParticipantUUID);
-
-				LLAvatarActions::startConference(ids, mSessionID);
-			}
-			else
-			{
-				inviteToSession(ids);
-			}
+			addSessionParticipants(ids);
 		}
 	}
 
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 23f9e75e21..2e8fc84746 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -152,7 +152,7 @@ private:
 	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
 	void setTyping(bool typing);
 	void onAddButtonClicked();
-	void onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
+	void addSessionParticipants(const uuid_vec_t& uuids);
 	bool canAddSelectedToChat(const uuid_vec_t& uuids);
 
 	void onCallButtonClicked();
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index ac2109dda4..c9eebe24d3 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -82,7 +82,7 @@ LLContextMenu* NearbyMenu::createMenu()
 
 		// registrar.add("Avatar.AddFriend",	boost::bind(&LLAvatarActions::requestFriendshipDialog,	mUUIDs)); // *TODO: unimplemented
 		registrar.add("Avatar.IM",			boost::bind(&LLAvatarActions::startConference,			mUUIDs, LLUUID::null));
-		registrar.add("Avatar.Call",		boost::bind(&LLAvatarActions::startAdhocCall,			mUUIDs));
+		registrar.add("Avatar.Call",		boost::bind(&LLAvatarActions::startAdhocCall,			mUUIDs, LLUUID::null));
 		registrar.add("Avatar.OfferTeleport",	boost::bind(&NearbyMenu::offerTeleport,					this));
 		registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog,		mUUIDs));
 		// registrar.add("Avatar.Share",		boost::bind(&LLAvatarActions::startIM,					mUUIDs)); // *TODO: unimplemented
-- 
cgit v1.2.3


From ac0243a006fa28e872e4ee88f7c1588eaefeaecf Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Tue, 3 Jul 2012 22:32:21 +0300
Subject: CHUI-188 FIX for crash in adding chat participants. Modified the
 duplicated participants check procedure LLIMFloater::canAddSelectedToChat()
 to use the list, updated by LLSpeakerMgr instead of
 LLIMSession::mInitialTargetIDs list, which is initialized at session start
 and not updated afterwards.

---
 indra/newview/llimfloater.cpp | 72 +++++++++++++++++++++++++++----------------
 1 file changed, 46 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 536d0b9a23..a506f0f9f3 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -339,34 +339,54 @@ void LLIMFloater::onAddButtonClicked()
 
 bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
 {
-       if (!mSession
-               || mDialog == IM_SESSION_GROUP_START
-               || mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID))
-       {
-               return false;
-       }
+	if (!mSession
+		|| mDialog == IM_SESSION_GROUP_START
+		|| mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID))
+	{
+		return false;
+	}
 
-       for (uuid_vec_t::const_iterator id = uuids.begin();
-                       id != uuids.end(); ++id)
-       {
-    	   	   // Skip this check for ad hoc conferences,
-    	       // conference participants should be listed in mSession->mInitialTargetIDs.
-               if (mIsP2PChat && *id == mOtherParticipantUUID)
-               {
-                       return false;
-               }
-
-               for (uuid_vec_t::const_iterator target_id = mSession->mInitialTargetIDs.begin();
-                               target_id != mSession->mInitialTargetIDs.end(); ++target_id)
-               {
-                       if (*id == *target_id)
-                       {
-                               return false;
-                       }
-               }
-       }
+	if (mIsP2PChat)
+	{
+		// For a P2P session just check if we are not adding the other participant.
+
+		for (uuid_vec_t::const_iterator id = uuids.begin();
+				id != uuids.end(); ++id)
+		{
+			if (*id == mOtherParticipantUUID)
+			{
+				return false;
+			}
+		}
+	}
+	else
+	{
+		// For a conference session we need to check against the list from LLSpeakerMgr,
+		// because this list may change when participants join or leave the session.
+
+		LLSpeakerMgr::speaker_list_t speaker_list;
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if (speaker_mgr)
+		{
+			speaker_mgr->getSpeakerList(&speaker_list, true);
+		}
 
-       return true;
+		for (uuid_vec_t::const_iterator id = uuids.begin();
+				id != uuids.end(); ++id)
+		{
+			for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin();
+					it != speaker_list.end(); ++it)
+			{
+				const LLPointer<LLSpeaker>& speaker = *it;
+				if (*id == speaker->mID)
+				{
+					return false;
+				}
+			}
+		}
+	}
+
+	return true;
 }
 
 void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids)
-- 
cgit v1.2.3


From a8defa513c3b2b83f476a1de115fd0332566b483 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 3 Jul 2012 17:05:28 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose removed viewer
 dependencies from folderview code

---
 indra/newview/llfolderview.cpp      | 84 +++++++++----------------------------
 indra/newview/llfolderview.h        |  5 +--
 indra/newview/llfolderviewitem.cpp  | 10 -----
 indra/newview/llfolderviewmodel.cpp |  3 +-
 indra/newview/llfolderviewmodel.h   |  1 -
 indra/newview/llinventorybridge.cpp |  6 +--
 indra/newview/llinventorypanel.cpp  | 11 +++++
 indra/newview/llinventorypanel.h    | 79 +---------------------------------
 8 files changed, 36 insertions(+), 163 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 6bc89cdbca..10677db094 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -27,25 +27,18 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llfolderview.h"
-
+#include "llfolderviewmodel.h"
 #include "llclipboard.h" // *TODO: remove this once hack below gone.
 #include "llkeyboard.h"
 #include "lllineeditor.h"
 #include "llmenugl.h"
 #include "llpanel.h"
 #include "llscrollcontainer.h" // hack to allow scrolling
+#include "lltextbox.h"
 #include "lltrans.h"
 #include "llui.h"
 #include "lluictrlfactory.h"
 
-// TODO RN: kill these
-// newview includes
-#include "llcallbacklist.h"			// per-frame on-idle
-#include "llfloaterproperties.h"	// showProperties
-#include "llviewerwindow.h"			// renamer popup handling
-#include "llpreview.h"				// openSelectedItems
-#include "llinventorypanel.h"		// idle loop for filtering, sort order declarations, etc.
-
 // Linden library includes
 #include "lldbstrings.h"
 #include "llfocusmgr.h"
@@ -172,7 +165,6 @@ LLFolderView::LLFolderView(const Params& p)
 	mNeedsAutoSelect( FALSE ),
 	mAutoSelectOverride(FALSE),
 	mNeedsAutoRename(FALSE),
-	mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME),	// This gets overridden by a pref immediately
 	mShowSelectionContext(FALSE),
 	mShowSingleSelection(FALSE),
 	mArrangeGeneration(0),
@@ -199,7 +191,6 @@ LLFolderView::LLFolderView(const Params& p)
 	mAutoOpenTimer.stop();
 	mKeyboardSelection = FALSE;
 	mIndentation = p.folder_indentation;
-	gIdleCallbacks.addFunction(idle, this);
 
 	//clear label
 	// go ahead and render root folder as usual
@@ -269,7 +260,6 @@ LLFolderView::~LLFolderView( void )
 	mStatusTextBox = NULL;
 
 	mAutoOpenItems.removeAllNodes();
-	gIdleCallbacks.deleteFunction(idle, this);
 
 	if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
 
@@ -291,16 +281,16 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 {
 	LLFolderViewFolder::addFolder(folder);
 
-	mFolders.remove(folder);
-	// enforce sort order of My Inventory followed by Library
-	if (((LLFolderViewModelItemInventory*)folder->getViewModelItem())->getUUID() == gInventory.getLibraryRootFolderID())
-	{
-		mFolders.push_back(folder);
-	}
-	else
-	{
-		mFolders.insert(mFolders.begin(), folder);
-	}
+	// TODO RN: enforce sort order of My Inventory followed by Library
+	//mFolders.remove(folder);
+	//if (((LLFolderViewModelItemInventory*)folder->getViewModelItem())->getUUID() == gInventory.getLibraryRootFolderID())
+	//{
+	//	mFolders.push_back(folder);
+	//}
+	//else
+	//{
+	//	mFolders.insert(mFolders.begin(), folder);
+	//}
 
 	return TRUE;
 }
@@ -754,7 +744,7 @@ void LLFolderView::closeRenamer( void )
 	if (mRenamer && mRenamer->getVisible())
 	{
 		// Triggers onRenamerLost() that actually closes the renamer.
-		gViewerWindow->removePopup(mRenamer);
+		LLUI::removePopup(mRenamer);
 	}
 }
 
@@ -785,24 +775,6 @@ bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFol
 	return false;
 }
 
-// static
-void LLFolderView::removeCutItems()
-{
-	// There's no item in "cut" mode on the clipboard -> exit
-	if (!LLClipboard::instance().isCutMode())
-		return;
-
-	// Get the list of clipboard item uuids and iterate through them
-	LLDynamicArray<LLUUID> objects;
-	LLClipboard::instance().pasteFromClipboard(objects);
-	for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
-		 iter != objects.end();
-		 ++iter)
-	{
-		gInventory.removeObject(*iter);
-	}
-}
-
 void LLFolderView::removeSelectedItems()
 {
 	if(getVisible() && getEnabled())
@@ -1126,9 +1098,9 @@ void LLFolderView::cut()
 			if(listener)
 			{
 				listener->cutToClipboard();
+				listener->removeItem();
 			}
 		}
-		LLFolderView::removeCutItems();
 	}
 	mSearchString.clear();
 }
@@ -1222,7 +1194,7 @@ void LLFolderView::startRenamingSelectedItem( void )
 		// set focus will fail unless item is visible
 		mRenamer->setFocus( TRUE );
 		mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
-		gViewerWindow->addPopup(mRenamer);
+		LLUI::addPopup(mRenamer);
 	}
 }
 
@@ -1808,16 +1780,10 @@ static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
 static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
 
 // Main idle routine
-void LLFolderView::doIdle()
+void LLFolderView::update()
 {
 	// If this is associated with the user's inventory, don't do anything
 	// until that inventory is loaded up.
-	const LLInventoryPanel *inventory_panel = dynamic_cast<LLInventoryPanel*>(mParentPanel);
-	if (inventory_panel && !inventory_panel->getIsViewsInitialized())
-	{
-		return;
-	}
-	
 	LLFastTimer t2(FTM_INVENTORY);
 
 	if (getFolderViewModel()->getFilter()->isModified() && getFolderViewModel()->getFilter()->isNotDefault())
@@ -1859,8 +1825,8 @@ void LLFolderView::doIdle()
 	BOOL filter_finished = getViewModelItem()->passedFilter()
 						&& mViewModel->contentsReady();
 	if (filter_finished 
-		|| gFocusMgr.childHasKeyboardFocus(inventory_panel) 
-		|| gFocusMgr.childHasMouseCapture(inventory_panel))
+		|| gFocusMgr.childHasKeyboardFocus(getParent()) // assume we are inside a scroll container
+		|| gFocusMgr.childHasMouseCapture(getParent()))
 	{
 		// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
 		mNeedsAutoSelect = FALSE;
@@ -1919,7 +1885,6 @@ void LLFolderView::doIdle()
 		constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
 	}
 
-
 	BOOL is_visible = isInVisibleChain();
 
 	if ( is_visible )
@@ -1954,17 +1919,6 @@ void LLFolderView::doIdle()
 	mSignalSelectCallback = FALSE;
 }
 
-
-//static
-void LLFolderView::idle(void* user_data)
-{
-	LLFolderView* self = (LLFolderView*)user_data;
-	if ( self )
-	{	// Do the real idle 
-		self->doIdle();
-	}
-}
-
 void LLFolderView::dumpSelectionInformation()
 {
 	llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
@@ -1988,7 +1942,7 @@ void LLFolderView::updateRenamerPosition()
 		screenPointToLocal( x, y, &x, &y );
 		mRenamer->setOrigin( x, y );
 
-		LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidthScaled(), 0);
+		LLRect scroller_rect(0, 0, LLUI::getWindowSize().mV[VX], 0);
 		if (mScrollContainer)
 		{
 			scroller_rect = mScrollContainer->getContentWindowRect();
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index e098119293..78f1d8aff2 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -165,7 +165,6 @@ public:
 
 	// Deletion functionality
  	void removeSelectedItems();
- 	static void removeCutItems();
 
 	// Open the selected item
 	void openSelectedItems( void );
@@ -223,8 +222,7 @@ public:
 	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
 	bool getUseEllipses() { return mUseEllipses; }
 
-	void	doIdle();						// Real idle routine
-	static void idle(void* user_data);		// static glue to doIdle()
+	void	update();						// needs to be called periodically (e.g. once per frame)
 
 	BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
 	BOOL needsAutoRename() { return mNeedsAutoRename; }
@@ -288,7 +286,6 @@ protected:
 	bool							mUseLabelSuffix;
 	bool							mShowItemLinkOverlays;
 	
-	U32								mSortOrder;
 	LLDepthStack<LLFolderViewFolder>	mAutoOpenItems;
 	LLFolderViewFolder*				mAutoOpenCandidate;
 	LLFrameTimer					mAutoOpenTimer;
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 3937d4332b..dee3fe7218 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -1798,16 +1798,6 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
 
 BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 {
-	/* Disable outfit double click to wear
-	const LLUUID &cat_uuid = getViewModelItem()->getUUID();
-	const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
-	if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
-	{
-		getViewModelItem()->performAction(NULL, NULL,"replaceoutfit");
-		return TRUE;
-	}
-	*/
-
 	BOOL handled = FALSE;
 	if( isOpen() )
 	{
diff --git a/indra/newview/llfolderviewmodel.cpp b/indra/newview/llfolderviewmodel.cpp
index 92db84156e..ca6225aca7 100644
--- a/indra/newview/llfolderviewmodel.cpp
+++ b/indra/newview/llfolderviewmodel.cpp
@@ -28,7 +28,6 @@
 
 #include "llfolderviewmodel.h"
 #include "lltrans.h"
-#include "llviewercontrol.h"
 
 bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
 {
@@ -49,6 +48,6 @@ std::string LLFolderViewModelCommon::getStatusText()
 
 void LLFolderViewModelCommon::filter()
 {
-	getFilter()->setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
+	getFilter()->setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
 	mFolderView->getViewModelItem()->filter(*getFilter());
 }
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
index 98b7255137..079409c2a4 100644
--- a/indra/newview/llfolderviewmodel.h
+++ b/indra/newview/llfolderviewmodel.h
@@ -27,7 +27,6 @@
 
 #include "llfontgl.h"	// just for StyleFlags enum
 #include "llfolderview.h"
-#include "lltooldraganddrop.h"
 
 // These are grouping of inventory types.
 // Order matters when sorting system folders to the top.
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 002278601a..d17c25d9f3 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1400,7 +1400,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 	else if ("cut" == action)
 	{
 		cutToClipboard();
-		LLFolderView::removeCutItems();
+		gInventory.removeObject(mUUID);
 		return;
 	}
 	else if ("copy" == action)
@@ -1680,14 +1680,12 @@ BOOL LLItemBridge::renameItem(const std::string& new_name)
 	return FALSE;
 }
 
-
 BOOL LLItemBridge::removeItem()
 {
 	if(!isItemRemovable())
 	{
 		return FALSE;
 	}
-
 	
 	// move it to the trash
 	LLPreview::hide(mUUID, TRUE);
@@ -2870,7 +2868,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 	else if ("cut" == action)
 	{
 		cutToClipboard();
-		LLFolderView::removeCutItems();
+		gInventory.removeObject(mUUID);
 		return;
 	}
 	else if ("copy" == action)
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index c1ffe89184..fed9893158 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -258,6 +258,8 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 
 LLInventoryPanel::~LLInventoryPanel()
 {
+	gIdleCallbacks.deleteFunction(idle, this);
+
 	U32 sort_order = getFolderViewModel()->getSorter().getSortOrder();
 	if (mSortOrderSetting != INHERIT_SORT_ORDER)
 	{
@@ -566,12 +568,21 @@ void LLInventoryPanel::onIdle(void *userdata)
 	}
 }
 
+void LLInventoryPanel::idle(void* user_data)
+{
+	LLInventoryPanel* panel = (LLInventoryPanel*)user_data;
+	panel->mFolderRoot->doIdle();
+}
+
+
 void LLInventoryPanel::initializeViews()
 {
 	if (!gInventory.isInventoryUsable()) return;
 
 	rebuildViewsFor(gInventory.getRootFolderID());
 
+	gIdleCallbacks.addFunction(idle, this);
+
 	mViewsInitialized = true;
 	
 	openStartFolderOrMyInventory();
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 1061f12575..465ccdd582 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -45,82 +45,6 @@ class LLInventoryFVBridgeBuilder;
 class LLInvPanelComplObserver;
 class LLFolderViewModelInventory;
 
-class LLFolderViewModelItemInventory
-	:	public LLFolderViewModelItemCommon
-{
-public:
-	LLFolderViewModelItemInventory()
-	:	mRootViewModel(NULL)
-	{}
-	void setRootViewModel(LLFolderViewModelInventory* root_view_model)
-	{
-		mRootViewModel = root_view_model;
-	}
-	virtual const LLUUID& getUUID() const = 0;
-	virtual time_t getCreationDate() const = 0;	// UTC seconds
-	virtual void setCreationDate(time_t creation_date_utc) = 0;
-	virtual PermissionMask getPermissionMask() const = 0;
-	virtual LLFolderType::EType getPreferredType() const = 0;
-	virtual void showProperties(void) = 0;
-	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual.
-	virtual BOOL isUpToDate() const = 0;
-	virtual bool hasChildren() const = 0;
-	virtual LLInventoryType::EType getInventoryType() const = 0;
-	virtual void performAction(LLInventoryModel* model, std::string action)   = 0;
-	virtual LLWearableType::EType getWearableType() const = 0;
-	virtual EInventorySortGroup getSortGroup() const = 0;
-	virtual LLInventoryObject* getInventoryObject() const = 0;
-	virtual void requestSort();
-	virtual bool potentiallyVisible();
-	virtual bool passedFilter(S32 filter_generation = -1);
-	virtual bool descendantsPassedFilter(S32 filter_generation = -1);
-	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
-	virtual bool filter( LLFolderViewFilter& filter);
-	virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
-protected:
-	LLFolderViewModelInventory* mRootViewModel;
-};
-
-class LLInventorySort
-{
-public:
-	LLInventorySort(U32 order = 0)
-	:	mSortOrder(order),
-		mByDate(false),
-		mSystemToTop(false),
-		mFoldersByName(false)
-	{
-		mByDate = (order & LLInventoryFilter::SO_DATE);
-		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
-		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
-	}
-
-	bool isByDate() const { return mByDate; }
-	U32 getSortOrder() const { return mSortOrder; }
-
-	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
-private:
-	U32  mSortOrder;
-	bool mByDate;
-	bool mSystemToTop;
-	bool mFoldersByName;
-};
-
-class LLFolderViewModelInventory
-	:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter>
-{
-public:
-	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t;
-
-	virtual ~LLFolderViewModelInventory() {}
-
-	void sort(LLFolderViewFolder* folder);
-
-	bool contentsReady();
-
-};
-
-
 class LLInventoryPanel : public LLPanel
 {
 	//--------------------------------------------------------------------
@@ -232,7 +156,8 @@ public:
 	void doCreate(const LLSD& userdata);
 	bool beginIMSession();
 	bool attachObject(const LLSD& userdata);
-	
+	static void idle(void* user_data);
+
 	// DEBUG ONLY:
 	static void dumpSelectionInformation(void* user_data);
 
-- 
cgit v1.2.3


From 52bf9e20454181d8acb0ac419a882cc1a0e3af9e Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 3 Jul 2012 18:11:14 -0700
Subject: CHUI-174 : Fixed crash in forced response to notifications. Use an
 empty form in that case and allow the notification to not be in the
 notifications list.

---
 indra/newview/llviewermessage.cpp | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index dd78bbd491..7e1f186769 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1481,7 +1481,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	}
 	 
 	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
-	llassert(notification_ptr != NULL);
 	
 	// For muting, we need to add the mute, then decline the offer.
 	// This must be done here because:
@@ -1504,7 +1503,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	
 	bool busy = gAgent.getBusy();
 	
-	LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+	LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm());
 
 	switch(button)
 	{
@@ -1550,7 +1549,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			break;
 		}
 
-		modified_form->setElementEnabled("Show", false);
+		if (modified_form != NULL)
+		{
+			modified_form->setElementEnabled("Show", false);
+		}
 		break;
 		// end switch (mIM)
 			
@@ -1567,7 +1569,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 		break;
 
 	case IOR_MUTE:
-		modified_form->setElementEnabled("Mute", false);
+		if (modified_form != NULL)
+		{
+			modified_form->setElementEnabled("Mute", false);
+		}
 		// MUTE falls through to decline
 	case IOR_DECLINE:
 		{
@@ -1604,8 +1609,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 				busy_message(gMessageSystem, mFromID);
 			}
 
-			modified_form->setElementEnabled("Show", false);
-			modified_form->setElementEnabled("Discard", false);
+			if (modified_form != NULL)
+			{
+				modified_form->setElementEnabled("Show", false);
+				modified_form->setElementEnabled("Discard", false);
+			}
 
 			break;
 		}
@@ -1627,8 +1635,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 		delete this;
 	}
 
-	notification_ptr->updateForm(modified_form);
-	notification_ptr->repost();
+	if (notification_ptr != NULL)
+	{
+		notification_ptr->updateForm(modified_form);
+		notification_ptr->repost();
+	}
 
 	return false;
 }
-- 
cgit v1.2.3


From cea3c37dcb09eb30cb986ecac4d29a4ff1cc0898 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 3 Jul 2012 19:58:49 -0700
Subject: CHUI-164 : Fix crash when closing conversations using the
 conversation widget. Populated the sessionRemoved() method with code to close
 the floater and clean up the list.

---
 indra/newview/llimfloatercontainer.cpp | 11 +++++++++--
 indra/newview/llimfloatercontainer.h   |  2 +-
 2 files changed, 10 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 261b5f33a2..08ace601a3 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -73,8 +73,15 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-		LLIMFloater::show(session_id);
-};
+	LLIMFloater::show(session_id);
+}
+
+void LLIMFloaterContainer::sessionRemoved(const LLUUID& session_id)
+{
+	LLIMFloater* floaterp = LLIMFloater::findInstance(session_id);
+	LLFloater::onClickClose(floaterp);
+	removeConversationListItem(floaterp);
+}
 
 BOOL LLIMFloaterContainer::postBuild()
 {
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 2bbd371e8f..c062127bee 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -158,7 +158,7 @@ public:
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
-	/*virtual*/ void sessionRemoved(const LLUUID& session_id) {};
+	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {};
 
 private:
-- 
cgit v1.2.3


From 1494a1058f41c5aa00a8ed08fe71123f63e92e81 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 3 Jul 2012 23:55:39 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose move llfolderview*
 into LLUI!

---
 indra/llui/CMakeLists.txt                    |    6 +
 indra/llui/llfolderview.cpp                  | 2078 +++++++++++++++++++++++++
 indra/llui/llfolderview.h                    |  388 +++++
 indra/llui/llfolderviewitem.cpp              | 2032 +++++++++++++++++++++++++
 indra/llui/llfolderviewitem.h                |  420 +++++
 indra/llui/llfolderviewmodel.cpp             |   53 +
 indra/llui/llfolderviewmodel.h               |  353 +++++
 indra/newview/CMakeLists.txt                 |    6 -
 indra/newview/llfolderview.cpp               | 2105 --------------------------
 indra/newview/llfolderview.h                 |  393 -----
 indra/newview/llfolderviewitem.cpp           | 2060 -------------------------
 indra/newview/llfolderviewitem.h             |  418 -----
 indra/newview/llfolderviewmodel.cpp          |   53 -
 indra/newview/llfolderviewmodel.h            |  357 -----
 indra/newview/llfolderviewmodelinventory.cpp |   26 +
 indra/newview/llfolderviewmodelinventory.h   |   13 +-
 indra/newview/llimfloatercontainer.h         |    9 -
 indra/newview/llinventorybridge.h            |    3 +-
 indra/newview/llinventorypanel.cpp           |   19 +-
 indra/newview/llpanelobjectinventory.cpp     |    2 +-
 indra/newview/lltexturectrl.cpp              |    1 +
 21 files changed, 5389 insertions(+), 5406 deletions(-)
 create mode 100644 indra/llui/llfolderview.cpp
 create mode 100644 indra/llui/llfolderview.h
 create mode 100644 indra/llui/llfolderviewitem.cpp
 create mode 100644 indra/llui/llfolderviewitem.h
 create mode 100644 indra/llui/llfolderviewmodel.cpp
 create mode 100644 indra/llui/llfolderviewmodel.h
 delete mode 100644 indra/newview/llfolderview.cpp
 delete mode 100644 indra/newview/llfolderview.h
 delete mode 100644 indra/newview/llfolderviewitem.cpp
 delete mode 100644 indra/newview/llfolderviewitem.h
 delete mode 100644 indra/newview/llfolderviewmodel.cpp
 delete mode 100644 indra/newview/llfolderviewmodel.h

(limited to 'indra')

diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index b50ed2342d..a9ad0a3c0b 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -54,6 +54,9 @@ set(llui_SOURCE_FILES
     llfloaterreglistener.cpp
     llflyoutbutton.cpp 
     llfocusmgr.cpp
+    llfolderview.cpp
+    llfolderviewitem.cpp
+    llfolderviewmodel.cpp
     llfunctorregistry.cpp
     lliconctrl.cpp
     llkeywords.cpp
@@ -154,6 +157,9 @@ set(llui_HEADER_FILES
     llfloaterreglistener.h
     llflyoutbutton.h 
     llfocusmgr.h
+    llfolderview.h
+    llfolderviewitem.h
+    llfolderviewmodel.h
     llfunctorregistry.h
     llhandle.h
     llhelp.h
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
new file mode 100644
index 0000000000..0d3bc44ae4
--- /dev/null
+++ b/indra/llui/llfolderview.cpp
@@ -0,0 +1,2078 @@
+/** 
+ * @file llfolderview.cpp
+ * @brief Implementation of the folder view collection of classes.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llfolderview.h"
+#include "llfolderviewmodel.h"
+#include "llclipboard.h" // *TODO: remove this once hack below gone.
+#include "llkeyboard.h"
+#include "lllineeditor.h"
+#include "llmenugl.h"
+#include "llpanel.h"
+#include "llscrollcontainer.h" // hack to allow scrolling
+#include "lltextbox.h"
+#include "lltrans.h"
+#include "llui.h"
+#include "lluictrlfactory.h"
+
+// Linden library includes
+#include "lldbstrings.h"
+#include "llfocusmgr.h"
+#include "llfontgl.h"
+#include "llgl.h" 
+#include "llrender.h"
+
+// Third-party library includes
+#include <algorithm>
+
+///----------------------------------------------------------------------------
+/// Local function declarations, constants, enums, and typedefs
+///----------------------------------------------------------------------------
+
+const S32 RENAME_WIDTH_PAD = 4;
+const S32 RENAME_HEIGHT_PAD = 1;
+const S32 AUTO_OPEN_STACK_DEPTH = 16;
+const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH
+			+ LLFolderViewItem::ICON_PAD 
+			+ LLFolderViewItem::ARROW_SIZE 
+			+ LLFolderViewItem::TEXT_PAD 
+			+ /*first few characters*/ 40;
+const S32 MINIMUM_RENAMER_WIDTH = 80;
+
+// *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params.
+const S32 STATUS_TEXT_HPAD = 6;
+const S32 STATUS_TEXT_VPAD = 8;
+
+enum {
+	SIGNAL_NO_KEYBOARD_FOCUS = 1,
+	SIGNAL_KEYBOARD_FOCUS = 2
+};
+
+F32 LLFolderView::sAutoOpenTime = 1.f;
+
+//---------------------------------------------------------------------------
+
+// Tells all folders in a folderview to close themselves
+// For efficiency, calls setOpenArrangeRecursively().
+// The calling function must then call:
+//	LLFolderView* root = getRoot();
+//	if( root )
+//	{
+//		root->arrange( NULL, NULL );
+//		root->scrollToShowSelection();
+//	}
+// to patch things up.
+class LLCloseAllFoldersFunctor : public LLFolderViewFunctor
+{
+public:
+	LLCloseAllFoldersFunctor(BOOL close) { mOpen = !close; }
+	virtual ~LLCloseAllFoldersFunctor() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+
+	BOOL mOpen;
+};
+
+
+void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)
+{
+	folder->setOpenArrangeRecursively(mOpen);
+}
+
+// Do nothing.
+void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
+{ }
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewScrollContainer
+///----------------------------------------------------------------------------
+
+// virtual
+const LLRect LLFolderViewScrollContainer::getScrolledViewRect() const
+{
+	LLRect rect = LLRect::null;
+	if (mScrolledView)
+	{
+		LLFolderView* folder_view = dynamic_cast<LLFolderView*>(mScrolledView);
+		if (folder_view)
+		{
+			S32 height = folder_view->getRect().getHeight();
+
+			rect = mScrolledView->getRect();
+			rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), height);
+		}
+	}
+
+	return rect;
+}
+
+LLFolderViewScrollContainer::LLFolderViewScrollContainer(const LLScrollContainer::Params& p)
+:	LLScrollContainer(p)
+{}
+
+///----------------------------------------------------------------------------
+/// Class LLFolderView
+///----------------------------------------------------------------------------
+LLFolderView::Params::Params()
+:	title("title"),
+	use_label_suffix("use_label_suffix"),
+	allow_multiselect("allow_multiselect", true),
+	show_empty_message("show_empty_message", true),
+	use_ellipses("use_ellipses", false)
+{
+	folder_indentation = -4;
+}
+
+
+// Default constructor
+LLFolderView::LLFolderView(const Params& p)
+:	LLFolderViewFolder(p),
+	mScrollContainer( NULL ),
+	mPopupMenuHandle(),
+	mAllowMultiSelect(p.allow_multiselect),
+	mShowEmptyMessage(p.show_empty_message),
+	mShowFolderHierarchy(FALSE),
+	mRenameItem( NULL ),
+	mNeedsScroll( FALSE ),
+	mUseLabelSuffix(p.use_label_suffix),
+	mPinningSelectedItem(FALSE),
+	mNeedsAutoSelect( FALSE ),
+	mAutoSelectOverride(FALSE),
+	mNeedsAutoRename(FALSE),
+	mShowSelectionContext(FALSE),
+	mShowSingleSelection(FALSE),
+	mArrangeGeneration(0),
+	mSignalSelectCallback(0),
+	mMinWidth(0),
+	mDragAndDropThisFrame(FALSE),
+	mCallbackRegistrar(NULL),
+	mParentPanel(p.parent_panel),
+	mUseEllipses(p.use_ellipses),
+	mDraggingOverItem(NULL),
+	mStatusTextBox(NULL),
+	mShowItemLinkOverlays(p.show_item_link_overlays),
+	mViewModel(p.view_model)
+{
+	mViewModel->setFolderView(this);
+	mRoot = this;
+
+	LLRect rect = p.rect;
+	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
+	setRect( rect );
+	reshape(rect.getWidth(), rect.getHeight());
+	mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH);
+	mAutoOpenCandidate = NULL;
+	mAutoOpenTimer.stop();
+	mKeyboardSelection = FALSE;
+	mIndentation = p.folder_indentation;
+
+	//clear label
+	// go ahead and render root folder as usual
+	// just make sure the label ("Inventory Folder") never shows up
+	mLabel = LLStringUtil::null;
+
+	// Escape is handled by reverting the rename, not commiting it (default behavior)
+	LLLineEditor::Params params;
+	params.name("ren");
+	params.rect(rect);
+	params.font(getLabelFontForStyle(LLFontGL::NORMAL));
+	params.max_length.bytes(DB_INV_ITEM_NAME_STR_LEN);
+	params.commit_callback.function(boost::bind(&LLFolderView::commitRename, this, _2));
+	params.prevalidate_callback(&LLTextValidate::validateASCIIPrintableNoPipe);
+	params.commit_on_focus_lost(true);
+	params.visible(false);
+	mRenamer = LLUICtrlFactory::create<LLLineEditor> (params);
+	addChild(mRenamer);
+
+	// Textbox
+	LLTextBox::Params text_p;
+	LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+	LLRect new_r = LLRect(rect.mLeft + ICON_PAD,
+			      rect.mTop - TEXT_PAD,
+			      rect.mRight,
+			      rect.mTop - TEXT_PAD - font->getLineHeight());
+	text_p.rect(new_r);
+	text_p.name(std::string(p.name));
+	text_p.font(font);
+	text_p.visible(false);
+	text_p.parse_urls(true);
+	text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047
+	// set text padding the same as in People panel. EXT-7047, EXT-4837
+	text_p.h_pad(STATUS_TEXT_HPAD);
+	text_p.v_pad(STATUS_TEXT_VPAD);
+	mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);
+	mStatusTextBox->setFollowsLeft();
+	mStatusTextBox->setFollowsTop();
+	//addChild(mStatusTextBox);
+
+
+	// make the popup menu available
+	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+	if (!menu)
+	{
+		menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
+	}
+	menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
+	mPopupMenuHandle = menu->getHandle();
+
+	mViewModelItem->openItem();
+}
+
+// Destroys the object
+LLFolderView::~LLFolderView( void )
+{
+	closeRenamer();
+
+	// The release focus call can potentially call the
+	// scrollcontainer, which can potentially be called with a partly
+	// destroyed scollcontainer. Just null it out here, and no worries
+	// about calling into the invalid scroll container.
+	// Same with the renamer.
+	mScrollContainer = NULL;
+	mRenameItem = NULL;
+	mRenamer = NULL;
+	mStatusTextBox = NULL;
+
+	mAutoOpenItems.removeAllNodes();
+
+	if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
+
+	mAutoOpenItems.removeAllNodes();
+	clearSelection();
+	mItems.clear();
+	mFolders.clear();
+
+	delete mViewModel;
+	mViewModel = NULL;
+}
+
+BOOL LLFolderView::canFocusChildren() const
+{
+	return FALSE;
+}
+
+BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
+{
+	LLFolderViewFolder::addFolder(folder);
+
+	// TODO RN: enforce sort order of My Inventory followed by Library
+	//mFolders.remove(folder);
+	//if (((LLFolderViewModelItemInventory*)folder->getViewModelItem())->getUUID() == gInventory.getLibraryRootFolderID())
+	//{
+	//	mFolders.push_back(folder);
+	//}
+	//else
+	//{
+	//	mFolders.insert(mFolders.begin(), folder);
+	//}
+
+	return TRUE;
+}
+
+void LLFolderView::closeAllFolders()
+{
+	// Close all the folders
+	setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
+	arrangeAll();
+}
+
+void LLFolderView::openTopLevelFolders()
+{
+	for (folders_t::iterator iter = mFolders.begin();
+		 iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		(*fit)->setOpen(TRUE);
+	}
+}
+
+// This view grows and shrinks to enclose all of its children items and folders.
+// *width should be 0
+// conform show folder state works
+S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
+{
+	mMinWidth = 0;
+	S32 target_height;
+
+	LLFolderViewFolder::arrange(&mMinWidth, &target_height);
+
+	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
+	reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
+
+	LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
+	if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
+	{
+		reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
+	}
+
+	// move item renamer text field to item's new position
+	updateRenamerPosition();
+
+	return llround(mTargetHeight);
+}
+
+static LLFastTimer::DeclareTimer FTM_FILTER("Filter Folder View");
+
+void LLFolderView::filter( LLFolderViewFilter& filter )
+{
+	LLFastTimer t2(FTM_FILTER);
+	filter.setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
+
+	getViewModelItem()->filter(filter);
+}
+
+void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+	LLRect scroll_rect;
+	if (mScrollContainer)
+	{
+		LLView::reshape(width, height, called_from_parent);
+		scroll_rect = mScrollContainer->getContentWindowRect();
+	}
+	width = llmax(mMinWidth, scroll_rect.getWidth());
+	height = llmax(llround(mCurHeight), scroll_rect.getHeight());
+
+	// Restrict width within scroll container's width
+	if (mUseEllipses && mScrollContainer)
+	{
+		width = scroll_rect.getWidth();
+	}
+
+	LLView::reshape(width, height, called_from_parent);
+	mReshapeSignal(mSelectedItems, FALSE);
+}
+
+void LLFolderView::addToSelectionList(LLFolderViewItem* item)
+{
+	if (item->isSelected())
+	{
+		removeFromSelectionList(item);
+	}
+	if (mSelectedItems.size())
+	{
+		mSelectedItems.back()->setIsCurSelection(FALSE);
+	}
+	item->setIsCurSelection(TRUE);
+	mSelectedItems.push_back(item);
+}
+
+void LLFolderView::removeFromSelectionList(LLFolderViewItem* item)
+{
+	if (mSelectedItems.size())
+	{
+		mSelectedItems.back()->setIsCurSelection(FALSE);
+	}
+
+	selected_items_t::iterator item_iter;
+	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end();)
+	{
+		if (*item_iter == item)
+		{
+			item_iter = mSelectedItems.erase(item_iter);
+		}
+		else
+		{
+			++item_iter;
+		}
+	}
+	if (mSelectedItems.size())
+	{
+		mSelectedItems.back()->setIsCurSelection(TRUE);
+	}
+}
+
+LLFolderViewItem* LLFolderView::getCurSelectedItem( void )
+{
+	if(mSelectedItems.size())
+	{
+		LLFolderViewItem* itemp = mSelectedItems.back();
+		llassert(itemp->getIsCurSelection());
+		return itemp;
+	}
+	return NULL;
+}
+
+
+// Record the selected item and pass it down the hierachy.
+BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
+								BOOL take_keyboard_focus)
+{
+	mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS;
+
+	if( selection == this )
+	{
+		return FALSE;
+	}
+
+	if( selection && take_keyboard_focus)
+	{
+		mParentPanel->setFocus(TRUE);
+	}
+
+	// clear selection down here because change of keyboard focus can potentially
+	// affect selection
+	clearSelection();
+
+	if(selection)
+	{
+		addToSelectionList(selection);
+	}
+
+	BOOL rv = LLFolderViewFolder::setSelection(selection, openitem, take_keyboard_focus);
+	if(openitem && selection)
+	{
+		selection->getParentFolder()->requestArrange();
+	}
+
+	llassert(mSelectedItems.size() <= 1);
+
+	return rv;
+}
+
+BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+	BOOL rv = FALSE;
+
+	// can't select root folder
+	if(!selection || selection == this)
+	{
+		return FALSE;
+	}
+
+	if (!mAllowMultiSelect)
+	{
+		clearSelection();
+	}
+
+	selected_items_t::iterator item_iter;
+	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
+	{
+		if (*item_iter == selection)
+		{
+			break;
+		}
+	}
+
+	BOOL on_list = (item_iter != mSelectedItems.end());
+
+	if(selected && !on_list)
+	{
+		addToSelectionList(selection);
+	}
+	if(!selected && on_list)
+	{
+		removeFromSelectionList(selection);
+	}
+
+	rv = LLFolderViewFolder::changeSelection(selection, selected);
+
+	mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS;
+	
+	return rv;
+}
+
+static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection");
+void LLFolderView::sanitizeSelection()
+{
+	LLFastTimer _(FTM_SANITIZE_SELECTION);
+	// store off current item in case it is automatically deselected
+	// and we want to preserve context
+	LLFolderViewItem* original_selected_item = getCurSelectedItem();
+
+	std::vector<LLFolderViewItem*> items_to_remove;
+	selected_items_t::iterator item_iter;
+	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
+	{
+		LLFolderViewItem* item = *item_iter;
+
+		// ensure that each ancestor is open and potentially passes filtering
+		BOOL visible = item->getViewModelItem()->potentiallyVisible(); // initialize from filter state for this item
+		// modify with parent open and filters states
+		LLFolderViewFolder* parent_folder = item->getParentFolder();
+		// Move up through parent folders and see what's visible
+		while(parent_folder)
+		{
+			visible = visible && parent_folder->isOpen() && parent_folder->getViewModelItem()->potentiallyVisible();
+			parent_folder = parent_folder->getParentFolder();
+		}
+
+		//  deselect item if any ancestor is closed or didn't pass filter requirements.
+		if (!visible)
+		{
+			items_to_remove.push_back(item);
+		}
+
+		// disallow nested selections (i.e. folder items plus one or more ancestors)
+		// could check cached mum selections count and only iterate if there are any
+		// but that may be a premature optimization.
+		selected_items_t::iterator other_item_iter;
+		for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter)
+		{
+			LLFolderViewItem* other_item = *other_item_iter;
+			for( parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder())
+			{
+				if (parent_folder == item)
+				{
+					// this is a descendent of the current folder, remove from list
+					items_to_remove.push_back(other_item);
+					break;
+				}
+			}
+		}
+
+		// Don't allow invisible items (such as root folders) to be selected.
+		if (item == getRoot())
+		{
+			items_to_remove.push_back(item);
+		}
+	}
+
+	std::vector<LLFolderViewItem*>::iterator item_it;
+	for (item_it = items_to_remove.begin(); item_it != items_to_remove.end(); ++item_it )
+	{
+		changeSelection(*item_it, FALSE); // toggle selection (also removes from list)
+	}
+
+	// if nothing selected after prior constraints...
+	if (mSelectedItems.empty())
+	{
+		// ...select first available parent of original selection
+		LLFolderViewItem* new_selection = NULL;
+		if (original_selected_item)
+		{
+			for(LLFolderViewFolder* parent_folder = original_selected_item->getParentFolder();
+				parent_folder;
+				parent_folder = parent_folder->getParentFolder())
+			{
+				if (parent_folder->getViewModelItem()->potentiallyVisible())
+				{
+					// give initial selection to first ancestor folder that potentially passes the filter
+					if (!new_selection)
+					{
+						new_selection = parent_folder;
+					}
+
+					// if any ancestor folder of original item is closed, move the selection up 
+					// to the highest closed
+					if (!parent_folder->isOpen())
+					{	
+						new_selection = parent_folder;
+					}
+				}
+			}
+		}
+		else
+		{
+			new_selection = NULL;
+		}
+
+		if (new_selection)
+		{
+			setSelection(new_selection, FALSE, FALSE);
+		}
+	}
+}
+
+void LLFolderView::clearSelection()
+{
+	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); 
+		 item_it != mSelectedItems.end(); 
+		 ++item_it)
+	{
+		(*item_it)->setUnselected();
+	}
+
+	mSelectedItems.clear();
+}
+
+std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const
+{
+	std::set<LLFolderViewItem*> selection;
+	std::copy(mSelectedItems.begin(), mSelectedItems.end(), std::inserter(selection, selection.begin()));
+	return selection;
+}
+
+bool LLFolderView::startDrag()
+{
+	std::vector<LLFolderViewModelItem*> selected_items;
+	selected_items_t::iterator item_it;
+
+	if (!mSelectedItems.empty())
+	{
+		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+		{
+			selected_items.push_back((*item_it)->getViewModelItem());
+		}
+
+		return getFolderViewModel()->startDrag(selected_items);
+	}
+	return false;
+}
+
+void LLFolderView::commitRename( const LLSD& data )
+{
+	finishRenamingItem();
+}
+
+void LLFolderView::draw()
+{
+	//LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+
+	// if cursor has moved off of me during drag and drop
+	// close all auto opened folders
+	if (!mDragAndDropThisFrame)
+	{
+		closeAutoOpenedFolders();
+	}
+
+	if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size())
+	{
+		mSearchString.clear();
+	}
+
+	if (hasVisibleChildren())
+	{
+		mStatusTextBox->setVisible( FALSE );
+	}
+	else if (mShowEmptyMessage)
+	{
+		mStatusTextBox->setValue(getFolderViewModel()->getStatusText());
+		mStatusTextBox->setVisible( TRUE );
+		
+		// firstly reshape message textbox with current size. This is necessary to
+		// LLTextBox::getTextPixelHeight works properly
+		const LLRect local_rect = getLocalRect();
+		mStatusTextBox->setShape(local_rect);
+
+		// get preferable text height...
+		S32 pixel_height = mStatusTextBox->getTextPixelHeight();
+		bool height_changed = local_rect.getHeight() != pixel_height;
+		if (height_changed)
+		{
+			// ... if it does not match current height, lets rearrange current view.
+			// This will indirectly call ::arrange and reshape of the status textbox.
+			// We should call this method to also notify parent about required rect.
+			// See EXT-7564, EXT-7047.
+			S32 height = 0;
+			S32 width = 0;
+			S32 total_height = arrange( &width, &height );
+			notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
+
+			LLUI::popMatrix();
+			LLUI::pushMatrix();
+			LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
+		}
+	}
+
+	// skip over LLFolderViewFolder::draw since we don't want the folder icon, label, 
+	// and arrow for the root folder
+	LLView::draw();
+
+	mDragAndDropThisFrame = FALSE;
+}
+
+void LLFolderView::finishRenamingItem( void )
+{
+	if(!mRenamer)
+	{
+		return;
+	}
+	if( mRenameItem )
+	{
+		mRenameItem->rename( mRenamer->getText() );
+	}
+
+	closeRenamer();
+
+	// List is re-sorted alphabetically, so scroll to make sure the selected item is visible.
+	scrollToShowSelection();
+}
+
+void LLFolderView::closeRenamer( void )
+{
+	if (mRenamer && mRenamer->getVisible())
+	{
+		// Triggers onRenamerLost() that actually closes the renamer.
+		LLUI::removePopup(mRenamer);
+	}
+}
+
+bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
+{
+	LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
+
+	if (item_parent)
+	{
+		for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
+		{
+			const LLFolderViewItem* const selected_item = (*it);
+
+			LLFolderViewItem* parent = item_parent;
+
+			while (parent)
+			{
+				if (selected_item == parent)
+				{
+					return true;
+				}
+
+				parent = dynamic_cast<LLFolderViewItem*>(parent->getParent());
+			}
+		}
+	}
+
+	return false;
+}
+
+void LLFolderView::removeSelectedItems()
+{
+	if(getVisible() && getEnabled())
+	{
+		// just in case we're removing the renaming item.
+		mRenameItem = NULL;
+
+		// create a temporary structure which we will use to remove
+		// items, since the removal will futz with internal data
+		// structures.
+		std::vector<LLFolderViewItem*> items;
+		S32 count = mSelectedItems.size();
+		if(count == 0) return;
+		LLFolderViewItem* item = NULL;
+		selected_items_t::iterator item_it;
+		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+		{
+			item = *item_it;
+			if (item && item->isRemovable())
+			{
+				items.push_back(item);
+			}
+			else
+			{
+				llinfos << "Cannot delete " << item->getName() << llendl;
+				return;
+			}
+		}
+
+		// iterate through the new container.
+		count = items.size();
+		LLUUID new_selection_id;
+		if(count == 1)
+		{
+			LLFolderViewItem* item_to_delete = items[0];
+			LLFolderViewFolder* parent = item_to_delete->getParentFolder();
+			LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE);
+			if (!new_selection)
+			{
+				new_selection = item_to_delete->getPreviousOpenNode(FALSE);
+			}
+			if(parent)
+			{
+				if (item_to_delete->remove())
+				{
+					// change selection on successful delete
+					if (new_selection)
+					{
+						getRoot()->setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
+					}
+					else
+					{
+						getRoot()->setSelection(NULL, mParentPanel->hasFocus());
+					}
+				}
+			}
+			arrangeAll();
+		}
+		else if (count > 1)
+		{
+			LLDynamicArray<LLFolderViewModelItem*> listeners;
+			LLFolderViewModelItem* listener;
+			LLFolderViewItem* last_item = items[count - 1];
+			LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
+			while(new_selection && new_selection->isSelected())
+			{
+				new_selection = new_selection->getNextOpenNode(FALSE);
+			}
+			if (!new_selection)
+			{
+				new_selection = last_item->getPreviousOpenNode(FALSE);
+				while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items)))
+				{
+					new_selection = new_selection->getPreviousOpenNode(FALSE);
+				}
+			}
+			if (new_selection)
+			{
+				getRoot()->setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
+			}
+			else
+			{
+				getRoot()->setSelection(NULL, mParentPanel->hasFocus());
+			}
+
+			for(S32 i = 0; i < count; ++i)
+			{
+				listener = items[i]->getViewModelItem();
+				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItem*>::FAIL))
+				{
+					listeners.put(listener);
+				}
+			}
+			listener = static_cast<LLFolderViewModelItem*>(listeners.get(0));
+			if(listener)
+			{
+				listener->removeBatch(listeners);
+			}
+		}
+		arrangeAll();
+		scrollToShowSelection();
+	}
+}
+
+// TODO RN: abstract 
+// open the selected item.
+void LLFolderView::openSelectedItems( void )
+{
+	//TODO RN: get working again
+	//if(getVisible() && getEnabled())
+	//{
+	//	if (mSelectedItems.size() == 1)
+	//	{
+	//		mSelectedItems.front()->openItem();
+	//	}
+	//	else
+	//	{
+	//		LLMultiPreview* multi_previewp = new LLMultiPreview();
+	//		LLMultiProperties* multi_propertiesp = new LLMultiProperties();
+
+	//		selected_items_t::iterator item_it;
+	//		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+	//		{
+	//			// IT_{OBJECT,ATTACHMENT} creates LLProperties
+	//			// floaters; others create LLPreviews.  Put
+	//			// each one in the right type of container.
+	//			LLFolderViewModelItemInventory* listener = static_cast<LLFolderViewModelItemInventory*>((*item_it)->getViewModelItem());
+	//			bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
+	//			if (is_prop)
+	//				LLFloater::setFloaterHost(multi_propertiesp);
+	//			else
+	//				LLFloater::setFloaterHost(multi_previewp);
+	//			listener->openItem();
+	//		}
+
+	//		LLFloater::setFloaterHost(NULL);
+	//		// *NOTE: LLMulti* will safely auto-delete when open'd
+	//		// without any children.
+	//		multi_previewp->openFloater(LLSD());
+	//		multi_propertiesp->openFloater(LLSD());
+	//	}
+	//}
+}
+
+void LLFolderView::propertiesSelectedItems( void )
+{
+	//TODO RN: get working again
+	//if(getVisible() && getEnabled())
+	//{
+	//	if (mSelectedItems.size() == 1)
+	//	{
+	//		LLFolderViewItem* folder_item = mSelectedItems.front();
+	//		if(!folder_item) return;
+	//		folder_item->getViewModelItem()->showProperties();
+	//	}
+	//	else
+	//	{
+	//		LLMultiProperties* multi_propertiesp = new LLMultiProperties();
+
+	//		LLFloater::setFloaterHost(multi_propertiesp);
+
+	//		selected_items_t::iterator item_it;
+	//		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+	//		{
+	//			(*item_it)->getViewModelItem()->showProperties();
+	//		}
+
+	//		LLFloater::setFloaterHost(NULL);
+	//		multi_propertiesp->openFloater(LLSD());
+	//	}
+	//}
+}
+
+
+void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
+{
+	if ((mAutoOpenItems.check() == item) || 
+		(mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) ||
+		item->isOpen())
+	{
+		return;
+	}
+
+	// close auto-opened folders
+	LLFolderViewFolder* close_item = mAutoOpenItems.check();
+	while (close_item && close_item != item->getParentFolder())
+	{
+		mAutoOpenItems.pop();
+		close_item->setOpenArrangeRecursively(FALSE);
+		close_item = mAutoOpenItems.check();
+	}
+
+	item->requestArrange();
+
+	mAutoOpenItems.push(item);
+	
+	item->setOpen(TRUE);
+	LLRect content_rect = mScrollContainer->getContentWindowRect();
+	LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
+	scrollToShowItem(item, constraint_rect);
+}
+
+void LLFolderView::closeAutoOpenedFolders()
+{
+	while (mAutoOpenItems.check())
+	{
+		LLFolderViewFolder* close_item = mAutoOpenItems.pop();
+		close_item->setOpen(FALSE);
+	}
+
+	if (mAutoOpenCandidate)
+	{
+		mAutoOpenCandidate->setAutoOpenCountdown(0.f);
+	}
+	mAutoOpenCandidate = NULL;
+	mAutoOpenTimer.stop();
+}
+
+BOOL LLFolderView::autoOpenTest(LLFolderViewFolder* folder)
+{
+	if (folder && mAutoOpenCandidate == folder)
+	{
+		if (mAutoOpenTimer.getStarted())
+		{
+			if (!mAutoOpenCandidate->isOpen())
+			{
+				mAutoOpenCandidate->setAutoOpenCountdown(clamp_rescale(mAutoOpenTimer.getElapsedTimeF32(), 0.f, sAutoOpenTime, 0.f, 1.f));
+			}
+			if (mAutoOpenTimer.getElapsedTimeF32() > sAutoOpenTime)
+			{
+				autoOpenItem(folder);
+				mAutoOpenTimer.stop();
+				return TRUE;
+			}
+		}
+		return FALSE;
+	}
+
+	// otherwise new candidate, restart timer
+	if (mAutoOpenCandidate)
+	{
+		mAutoOpenCandidate->setAutoOpenCountdown(0.f);
+	}
+	mAutoOpenCandidate = folder;
+	mAutoOpenTimer.start();
+	return FALSE;
+}
+
+BOOL LLFolderView::canCopy() const
+{
+	if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
+	{
+		return FALSE;
+	}
+	
+	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
+	{
+		const LLFolderViewItem* item = *selected_it;
+		if (!item->getViewModelItem()->isItemCopyable())
+		{
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+// copy selected item
+void LLFolderView::copy()
+{
+	// *NOTE: total hack to clear the inventory clipboard
+	LLClipboard::instance().reset();
+	S32 count = mSelectedItems.size();
+	if(getVisible() && getEnabled() && (count > 0))
+	{
+		LLFolderViewModelItem* listener = NULL;
+		selected_items_t::iterator item_it;
+		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+		{
+			listener = (*item_it)->getViewModelItem();
+			if(listener)
+			{
+				listener->copyToClipboard();
+			}
+		}
+	}
+	mSearchString.clear();
+}
+
+BOOL LLFolderView::canCut() const
+{
+	if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
+	{
+		return FALSE;
+	}
+	
+	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
+	{
+		const LLFolderViewItem* item = *selected_it;
+		const LLFolderViewModelItem* listener = item->getViewModelItem();
+
+		if (!listener || !listener->isItemRemovable())
+		{
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+void LLFolderView::cut()
+{
+	// clear the inventory clipboard
+	LLClipboard::instance().reset();
+	S32 count = mSelectedItems.size();
+	if(getVisible() && getEnabled() && (count > 0))
+	{
+		LLFolderViewModelItem* listener = NULL;
+		selected_items_t::iterator item_it;
+		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+		{
+			listener = (*item_it)->getViewModelItem();
+			if(listener)
+			{
+				listener->cutToClipboard();
+				listener->removeItem();
+			}
+		}
+	}
+	mSearchString.clear();
+}
+
+BOOL LLFolderView::canPaste() const
+{
+	if (mSelectedItems.empty())
+	{
+		return FALSE;
+	}
+
+	if(getVisible() && getEnabled())
+	{
+		for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
+			 item_it != mSelectedItems.end(); ++item_it)
+		{
+			// *TODO: only check folders and parent folders of items
+			const LLFolderViewItem* item = (*item_it);
+			const LLFolderViewModelItem* listener = item->getViewModelItem();
+			if(!listener || !listener->isClipboardPasteable())
+			{
+				const LLFolderViewFolder* folderp = item->getParentFolder();
+				listener = folderp->getViewModelItem();
+				if (!listener || !listener->isClipboardPasteable())
+				{
+					return FALSE;
+				}
+			}
+		}
+		return TRUE;
+	}
+	return FALSE;
+}
+
+// paste selected item
+void LLFolderView::paste()
+{
+	if(getVisible() && getEnabled())
+	{
+		// find set of unique folders to paste into
+		std::set<LLFolderViewFolder*> folder_set;
+
+		selected_items_t::iterator selected_it;
+		for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
+		{
+			LLFolderViewItem* item = *selected_it;
+			LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(item);
+			if (folder == NULL)
+			{
+				item = item->getParentFolder();
+			}
+			folder_set.insert(folder);
+		}
+
+		std::set<LLFolderViewFolder*>::iterator set_iter;
+		for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)
+		{
+			LLFolderViewModelItem* listener = (*set_iter)->getViewModelItem();
+			if(listener && listener->isClipboardPasteable())
+			{
+				listener->pasteFromClipboard();
+			}
+		}
+	}
+	mSearchString.clear();
+}
+
+// public rename functionality - can only start the process
+void LLFolderView::startRenamingSelectedItem( void )
+{
+	// make sure selection is visible
+	scrollToShowSelection();
+
+	S32 count = mSelectedItems.size();
+	LLFolderViewItem* item = NULL;
+	if(count > 0)
+	{
+		item = mSelectedItems.front();
+	}
+	if(getVisible() && getEnabled() && (count == 1) && item && item->getViewModelItem() &&
+	   item->getViewModelItem()->isItemRenameable())
+	{
+		mRenameItem = item;
+
+		updateRenamerPosition();
+
+
+		mRenamer->setText(item->getName());
+		mRenamer->selectAll();
+		mRenamer->setVisible( TRUE );
+		// set focus will fail unless item is visible
+		mRenamer->setFocus( TRUE );
+		mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
+		LLUI::addPopup(mRenamer);
+	}
+}
+
+BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
+{
+	BOOL handled = FALSE;
+
+	// SL-51858: Key presses are not being passed to the Popup menu.
+	// A proper fix is non-trivial so instead just close the menu.
+	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+	if (menu && menu->isOpen())
+	{
+		LLMenuGL::sMenuContainer->hideMenus();
+	}
+
+	LLView *item = NULL;
+	if (getChildCount() > 0)
+	{
+		item = *(getChildList()->begin());
+	}
+
+	switch( key )
+	{
+	case KEY_F2:
+		mSearchString.clear();
+		startRenamingSelectedItem();
+		handled = TRUE;
+		break;
+
+	case KEY_RETURN:
+		if (mask == MASK_NONE)
+		{
+			if( mRenameItem && mRenamer->getVisible() )
+			{
+				finishRenamingItem();
+				mSearchString.clear();
+				handled = TRUE;
+			}
+			else
+			{
+				LLFolderView::openSelectedItems();
+				handled = TRUE;
+			}
+		}
+		break;
+
+	case KEY_ESCAPE:
+		if( mRenameItem && mRenamer->getVisible() )
+		{
+			closeRenamer();
+			handled = TRUE;
+		}
+		mSearchString.clear();
+		break;
+
+	case KEY_PAGE_UP:
+		mSearchString.clear();
+		mScrollContainer->pageUp(30);
+		handled = TRUE;
+		break;
+
+	case KEY_PAGE_DOWN:
+		mSearchString.clear();
+		mScrollContainer->pageDown(30);
+		handled = TRUE;
+		break;
+
+	case KEY_HOME:
+		mSearchString.clear();
+		mScrollContainer->goToTop();
+		handled = TRUE;
+		break;
+
+	case KEY_END:
+		mSearchString.clear();
+		mScrollContainer->goToBottom();
+		break;
+
+	case KEY_DOWN:
+		if((mSelectedItems.size() > 0) && mScrollContainer)
+		{
+			LLFolderViewItem* last_selected = getCurSelectedItem();
+
+			if (!mKeyboardSelection)
+			{
+				setSelection(last_selected, FALSE, TRUE);
+				mKeyboardSelection = TRUE;
+			}
+
+			LLFolderViewItem* next = NULL;
+			if (mask & MASK_SHIFT)
+			{
+				// don't shift select down to children of folders (they are implicitly selected through parent)
+				next = last_selected->getNextOpenNode(FALSE);
+				if (next)
+				{
+					if (next->isSelected())
+					{
+						// shrink selection
+						getRoot()->changeSelection(last_selected, FALSE);
+					}
+					else if (last_selected->getParentFolder() == next->getParentFolder())
+					{
+						// grow selection
+						getRoot()->changeSelection(next, TRUE);
+					}
+				}
+			}
+			else
+			{
+				next = last_selected->getNextOpenNode();
+				if( next )
+				{
+					if (next == last_selected)
+					{
+						//special case for LLAccordionCtrl
+						if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
+						{
+							clearSelection();
+							return TRUE;
+						}
+						return FALSE;
+					}
+					setSelection( next, FALSE, TRUE );
+				}
+				else
+				{
+					//special case for LLAccordionCtrl
+					if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
+					{
+						clearSelection();
+						return TRUE;
+					}
+					return FALSE;
+				}
+			}
+			scrollToShowSelection();
+			mSearchString.clear();
+			handled = TRUE;
+		}
+		break;
+
+	case KEY_UP:
+		if((mSelectedItems.size() > 0) && mScrollContainer)
+		{
+			LLFolderViewItem* last_selected = mSelectedItems.back();
+
+			if (!mKeyboardSelection)
+			{
+				setSelection(last_selected, FALSE, TRUE);
+				mKeyboardSelection = TRUE;
+			}
+
+			LLFolderViewItem* prev = NULL;
+			if (mask & MASK_SHIFT)
+			{
+				// don't shift select down to children of folders (they are implicitly selected through parent)
+				prev = last_selected->getPreviousOpenNode(FALSE);
+				if (prev)
+				{
+					if (prev->isSelected())
+					{
+						// shrink selection
+						getRoot()->changeSelection(last_selected, FALSE);
+					}
+					else if (last_selected->getParentFolder() == prev->getParentFolder())
+					{
+						// grow selection
+						getRoot()->changeSelection(prev, TRUE);
+					}
+				}
+			}
+			else
+			{
+				prev = last_selected->getPreviousOpenNode();
+				if( prev )
+				{
+					if (prev == this)
+					{
+						// If case we are in accordion tab notify parent to go to the previous accordion
+						if(notifyParent(LLSD().with("action","select_prev")) > 0 )//message was processed
+						{
+							clearSelection();
+							return TRUE;
+						}
+
+						return FALSE;
+					}
+					setSelection( prev, FALSE, TRUE );
+				}
+			}
+			scrollToShowSelection();
+			mSearchString.clear();
+
+			handled = TRUE;
+		}
+		break;
+
+	case KEY_RIGHT:
+		if(mSelectedItems.size())
+		{
+			LLFolderViewItem* last_selected = getCurSelectedItem();
+			last_selected->setOpen( TRUE );
+			mSearchString.clear();
+			handled = TRUE;
+		}
+		break;
+
+	case KEY_LEFT:
+		if(mSelectedItems.size())
+		{
+			LLFolderViewItem* last_selected = getCurSelectedItem();
+			LLFolderViewItem* parent_folder = last_selected->getParentFolder();
+			if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())
+			{
+				setSelection(parent_folder, FALSE, TRUE);
+			}
+			else
+			{
+				last_selected->setOpen( FALSE );
+			}
+			mSearchString.clear();
+			scrollToShowSelection();
+			handled = TRUE;
+		}
+		break;
+	}
+
+	if (!handled && mParentPanel->hasFocus())
+	{
+		if (key == KEY_BACKSPACE)
+		{
+			mSearchTimer.reset();
+			if (mSearchString.size())
+			{
+				mSearchString.erase(mSearchString.size() - 1, 1);
+			}
+			search(getCurSelectedItem(), mSearchString, FALSE);
+			handled = TRUE;
+		}
+	}
+
+	return handled;
+}
+
+
+BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
+{
+	if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
+	{
+		return FALSE;
+	}
+
+	if (uni_char > 0x7f)
+	{
+		llwarns << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << llendl;
+		return FALSE;
+	}
+
+	BOOL handled = FALSE;
+	if (mParentPanel->hasFocus())
+	{
+		// SL-51858: Key presses are not being passed to the Popup menu.
+		// A proper fix is non-trivial so instead just close the menu.
+		LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+		if (menu && menu->isOpen())
+		{
+			LLMenuGL::sMenuContainer->hideMenus();
+		}
+
+		//do text search
+		if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout"))
+		{
+			mSearchString.clear();
+		}
+		mSearchTimer.reset();
+		if (mSearchString.size() < 128)
+		{
+			mSearchString += uni_char;
+		}
+		search(getCurSelectedItem(), mSearchString, FALSE);
+
+		handled = TRUE;
+	}
+
+	return handled;
+}
+
+
+BOOL LLFolderView::canDoDelete() const
+{
+	if (mSelectedItems.size() == 0) return FALSE;
+
+	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+	{
+		if (!(*item_it)->getViewModelItem()->isItemRemovable())
+		{
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+void LLFolderView::doDelete()
+{
+	if(mSelectedItems.size() > 0)
+	{				
+		removeSelectedItems();
+	}
+}
+
+
+BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	mKeyboardSelection = FALSE;
+	mSearchString.clear();
+
+	mParentPanel->setFocus(TRUE);
+
+	LLEditMenuHandler::gEditMenuHandler = this;
+
+	return LLView::handleMouseDown( x, y, mask );
+}
+
+BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward)
+{
+	// get first selected item
+	LLFolderViewItem* search_item = first_item;
+
+	// make sure search string is upper case
+	std::string upper_case_string = search_string;
+	LLStringUtil::toUpper(upper_case_string);
+
+	// if nothing selected, select first item in folder
+	if (!search_item)
+	{
+		// start from first item
+		search_item = getNextFromChild(NULL);
+	}
+
+	// search over all open nodes for first substring match (with wrapping)
+	BOOL found = FALSE;
+	LLFolderViewItem* original_search_item = search_item;
+	do
+	{
+		// wrap at end
+		if (!search_item)
+		{
+			if (backward)
+			{
+				search_item = getPreviousFromChild(NULL);
+			}
+			else
+			{
+				search_item = getNextFromChild(NULL);
+			}
+			if (!search_item || search_item == original_search_item)
+			{
+				break;
+			}
+		}
+
+		const std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
+		S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
+		if (!current_item_label.compare(0, search_string_length, upper_case_string))
+		{
+			found = TRUE;
+			break;
+		}
+		if (backward)
+		{
+			search_item = search_item->getPreviousOpenNode();
+		}
+		else
+		{
+			search_item = search_item->getNextOpenNode();
+		}
+
+	} while(search_item != original_search_item);
+	
+
+	if (found)
+	{
+		setSelection(search_item, FALSE, TRUE);
+		scrollToShowSelection();
+	}
+
+	return found;
+}
+
+BOOL LLFolderView::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+	// skip LLFolderViewFolder::handleDoubleClick()
+	return LLView::handleDoubleClick( x, y, mask );
+}
+
+BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+	// all user operations move keyboard focus to inventory
+	// this way, we know when to stop auto-updating a search
+	mParentPanel->setFocus(TRUE);
+
+	BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
+	S32 count = mSelectedItems.size();
+	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+	if (   handled
+		&& ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible
+		&& menu )
+	{
+		if (mCallbackRegistrar)
+			mCallbackRegistrar->pushScope();
+
+		updateMenuOptions(menu);
+	   
+		menu->updateParent(LLMenuGL::sMenuContainer);
+		LLMenuGL::showPopup(this, menu, x, y);
+		if (mCallbackRegistrar)
+			mCallbackRegistrar->popScope();
+	}
+	else
+	{
+		if (menu && menu->getVisible())
+		{
+			menu->setVisible(FALSE);
+		}
+		setSelection(NULL, FALSE, TRUE);
+	}
+	return handled;
+}
+
+// Add "--no options--" if the menu is completely blank.
+BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const
+{
+	const std::string nooptions_str = "--no options--";
+	LLView *nooptions_item = NULL;
+	
+	const LLView::child_list_t *list = menu->getChildList();
+	for (LLView::child_list_t::const_iterator itor = list->begin(); 
+		 itor != list->end(); 
+		 ++itor)
+	{
+		LLView *menu_item = (*itor);
+		if (menu_item->getVisible())
+		{
+			return FALSE;
+		}
+		std::string name = menu_item->getName();
+		if (menu_item->getName() == nooptions_str)
+		{
+			nooptions_item = menu_item;
+		}
+	}
+	if (nooptions_item)
+	{
+		nooptions_item->setVisible(TRUE);
+		nooptions_item->setEnabled(FALSE);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )
+{
+	return LLView::handleHover( x, y, mask );
+}
+
+BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+									 EDragAndDropType cargo_type,
+									 void* cargo_data, 
+									 EAcceptance* accept,
+									 std::string& tooltip_msg)
+{
+	mDragAndDropThisFrame = TRUE;
+	// have children handle it first
+	BOOL handled = LLView::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data,
+											 accept, tooltip_msg);
+
+	// when drop is not handled by child, it should be handled
+	// by the folder which is the hierarchy root.
+	if (!handled)
+	{
+		handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+	}
+
+	return handled;
+}
+
+void LLFolderView::deleteAllChildren()
+{
+	closeRenamer();
+	if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
+	mPopupMenuHandle = LLHandle<LLView>();
+	mScrollContainer = NULL;
+	mRenameItem = NULL;
+	mRenamer = NULL;
+	mStatusTextBox = NULL;
+	
+	clearSelection();
+	LLView::deleteAllChildren();
+}
+
+void LLFolderView::scrollToShowSelection()
+{
+	if ( mSelectedItems.size() )
+	{
+		mNeedsScroll = TRUE;
+	}
+}
+
+// If the parent is scroll container, scroll it to make the selection
+// is maximally visible.
+void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
+{
+	if (!mScrollContainer) return;
+
+	// don't scroll to items when mouse is being used to scroll/drag and drop
+	if (gFocusMgr.childHasMouseCapture(mScrollContainer))
+	{
+		mNeedsScroll = FALSE;
+		return;
+	}
+
+	// if item exists and is in visible portion of parent folder...
+	if(item)
+	{
+		LLRect local_rect = item->getLocalRect();
+		LLRect item_scrolled_rect; // item position relative to display area of scroller
+		LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect();
+		
+		S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); 
+		S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight(); 
+		// when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
+		S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight(); 
+		
+		// get portion of item that we want to see...
+		LLRect item_local_rect = LLRect(item->getIndentation(), 
+										local_rect.getHeight(), 
+										llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()), 
+										llmax(0, local_rect.getHeight() - max_height_to_show));
+
+		LLRect item_doc_rect;
+
+		item->localRectToOtherView(item_local_rect, &item_doc_rect, this); 
+
+		mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect );
+
+	}
+}
+
+LLRect LLFolderView::getVisibleRect()
+{
+	S32 visible_height = mScrollContainer->getRect().getHeight();
+	S32 visible_width = mScrollContainer->getRect().getWidth();
+	LLRect visible_rect;
+	visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height);
+	return visible_rect;
+}
+
+BOOL LLFolderView::getShowSelectionContext()
+{
+	if (mShowSelectionContext)
+	{
+		return TRUE;
+	}
+	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+	if (menu && menu->getVisible())
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
+void LLFolderView::setShowSingleSelection(BOOL show)
+{
+	if (show != mShowSingleSelection)
+	{
+		mMultiSelectionFadeTimer.reset();
+		mShowSingleSelection = show;
+	}
+}
+
+static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
+static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
+
+// Main idle routine
+void LLFolderView::update()
+{
+	// If this is associated with the user's inventory, don't do anything
+	// until that inventory is loaded up.
+	LLFastTimer t2(FTM_INVENTORY);
+
+	if (getFolderViewModel()->getFilter()->isModified() && getFolderViewModel()->getFilter()->isNotDefault())
+	{
+		mNeedsAutoSelect = TRUE;
+	}
+	getFolderViewModel()->getFilter()->clearModified();
+
+	// filter to determine visibility before arranging
+	filter(*(getFolderViewModel()->getFilter()));
+
+	// automatically show matching items, and select first one if we had a selection
+	if (mNeedsAutoSelect)
+	{
+		LLFastTimer t3(FTM_AUTO_SELECT);
+		// select new item only if a filtered item not currently selected
+		LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
+		if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->getViewModelItem()->potentiallyVisible()))
+		{
+			// these are named variables to get around gcc not binding non-const references to rvalues
+			// and functor application is inherently non-const to allow for stateful functors
+			LLSelectFirstFilteredItem functor;
+			applyFunctorRecursively(functor);
+		}
+
+		// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
+		// Used by LLPlacesFolderView.
+		if (getFolderViewModel()->getFilter()->showAllResults())
+		{
+			// these are named variables to get around gcc not binding non-const references to rvalues
+			// and functor application is inherently non-const to allow for stateful functors
+			LLOpenFilteredFolders functor;
+			applyFunctorRecursively(functor);
+		}
+
+		scrollToShowSelection();
+	}
+
+	BOOL filter_finished = getViewModelItem()->passedFilter()
+						&& mViewModel->contentsReady();
+	if (filter_finished 
+		|| gFocusMgr.childHasKeyboardFocus(getParent()) // assume we are inside a scroll container
+		|| gFocusMgr.childHasMouseCapture(getParent()))
+	{
+		// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
+		mNeedsAutoSelect = FALSE;
+	}
+
+
+	// during filtering process, try to pin selected item's location on screen
+	// this will happen when searching your inventory and when new items arrive
+	if (!filter_finished)
+	{
+		// calculate rectangle to pin item to at start of animated rearrange
+		if (!mPinningSelectedItem && !mSelectedItems.empty())
+		{
+			// lets pin it!
+			mPinningSelectedItem = TRUE;
+
+			LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
+			LLFolderViewItem* selected_item = mSelectedItems.back();
+
+			LLRect item_rect;
+			selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
+			// if item is visible in scrolled region
+			if (visible_content_rect.overlaps(item_rect))
+			{
+				// then attempt to keep it in same place on screen
+				mScrollConstraintRect = item_rect;
+				mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
+			}
+			else
+			{
+				// otherwise we just want it onscreen somewhere
+				LLRect content_rect = mScrollContainer->getContentWindowRect();
+				mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
+			}
+		}
+	}
+	else
+	{
+		// stop pinning selected item after folders stop rearranging
+		if (!needsArrange())
+		{
+			mPinningSelectedItem = FALSE;
+		}
+	}
+
+	LLRect constraint_rect;
+	if (mPinningSelectedItem)
+	{
+		// use last known constraint rect for pinned item
+		constraint_rect = mScrollConstraintRect;
+	}
+	else
+	{
+		// during normal use (page up/page down, etc), just try to fit item on screen
+		LLRect content_rect = mScrollContainer->getContentWindowRect();
+		constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
+	}
+
+	BOOL is_visible = isInVisibleChain();
+
+	if ( is_visible )
+	{
+		sanitizeSelection();
+		if( needsArrange() )
+		{
+			S32 height = 0;
+			S32 width = 0;
+			S32 total_height = arrange( &width, &height );
+			notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
+		}
+	}
+
+	if (mSelectedItems.size() && mNeedsScroll)
+	{
+		scrollToShowItem(mSelectedItems.back(), constraint_rect);
+		// continue scrolling until animated layout change is done
+		if (filter_finished
+			&& (!needsArrange() || !is_visible))
+		{
+			mNeedsScroll = FALSE;
+		}
+	}
+
+	if (mSignalSelectCallback)
+	{
+		//RN: we use keyboard focus as a proxy for user-explicit actions
+		BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS);
+		mSelectSignal(mSelectedItems, take_keyboard_focus);
+	}
+	mSignalSelectCallback = FALSE;
+}
+
+void LLFolderView::dumpSelectionInformation()
+{
+	llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
+	llinfos << "****************************************" << llendl;
+	selected_items_t::iterator item_it;
+	for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+	{
+		llinfos << "  " << (*item_it)->getName() << llendl;
+	}
+	llinfos << "****************************************" << llendl;
+}
+
+void LLFolderView::updateRenamerPosition()
+{
+	if(mRenameItem)
+	{
+		// See also LLFolderViewItem::draw()
+		S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mRenameItem->getIndentation();
+		S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
+		mRenameItem->localPointToScreen( x, y, &x, &y );
+		screenPointToLocal( x, y, &x, &y );
+		mRenamer->setOrigin( x, y );
+
+		LLRect scroller_rect(0, 0, LLUI::getWindowSize().mV[VX], 0);
+		if (mScrollContainer)
+		{
+			scroller_rect = mScrollContainer->getContentWindowRect();
+		}
+
+		S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
+		S32 height = mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
+		mRenamer->reshape( width, height, TRUE );
+	}
+}
+
+// Update visibility and availability (i.e. enabled/disabled) of context menu items.
+void LLFolderView::updateMenuOptions(LLMenuGL* menu)
+{
+	const LLView::child_list_t *list = menu->getChildList();
+
+	LLView::child_list_t::const_iterator menu_itor;
+	for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor)
+	{
+		(*menu_itor)->setVisible(FALSE);
+		(*menu_itor)->pushVisible(TRUE);
+		(*menu_itor)->setEnabled(TRUE);
+	}
+
+	// Successively filter out invalid options
+
+	U32 flags = FIRST_SELECTED_ITEM;
+	for (selected_items_t::iterator item_itor = mSelectedItems.begin();
+			item_itor != mSelectedItems.end();
+			++item_itor)
+	{
+		LLFolderViewItem* selected_item = (*item_itor);
+		selected_item->buildContextMenu(*menu, flags);
+		flags = 0x0;
+	}
+
+	addNoOptions(menu);
+}
+
+// Refresh the context menu (that is already shown).
+void LLFolderView::updateMenu()
+{
+	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
+	if (menu && menu->getVisible())
+	{
+		updateMenuOptions(menu);
+		menu->needsArrange(); // update menu height if needed
+	}
+}
+
+bool LLFolderView::selectFirstItem()
+{
+	for (folders_t::iterator iter = mFolders.begin();
+		 iter != mFolders.end();++iter)
+	{
+		LLFolderViewFolder* folder = (*iter );
+		if (folder->getVisible())
+		{
+			LLFolderViewItem* itemp = folder->getNextFromChild(0,true);
+			if(itemp)
+				setSelection(itemp,FALSE,TRUE);
+			return true;	
+		}
+		
+	}
+	for(items_t::iterator iit = mItems.begin();
+		iit != mItems.end(); ++iit)
+	{
+		LLFolderViewItem* itemp = (*iit);
+		if (itemp->getVisible())
+		{
+			setSelection(itemp,FALSE,TRUE);
+			return true;	
+		}
+	}
+	return false;
+}
+bool LLFolderView::selectLastItem()
+{
+	for(items_t::reverse_iterator iit = mItems.rbegin();
+		iit != mItems.rend(); ++iit)
+	{
+		LLFolderViewItem* itemp = (*iit);
+		if (itemp->getVisible())
+		{
+			setSelection(itemp,FALSE,TRUE);
+			return true;	
+		}
+	}
+	for (folders_t::reverse_iterator iter = mFolders.rbegin();
+		 iter != mFolders.rend();++iter)
+	{
+		LLFolderViewFolder* folder = (*iter);
+		if (folder->getVisible())
+		{
+			LLFolderViewItem* itemp = folder->getPreviousFromChild(0,true);
+			if(itemp)
+				setSelection(itemp,FALSE,TRUE);
+			return true;	
+		}
+	}
+	return false;
+}
+
+
+S32	LLFolderView::notify(const LLSD& info) 
+{
+	if(info.has("action"))
+	{
+		std::string str_action = info["action"];
+		if(str_action == "select_first")
+		{
+			setFocus(true);
+			selectFirstItem();
+			scrollToShowSelection();
+			return 1;
+
+		}
+		else if(str_action == "select_last")
+		{
+			setFocus(true);
+			selectLastItem();
+			scrollToShowSelection();
+			return 1;
+		}
+	}
+	return 0;
+}
+
+
+///----------------------------------------------------------------------------
+/// Local function definitions
+///----------------------------------------------------------------------------
+
+void LLFolderView::onRenamerLost()
+{
+	if (mRenamer && mRenamer->getVisible())
+	{
+		mRenamer->setVisible(FALSE);
+
+		// will commit current name (which could be same as original name)
+		mRenamer->setFocus(FALSE);
+	}
+
+	if( mRenameItem )
+	{
+		setSelection( mRenameItem, TRUE );
+		mRenameItem = NULL;
+	}
+}
+
+S32 LLFolderView::getItemHeight()
+{
+	if(!hasVisibleChildren())
+	{
+		//We need to display status textbox, let's reserve some place for it
+		return llmax(0, mStatusTextBox->getTextPixelHeight());
+	}
+	return 0;
+}
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
new file mode 100644
index 0000000000..ba37a11bbe
--- /dev/null
+++ b/indra/llui/llfolderview.h
@@ -0,0 +1,388 @@
+/** 
+ * @file llfolderview.h
+ * @brief Definition of the folder view collection of classes.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+/**
+ *
+ * The folder view collection of classes provides an interface for
+ * making a 'folder view' similar to the way the a single pane file
+ * folder interface works.
+ *
+ */
+
+#ifndef LL_LLFOLDERVIEW_H
+#define LL_LLFOLDERVIEW_H
+
+#include "llfolderviewitem.h"	// because LLFolderView is-a LLFolderViewFolder
+
+#include "lluictrl.h"
+#include "v4color.h"
+#include "stdenums.h"
+#include "lldepthstack.h"
+#include "lleditmenuhandler.h"
+#include "llfontgl.h"
+#include "llscrollcontainer.h"
+
+class LLFolderViewModelInterface;
+class LLFolderViewFolder;
+class LLFolderViewItem;
+class LLFolderViewFilter;
+class LLPanel;
+class LLLineEditor;
+class LLMenuGL;
+class LLUICtrl;
+class LLTextBox;
+
+/**
+ * Class LLFolderViewScrollContainer
+ *
+ * A scroll container which provides the information about the height
+ * of currently displayed folder view contents.
+ * Used for updating vertical scroll bar visibility in inventory panel.
+ * See LLScrollContainer::calcVisibleSize().
+ */
+class LLFolderViewScrollContainer : public LLScrollContainer
+{
+public:
+	/*virtual*/ ~LLFolderViewScrollContainer() {};
+	/*virtual*/ const LLRect getScrolledViewRect() const;
+
+protected:
+	LLFolderViewScrollContainer(const LLScrollContainer::Params& p);
+	friend class LLUICtrlFactory;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderView
+//
+// The LLFolderView represents the root level folder view object. 
+// It manages the screen region of the folder view.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
+	{
+		Mandatory<LLPanel*>	    parent_panel;
+		Optional<std::string>   title;
+		Optional<bool>			use_label_suffix,
+								allow_multiselect,
+								show_empty_message,
+								use_ellipses,
+								show_item_link_overlays;
+		Mandatory<LLFolderViewModelInterface*>	view_model;
+
+		Params();
+	};
+
+	friend class LLFolderViewScrollContainer;
+
+	LLFolderView(const Params&);
+	virtual ~LLFolderView( void );
+
+	virtual BOOL canFocusChildren() const;
+
+	virtual const LLFolderView*	getRoot() const { return this; }
+	virtual LLFolderView*	getRoot() { return this; }
+
+	LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; }
+	const LLFolderViewModelInterface* getFolderViewModel() const { return mViewModel; }
+
+	typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
+	void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
+	void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
+	
+	bool getAllowMultiSelect() { return mAllowMultiSelect; }
+
+	// Close all folders in the view
+	void closeAllFolders();
+	void openTopLevelFolders();
+
+	virtual BOOL addFolder( LLFolderViewFolder* folder);
+
+	// Find width and height of this object and its children. Also
+	// makes sure that this view and its children are the right size.
+	virtual S32 arrange( S32* width, S32* height );
+	virtual S32 getItemHeight();
+
+	void arrangeAll() { mArrangeGeneration++; }
+	S32 getArrangeGeneration() { return mArrangeGeneration; }
+
+	// applies filters to control visibility of items
+	virtual void filter( LLFolderViewFilter& filter);
+
+	// Get the last selected item
+	virtual LLFolderViewItem* getCurSelectedItem( void );
+
+	// Record the selected item and pass it down the hierarchy.
+	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
+		BOOL take_keyboard_focus = TRUE);
+
+	// This method is used to toggle the selection of an item. Walks
+	// children, and keeps track of selected objects.
+	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
+
+	virtual std::set<LLFolderViewItem*> getSelectionList() const;
+	S32 getNumSelectedItems() { return mSelectedItems.size(); }
+
+	// Make sure if ancestor is selected, descendants are not
+	void sanitizeSelection();
+	virtual void clearSelection();
+	void addToSelectionList(LLFolderViewItem* item);
+	void removeFromSelectionList(LLFolderViewItem* item);
+
+	bool startDrag();
+	void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
+	void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
+	LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
+
+	// Deletion functionality
+ 	void removeSelectedItems();
+
+	// Open the selected item
+	void openSelectedItems( void );
+	void propertiesSelectedItems( void );
+
+	void autoOpenItem(LLFolderViewFolder* item);
+	void closeAutoOpenedFolders();
+	BOOL autoOpenTest(LLFolderViewFolder* item);
+	BOOL isOpen() const { return TRUE; } // root folder always open
+
+	// Copy & paste
+	virtual void	copy();
+	virtual BOOL	canCopy() const;
+
+	virtual void	cut();
+	virtual BOOL	canCut() const;
+
+	virtual void	paste();
+	virtual BOOL	canPaste() const;
+
+	virtual void	doDelete();
+	virtual BOOL	canDoDelete() const;
+
+	// Public rename functionality - can only start the process
+	void startRenamingSelectedItem( void );
+
+	// LLView functionality
+	///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
+	/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
+	/*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
+	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+								   EDragAndDropType cargo_type,
+								   void* cargo_data,
+								   EAcceptance* accept,
+								   std::string& tooltip_msg);
+	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) { setShowSelectionContext(FALSE); }
+	virtual void draw();
+	virtual void deleteAllChildren();
+
+	void scrollToShowSelection();
+	void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
+	void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
+	LLRect getVisibleRect();
+
+	BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward);
+	void setShowSelectionContext(BOOL show) { mShowSelectionContext = show; }
+	BOOL getShowSelectionContext();
+	void setShowSingleSelection(BOOL show);
+	BOOL getShowSingleSelection() { return mShowSingleSelection; }
+	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
+	bool getUseEllipses() { return mUseEllipses; }
+
+	void	update();						// needs to be called periodically (e.g. once per frame)
+
+	BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
+	BOOL needsAutoRename() { return mNeedsAutoRename; }
+	void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
+	void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
+	void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
+
+	bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
+
+	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
+
+	LLPanel* getParentPanel() { return mParentPanel; }
+	// DEBUG only
+	void dumpSelectionInformation();
+
+	virtual S32	notify(const LLSD& info) ;
+	
+	bool useLabelSuffix() { return mUseLabelSuffix; }
+	void updateMenu();
+
+private:
+	void updateMenuOptions(LLMenuGL* menu);
+	void updateRenamerPosition();
+
+protected:
+	LLScrollContainer* mScrollContainer;  // NULL if this is not a child of a scroll container.
+
+	void commitRename( const LLSD& data );
+	void onRenamerLost();
+
+	void finishRenamingItem( void );
+	void closeRenamer( void );
+
+	bool selectFirstItem();
+	bool selectLastItem();
+	
+	BOOL addNoOptions(LLMenuGL* menu) const;
+
+
+protected:
+	LLHandle<LLView>					mPopupMenuHandle;
+	
+	typedef std::deque<LLFolderViewItem*> selected_items_t;
+	selected_items_t				mSelectedItems;
+	BOOL							mKeyboardSelection;
+	BOOL							mAllowMultiSelect;
+	BOOL							mShowEmptyMessage;
+	BOOL							mShowFolderHierarchy;
+
+	// Renaming variables and methods
+	LLFolderViewItem*				mRenameItem;  // The item currently being renamed
+	LLLineEditor*					mRenamer;
+
+	BOOL							mNeedsScroll;
+	BOOL							mPinningSelectedItem;
+	LLRect							mScrollConstraintRect;
+	BOOL							mNeedsAutoSelect;
+	BOOL							mAutoSelectOverride;
+	BOOL							mNeedsAutoRename;
+	bool							mUseLabelSuffix;
+	bool							mShowItemLinkOverlays;
+	
+	LLDepthStack<LLFolderViewFolder>	mAutoOpenItems;
+	LLFolderViewFolder*				mAutoOpenCandidate;
+	LLFrameTimer					mAutoOpenTimer;
+	LLFrameTimer					mSearchTimer;
+	std::string						mSearchString;
+	BOOL							mShowSelectionContext;
+	BOOL							mShowSingleSelection;
+	LLFrameTimer					mMultiSelectionFadeTimer;
+	S32								mArrangeGeneration;
+
+	signal_t						mSelectSignal;
+	signal_t						mReshapeSignal;
+	S32								mSignalSelectCallback;
+	S32								mMinWidth;
+	BOOL							mDragAndDropThisFrame;
+	
+	LLPanel*						mParentPanel;
+	
+	LLFolderViewModelInterface*		mViewModel;
+
+	/**
+	 * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
+	 * NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel.
+	 */
+	bool							mUseEllipses; // See EXT-719
+
+	/**
+	 * Contains item under mouse pointer while dragging
+	 */
+	LLFolderViewItem*				mDraggingOverItem; // See EXT-719
+
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;
+	
+public:
+	static F32 sAutoOpenTime;
+	LLTextBox*						mStatusTextBox;
+
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewFunctor
+//
+// Simple abstract base class for applying a functor to folders and
+// items in a folder view hierarchy. This is suboptimal for algorithms
+// that only work folders or only work on items, but I'll worry about
+// that later when it's determined to be too slow.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLFolderViewFunctor
+{
+public:
+	virtual ~LLFolderViewFunctor() {}
+	virtual void doFolder(LLFolderViewFolder* folder) = 0;
+	virtual void doItem(LLFolderViewItem* item) = 0;
+};
+
+class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+{
+public:
+	LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
+	virtual ~LLSelectFirstFilteredItem() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+	BOOL wasItemSelected() { return mItemSelected; }
+protected:
+	BOOL mItemSelected;
+};
+
+class LLOpenFilteredFolders : public LLFolderViewFunctor
+{
+public:
+	LLOpenFilteredFolders()  {}
+	virtual ~LLOpenFilteredFolders() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+};
+
+class LLSaveFolderState : public LLFolderViewFunctor
+{
+public:
+	LLSaveFolderState() : mApply(FALSE) {}
+	virtual ~LLSaveFolderState() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item) {}
+	void setApply(BOOL apply);
+	void clearOpenFolders() { mOpenFolders.clear(); }
+protected:
+	std::set<LLUUID> mOpenFolders;
+	BOOL mApply;
+};
+
+class LLOpenFoldersWithSelection : public LLFolderViewFunctor
+{
+public:
+	LLOpenFoldersWithSelection() {}
+	virtual ~LLOpenFoldersWithSelection() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+};
+
+// Flags for buildContextMenu()
+const U32 SUPPRESS_OPEN_ITEM = 0x1;
+const U32 FIRST_SELECTED_ITEM = 0x2;
+
+#endif // LL_LLFOLDERVIEW_H
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
new file mode 100644
index 0000000000..741fc9c324
--- /dev/null
+++ b/indra/llui/llfolderviewitem.cpp
@@ -0,0 +1,2032 @@
+/** 
+* @file llfolderviewitem.cpp
+* @brief Items and folders that can appear in a hierarchical folder view
+*
+* $LicenseInfo:firstyear=2001&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#include "linden_common.h"
+#include "llfolderviewitem.h"
+
+#include "llfolderview.h"
+#include "llfolderviewmodel.h"
+#include "llpanel.h"
+#include "llcriticaldamp.h"
+#include "llclipboard.h"
+#include "llfocusmgr.h"		// gFocusMgr
+#include "lltrans.h"
+#include "llwindow.h"
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewItem
+///----------------------------------------------------------------------------
+
+static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
+
+// statics 
+std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
+
+// only integers can be initialized in header
+const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
+const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
+
+//static
+LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
+{
+	LLFontGL* rtn = sFonts[style];
+	if (!rtn) // grab label font with this style, lazily
+	{
+		LLFontDescriptor labelfontdesc("SansSerif", "Small", style);
+		rtn = LLFontGL::getFont(labelfontdesc);
+		if (!rtn)
+		{
+			rtn = LLFontGL::getFontDefault();
+		}
+		sFonts[style] = rtn;
+	}
+	return rtn;
+}
+
+//static
+void LLFolderViewItem::initClass()
+{
+}
+
+//static
+void LLFolderViewItem::cleanupClass()
+{
+	sFonts.clear();
+}
+
+
+// NOTE: Optimize this, we call it a *lot* when opening a large inventory
+LLFolderViewItem::Params::Params()
+:	root(),
+	listener(),
+	folder_arrow_image("folder_arrow_image"),
+	folder_indentation("folder_indentation"),
+	selection_image("selection_image"),
+	item_height("item_height"),
+	item_top_pad("item_top_pad"),
+	creation_date()
+{}
+
+// Default constructor
+LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
+:	LLView(p),
+	mLabelWidth(0),
+	mLabelWidthDirty(false),
+	mParentFolder( NULL ),
+	mIsSelected( FALSE ),
+	mIsCurSelection( FALSE ),
+	mSelectPending(FALSE),
+	mLabelStyle( LLFontGL::NORMAL ),
+	mHasVisibleChildren(FALSE),
+	mIndentation(0),
+	mItemHeight(p.item_height),
+	//TODO RN: create interface for string highlighting
+	//mStringMatchOffset(std::string::npos),
+	mControlLabelRotation(0.f),
+	mDragAndDropTarget(FALSE),
+	mLabel(p.name),
+	mRoot(p.root),
+	mViewModelItem(p.listener),
+	mIsMouseOverTitle(false)
+{
+	if (mViewModelItem)
+	{
+		mViewModelItem->setFolderViewItem(this);
+	}
+}
+
+BOOL LLFolderViewItem::postBuild()
+{
+	refresh();
+	return TRUE;
+}
+
+// Destroys the object
+LLFolderViewItem::~LLFolderViewItem( void )
+{
+	delete mViewModelItem;
+	mViewModelItem = NULL;
+}
+
+LLFolderView* LLFolderViewItem::getRoot()
+{
+	return mRoot;
+}
+
+const LLFolderView* LLFolderViewItem::getRoot() const
+{
+	return mRoot;
+}
+// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
+BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
+{
+	LLFolderViewItem* root = this;
+	while( root->mParentFolder )
+	{
+		if( root->mParentFolder == potential_ancestor )
+		{
+			return TRUE;
+		}
+		root = root->mParentFolder;
+	}
+	return FALSE;
+}
+
+LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
+{
+	if (!mParentFolder)
+	{
+		return NULL;
+	}
+
+	LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
+	while(itemp && !itemp->getVisible())
+	{
+		LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
+		if (itemp == next_itemp) 
+		{
+			// hit last item
+			return itemp->getVisible() ? itemp : this;
+		}
+		itemp = next_itemp;
+	}
+
+	return itemp;
+}
+
+LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
+{
+	if (!mParentFolder)
+	{
+		return NULL;
+	}
+
+	LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
+
+	// Skip over items that are invisible or are hidden from the UI.
+	while(itemp && !itemp->getVisible())
+	{
+		LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
+		if (itemp == next_itemp) 
+		{
+			// hit first item
+			return itemp->getVisible() ? itemp : this;
+		}
+		itemp = next_itemp;
+	}
+
+	return itemp;
+}
+
+BOOL LLFolderViewItem::passedFilter(S32 filter_generation) 
+{
+	return getViewModelItem()->passedFilter(filter_generation);
+}
+
+void LLFolderViewItem::refresh()
+{ 
+	LLFolderViewModelItem& vmi = *getViewModelItem();
+
+	mLabel = vmi.getDisplayName();
+
+	setToolTip(mLabel);
+	mIcon = vmi.getIcon();
+	mIconOpen = vmi.getIconOpen();
+	mIconOverlay = vmi.getIconOverlay();
+
+	if (mRoot->useLabelSuffix())
+	{
+		mLabelStyle = vmi.getLabelStyle();
+		mLabelSuffix = vmi.getLabelSuffix();
+	}
+
+	//TODO RN: make sure this logic still fires
+	//std::string searchable_label(mLabel);
+	//searchable_label.append(mLabelSuffix);
+	//LLStringUtil::toUpper(searchable_label);
+
+	//if (mSearchableLabel.compare(searchable_label))
+	//{
+	//	mSearchableLabel.assign(searchable_label);
+	//	vmi.dirtyFilter();
+	//	// some part of label has changed, so overall width has potentially changed, and sort order too
+	//	if (mParentFolder)
+	//	{
+	//		mParentFolder->requestSort();
+	//		mParentFolder->requestArrange();
+	//	}
+	//}
+
+	mLabelWidthDirty = true;
+	vmi.dirtyFilter();
+}
+
+// Utility function for LLFolderView
+void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
+									 BOOL take_keyboard_focus)
+{
+	LLFolderView* root = getRoot();
+	if (getParentFolder())
+	{
+		getParentFolder()->requestArrange();
+	}
+	if(set_selection)
+	{
+		getRoot()->setSelection(this, TRUE, take_keyboard_focus);
+		if(root)
+		{
+			root->scrollToShowSelection();
+		}
+	}		
+}
+
+
+std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const
+{
+	std::set<LLFolderViewItem*> selection;
+	return selection;
+}
+
+// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
+{
+	return folder->addItem(this);
+}
+
+
+// Finds width and height of this object and its children.  Also
+// makes sure that this view and its children are the right size.
+S32 LLFolderViewItem::arrange( S32* width, S32* height )
+{
+	const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+	S32 indentation = p.folder_indentation();
+	// Only indent deeper items in hierarchy
+	mIndentation = (getParentFolder())
+		? getParentFolder()->getIndentation() + indentation
+		: 0;
+	if (mLabelWidthDirty)
+	{
+		mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + TEXT_PAD_RIGHT; 
+		mLabelWidthDirty = false;
+	}
+
+	*width = llmax(*width, mLabelWidth + mIndentation); 
+
+	// determine if we need to use ellipses to avoid horizontal scroll. EXT-719
+	bool use_ellipses = getRoot()->getUseEllipses();
+	if (use_ellipses)
+	{
+		// limit to set rect to avoid horizontal scrollbar
+		*width = llmin(*width, getRoot()->getRect().getWidth());
+	}
+	*height = getItemHeight();
+	return *height;
+}
+
+S32 LLFolderViewItem::getItemHeight()
+{
+	return mItemHeight;
+}
+
+// *TODO: This can be optimized a lot by simply recording that it is
+// selected in the appropriate places, and assuming that set selection
+// means 'deselect' for a leaf item. Do this optimization after
+// multiple selection is implemented to make sure it all plays nice
+// together.
+BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
+{
+	if (selection == this && !mIsSelected)
+	{
+		selectItem();
+	}
+	else if (mIsSelected)	// Deselect everything else.
+	{
+		deselectItem();
+	}
+	return mIsSelected;
+}
+
+BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+	if (selection == this)
+	{
+		if (mIsSelected)
+		{
+			deselectItem();
+		}
+		else
+		{
+			selectItem();
+		}
+		return TRUE;
+	}
+	return FALSE;
+}
+
+void LLFolderViewItem::deselectItem(void)
+{
+	mIsSelected = FALSE;
+}
+
+void LLFolderViewItem::selectItem(void)
+{
+	if (mIsSelected == FALSE)
+	{
+		getViewModelItem()->selectItem();
+		mIsSelected = TRUE;
+	}
+}
+
+BOOL LLFolderViewItem::isMovable()
+{
+	return getViewModelItem()->isItemMovable();
+}
+
+BOOL LLFolderViewItem::isRemovable()
+{
+	return getViewModelItem()->isItemRemovable();
+}
+
+void LLFolderViewItem::destroyView()
+{
+	getRoot()->removeFromSelectionList(this);
+
+	if (mParentFolder)
+	{
+		// removeView deletes me
+		mParentFolder->extractItem(this);
+	}
+	delete this;
+}
+
+// Call through to the viewed object and return true if it can be
+// removed.
+//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
+BOOL LLFolderViewItem::remove()
+{
+	if(!isRemovable())
+	{
+		return FALSE;
+	}
+	return getViewModelItem()->removeItem();
+}
+
+// Build an appropriate context menu for the item.
+void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+	getViewModelItem()->buildContextMenu(menu, flags);
+}
+
+void LLFolderViewItem::openItem( void )
+{
+	getViewModelItem()->openItem();
+}
+
+void LLFolderViewItem::rename(const std::string& new_name)
+{
+	if( !new_name.empty() )
+	{
+		getViewModelItem()->renameItem(new_name);
+
+			if(mParentFolder)
+			{
+				mParentFolder->requestSort();
+			}
+		}
+	}
+
+const std::string& LLFolderViewItem::getName( void ) const
+{
+	return getViewModelItem()->getName();
+}
+
+// LLView functionality
+BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+	if(!mIsSelected)
+	{
+		getRoot()->setSelection(this, FALSE);
+	}
+	make_ui_sound("UISndClick");
+	return TRUE;
+}
+
+BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	if (LLView::childrenHandleMouseDown(x, y, mask))
+	{
+		return TRUE;
+	}
+	
+	// No handler needed for focus lost since this class has no
+	// state that depends on it.
+	gFocusMgr.setMouseCapture( this );
+
+	if (!mIsSelected)
+	{
+		if(mask & MASK_CONTROL)
+		{
+			getRoot()->changeSelection(this, !mIsSelected);
+		}
+		else if (mask & MASK_SHIFT)
+		{
+			getParentFolder()->extendSelectionTo(this);
+		}
+		else
+		{
+			getRoot()->setSelection(this, FALSE);
+		}
+		make_ui_sound("UISndClick");
+	}
+	else
+	{
+		mSelectPending = TRUE;
+	}
+
+	mDragStartX = x;
+	mDragStartY = y;
+	return TRUE;
+}
+
+BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
+{
+	static LLCachedControl<S32> drag_and_drop_threshold(*LLUI::sSettingGroups["config"],"DragAndDropDistanceThreshold");
+
+	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
+	if( hasMouseCapture() && isMovable() )
+	{
+		LLFolderView* root = getRoot();
+
+		if( (x - mDragStartX) * (x - mDragStartX) + (y - mDragStartY) * (y - mDragStartY) > drag_and_drop_threshold() * drag_and_drop_threshold() 
+			&& root->getCurSelectedItem()
+			&& root->startDrag())
+		{
+			// RN: when starting drag and drop, clear out last auto-open
+			root->autoOpenTest(NULL);
+			root->setShowSelectionContext(TRUE);
+
+			// Release keyboard focus, so that if stuff is dropped into the
+			// world, pressing the delete key won't blow away the inventory
+			// item.
+			gFocusMgr.setKeyboardFocus(NULL);
+
+			getWindow()->setCursor(UI_CURSOR_ARROW);
+			return TRUE;
+		}
+		else
+		{
+			getWindow()->setCursor(UI_CURSOR_NOLOCKED);
+			return TRUE;
+		}
+	}
+	else
+	{
+		getRoot()->setShowSelectionContext(FALSE);
+		getWindow()->setCursor(UI_CURSOR_ARROW);
+		// let parent handle this then...
+		return FALSE;
+	}
+}
+
+
+BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+	getViewModelItem()->openItem();
+	return TRUE;
+}
+
+BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+	if (LLView::childrenHandleMouseUp(x, y, mask))
+	{
+		return TRUE;
+	}
+	
+	// if mouse hasn't moved since mouse down...
+	if ( pointInView(x, y) && mSelectPending )
+	{
+		//...then select
+		if(mask & MASK_CONTROL)
+		{
+			getRoot()->changeSelection(this, !mIsSelected);
+		}
+		else if (mask & MASK_SHIFT)
+		{
+			getParentFolder()->extendSelectionTo(this);
+		}
+		else
+		{
+			getRoot()->setSelection(this, FALSE);
+		}
+	}
+
+	mSelectPending = FALSE;
+
+	if( hasMouseCapture() )
+	{
+		if (getRoot())
+		{
+		getRoot()->setShowSelectionContext(FALSE);
+		}
+		gFocusMgr.setMouseCapture( NULL );
+	}
+	return TRUE;
+}
+
+void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	mIsMouseOverTitle = false;
+}
+
+BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+										 EDragAndDropType cargo_type,
+										 void* cargo_data,
+										 EAcceptance* accept,
+										 std::string& tooltip_msg)
+{
+	BOOL handled = FALSE;
+	BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+		handled = accepted;
+		if (accepted)
+		{
+			mDragAndDropTarget = TRUE;
+			*accept = ACCEPT_YES_MULTI;
+		}
+		else
+		{
+			*accept = ACCEPT_NO;
+		}
+	if(mParentFolder && !handled)
+	{
+		// store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event.
+		mRoot->setDraggingOverItem(this);
+		handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
+		mRoot->setDraggingOverItem(NULL);
+	}
+	if (handled)
+	{
+		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
+	}
+
+	return handled;
+}
+
+void LLFolderViewItem::draw()
+{
+	static LLUIColor sFgColor 			= LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+	static LLUIColor sHighlightBgColor 	= LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+	static LLUIColor sHighlightFgColor 	= LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+	static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+	static LLUIColor sFilterBGColor 	= LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+	static LLUIColor sFilterTextColor 	= LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+	static LLUIColor sSuffixColor 		= LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
+	static LLUIColor sLibraryColor 		= LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
+	static LLUIColor sLinkColor 		= LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
+	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+	static LLUIColor sMouseOverColor 	= LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+
+	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+	const S32 TOP_PAD = default_params.item_top_pad;
+	const S32 FOCUS_LEFT = 1;
+	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+
+	getViewModelItem()->update();
+
+	//--------------------------------------------------------------------------------//
+	// Draw open folder arrow
+	//
+	if (hasVisibleChildren() || getViewModelItem()->hasChildren())
+	{
+		LLUIImage* arrow_image = default_params.folder_arrow_image;
+		gl_draw_scaled_rotated_image(
+			mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
+			ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
+	}
+
+
+	//--------------------------------------------------------------------------------//
+	// Draw highlight for selected items
+	//
+	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+	const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
+	const S32 focus_top = getRect().getHeight();
+	const S32 focus_bottom = getRect().getHeight() - mItemHeight;
+	const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
+	if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE
+	{
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		LLColor4 bg_color = sHighlightBgColor;
+		if (!mIsCurSelection)
+		{
+			// do time-based fade of extra objects
+			F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
+			if (getRoot() && getRoot()->getShowSingleSelection())
+			{
+				// fading out
+				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
+			}
+			else
+			{
+				// fading in
+				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
+			}
+		}
+		gl_rect_2d(FOCUS_LEFT,
+				   focus_top, 
+				   getRect().getWidth() - 2,
+				   focus_bottom,
+				   bg_color, filled);
+		if (mIsCurSelection)
+		{
+			gl_rect_2d(FOCUS_LEFT, 
+					   focus_top, 
+					   getRect().getWidth() - 2,
+					   focus_bottom,
+					   sFocusOutlineColor, FALSE);
+		}
+		if (folder_open)
+		{
+			gl_rect_2d(FOCUS_LEFT,
+					   focus_bottom + 1, // overlap with bottom edge of above rect
+					   getRect().getWidth() - 2,
+					   0,
+					   sFocusOutlineColor, FALSE);
+			if (show_context)
+			{
+				gl_rect_2d(FOCUS_LEFT,
+						   focus_bottom + 1,
+						   getRect().getWidth() - 2,
+						   0,
+						   sHighlightBgColor, TRUE);
+			}
+		}
+	}
+	else if (mIsMouseOverTitle)
+	{
+		gl_rect_2d(FOCUS_LEFT,
+			focus_top, 
+			getRect().getWidth() - 2,
+			focus_bottom,
+			sMouseOverColor, FALSE);
+	}
+
+	//--------------------------------------------------------------------------------//
+	// Draw DragNDrop highlight
+	//
+	if (mDragAndDropTarget)
+	{
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		gl_rect_2d(FOCUS_LEFT, 
+				   focus_top, 
+				   getRect().getWidth() - 2,
+				   focus_bottom,
+				   sHighlightBgColor, FALSE);
+		if (folder_open)
+		{
+			gl_rect_2d(FOCUS_LEFT,
+					   focus_bottom + 1, // overlap with bottom edge of above rect
+					   getRect().getWidth() - 2,
+					   0,
+					   sHighlightBgColor, FALSE);
+		}
+		mDragAndDropTarget = FALSE;
+	}
+
+	//--------------------------------------------------------------------------------//
+	// Draw open icon
+	//
+	const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
+	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
+ 	{
+		mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
+	}
+	else if (mIcon)
+	{
+ 		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+ 	}
+
+	if (mIconOverlay && getRoot()->showItemLinkOverlays())
+	{
+		mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+	}
+
+	//--------------------------------------------------------------------------------//
+	// Exit if no label to draw
+	//
+	if (mLabel.empty())
+	{
+		return;
+	}
+
+	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
+	//TODO RN: implement this in terms of getColor()
+	//if (highlight_link) color = sLinkColor;
+	//if (gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
+	
+	F32 right_x  = 0;
+	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
+
+	//--------------------------------------------------------------------------------//
+	// Draw the actual label text
+	//
+	font->renderUTF8(mLabel, 0, text_left, y, color,
+					 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+					 S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);
+
+	//--------------------------------------------------------------------------------//
+	// Draw label suffix
+	//
+	if (!mLabelSuffix.empty())
+	{
+		font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
+						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+						  S32_MAX, S32_MAX, &right_x, FALSE );
+	}
+
+	//--------------------------------------------------------------------------------//
+	// Highlight string match
+	//
+	//TODO RN: expose interface for highlighting
+	//if (mStringMatchOffset != std::string::npos)
+	//{
+	//	// don't draw backgrounds for zero-length strings
+	//	S32 filter_string_length = getRoot()->getFilterSubString().size();
+	//	if (filter_string_length > 0)
+	//	{
+	//		std::string combined_string = mLabel + mLabelSuffix;
+	//		S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
+	//		S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
+	//		S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
+	//		S32 top = getRect().getHeight() - TOP_PAD;
+	//	
+	//		LLUIImage* box_image = default_params.selection_image;
+	//		LLRect box_rect(left, top, right, bottom);
+	//		box_image->draw(box_rect, sFilterBGColor);
+	//		F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
+	//		F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+	//		font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
+	//						  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+	//						  filter_string_length, S32_MAX, &right_x, FALSE );
+	//	}
+	//}
+}
+
+const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
+	{
+	return getRoot()->getFolderViewModel();
+}
+
+LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
+		{
+	return getRoot()->getFolderViewModel();
+}
+
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewFolder
+///----------------------------------------------------------------------------
+
+LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): 
+	LLFolderViewItem( p ),
+	mIsOpen(FALSE),
+	mExpanderHighlighted(FALSE),
+	mCurHeight(0.f),
+	mTargetHeight(0.f),
+	mAutoOpenCountdown(0.f),
+	mLastArrangeGeneration( -1 ),
+	mLastCalculatedWidth(0)
+{
+}
+
+// Destroys the object
+LLFolderViewFolder::~LLFolderViewFolder( void )
+{
+	// The LLView base class takes care of object destruction. make sure that we
+	// don't have mouse or keyboard focus
+	gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+}
+
+// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
+{
+	return folder->addFolder(this);
+}
+
+static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
+
+// Finds width and height of this object and its children. Also
+// makes sure that this view and its children are the right size.
+S32 LLFolderViewFolder::arrange( S32* width, S32* height )
+{
+	// sort before laying out contents
+	getRoot()->getFolderViewModel()->sort(this);
+
+	LLFastTimer t2(FTM_ARRANGE);
+
+	// evaluate mHasVisibleChildren
+	mHasVisibleChildren = false;
+	if (getViewModelItem()->descendantsPassedFilter())
+	{
+		// We have to verify that there's at least one child that's not filtered out
+		bool found = false;
+		// Try the items first
+		for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
+		{
+			LLFolderViewItem* itemp = (*iit);
+			found = itemp->passedFilter();
+			if (found)
+				break;
+		}
+		if (!found)
+		{
+			// If no item found, try the folders
+			for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
+			{
+				LLFolderViewFolder* folderp = (*fit);
+				found = folderp->passedFilter();
+				if (found)
+					break;
+			}
+		}
+
+		mHasVisibleChildren = found;
+	}
+
+	// calculate height as a single item (without any children), and reshapes rectangle to match
+	LLFolderViewItem::arrange( width, height );
+
+	// clamp existing animated height so as to never get smaller than a single item
+	mCurHeight = llmax((F32)*height, mCurHeight);
+
+	// initialize running height value as height of single item in case we have no children
+	F32 running_height = (F32)*height;
+	F32 target_height = (F32)*height;
+
+	// are my children visible?
+	if (needsArrange())
+	{
+		// set last arrange generation first, in case children are animating
+		// and need to be arranged again
+		mLastArrangeGeneration = getRoot()->getArrangeGeneration();
+		if (isOpen())
+		{
+			// Add sizes of children
+			S32 parent_item_height = getRect().getHeight();
+
+			for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
+			{
+				LLFolderViewFolder* folderp = (*fit);
+				folderp->setVisible(folderp->passedFilter()); // passed filter or has descendants that passed filter
+
+				if (folderp->getVisible())
+				{
+					S32 child_width = *width;
+					S32 child_height = 0;
+					S32 child_top = parent_item_height - llround(running_height);
+
+					target_height += folderp->arrange( &child_width, &child_height );
+
+					running_height += (F32)child_height;
+					*width = llmax(*width, child_width);
+					folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
+				}
+			}
+			for(items_t::iterator iit = mItems.begin();
+				iit != mItems.end(); ++iit)
+			{
+				LLFolderViewItem* itemp = (*iit);
+				itemp->setVisible(itemp->passedFilter());
+
+				if (itemp->getVisible())
+				{
+					S32 child_width = *width;
+					S32 child_height = 0;
+					S32 child_top = parent_item_height - llround(running_height);
+
+					target_height += itemp->arrange( &child_width, &child_height );
+					// don't change width, as this item is as wide as its parent folder by construction
+					itemp->reshape( itemp->getRect().getWidth(), child_height);
+
+					running_height += (F32)child_height;
+					*width = llmax(*width, child_width);
+					itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
+				}
+			}
+		}
+
+		mTargetHeight = target_height;
+		// cache this width so next time we can just return it
+		mLastCalculatedWidth = *width;
+	}
+	else
+	{
+		// just use existing width
+		*width = mLastCalculatedWidth;
+	}
+
+	// animate current height towards target height
+	if (llabs(mCurHeight - mTargetHeight) > 1.f)
+	{
+		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
+
+		requestArrange();
+
+		// hide child elements that fall out of current animated height
+		for (folders_t::iterator iter = mFolders.begin();
+			iter != mFolders.end();)
+		{
+			folders_t::iterator fit = iter++;
+			// number of pixels that bottom of folder label is from top of parent folder
+			if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() 
+				> llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
+			{
+				// hide if beyond current folder height
+				(*fit)->setVisible(FALSE);
+			}
+		}
+
+		for (items_t::iterator iter = mItems.begin();
+			iter != mItems.end();)
+		{
+			items_t::iterator iit = iter++;
+			// number of pixels that bottom of item label is from top of parent folder
+			if (getRect().getHeight() - (*iit)->getRect().mBottom
+				> llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
+			{
+				(*iit)->setVisible(FALSE);
+			}
+		}
+	}
+	else
+	{
+		mCurHeight = mTargetHeight;
+	}
+
+	// don't change width as this item is already as wide as its parent folder
+	reshape(getRect().getWidth(),llround(mCurHeight));
+
+	// pass current height value back to parent
+	*height = llround(mCurHeight);
+
+	return llround(mTargetHeight);
+}
+
+BOOL LLFolderViewFolder::needsArrange()
+{
+	return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); 
+}
+
+void LLFolderViewFolder::requestSort()
+{
+	getViewModelItem()->requestSort();
+}
+
+//TODO RN: get height resetting working
+//void LLFolderViewFolder::setPassedFilter(BOOL passed, BOOL passed_folder, S32 filter_generation)
+//{
+//	// if this folder is now filtered, but wasn't before
+//	// (it just passed)
+//	if (passed && !passedFilter(filter_generation))
+//	{
+//		// reset current height, because last time we drew it
+//		// it might have had more visible items than now
+//		mCurHeight = 0.f;
+//	}
+//
+//	LLFolderViewItem::setPassedFilter(passed, passed_folder, filter_generation);
+//}
+
+
+// Passes selection information on to children and record selection
+// information if necessary.
+BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
+                                      BOOL take_keyboard_focus)
+{
+	BOOL rv = FALSE;
+	if (selection == this)
+	{
+		if (!isSelected())
+		{
+			selectItem();
+		}
+		rv = TRUE;
+	}
+	else
+	{
+		if (isSelected())
+		{
+			deselectItem();
+		}
+		rv = FALSE;
+	}
+	BOOL child_selected = FALSE;
+
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
+		{
+			rv = TRUE;
+			child_selected = TRUE;
+		}
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
+		{
+			rv = TRUE;
+			child_selected = TRUE;
+		}
+	}
+	if(openitem && child_selected)
+	{
+		setOpenArrangeRecursively(TRUE);
+	}
+	return rv;
+}
+
+// This method is used to change the selection of an item.
+// Recursively traverse all children; if 'selection' is 'this' then change
+// the select status if necessary.
+// Returns TRUE if the selection state of this folder, or of a child, was changed.
+BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+	BOOL rv = FALSE;
+	if(selection == this)
+	{
+		if (isSelected() != selected)
+		{
+			rv = TRUE;
+			if (selected)
+			{
+				selectItem();
+			}
+			else
+			{
+				deselectItem();
+			}
+		}
+	}
+
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		if((*fit)->changeSelection(selection, selected))
+		{
+			rv = TRUE;
+		}
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		if((*iit)->changeSelection(selection, selected))
+		{
+			rv = TRUE;
+		}
+	}
+	return rv;
+}
+
+LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
+{
+	if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
+
+	std::deque<LLFolderViewFolder*> item_a_ancestors;
+
+	LLFolderViewFolder* parent = item_a->getParentFolder();
+	while(parent)
+	{
+		item_a_ancestors.push_back(parent);
+		parent = parent->getParentFolder();
+	}
+
+	std::deque<LLFolderViewFolder*> item_b_ancestors;
+	
+	parent = item_b->getParentFolder();
+	while(parent)
+	{
+		item_b_ancestors.push_back(parent);
+		parent = parent->getParentFolder();
+	}
+
+	LLFolderViewFolder* common_ancestor = item_a->getRoot();
+
+	while(item_a_ancestors.size() > item_b_ancestors.size())
+	{
+		item_a = item_a_ancestors.front();
+		item_a_ancestors.pop_front();
+	}
+
+	while(item_b_ancestors.size() > item_a_ancestors.size())
+	{
+		item_b = item_b_ancestors.front();
+		item_b_ancestors.pop_front();
+	}
+
+	while(item_a_ancestors.size())
+	{
+		common_ancestor = item_a_ancestors.front();
+
+		if (item_a_ancestors.front() == item_b_ancestors.front())
+		{
+			// which came first, sibling a or sibling b?
+			for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
+				it != end_it;
+				++it)
+			{
+				LLFolderViewItem* item = *it;
+
+				if (item == item_a)
+				{
+					reverse = false;
+					return common_ancestor;
+				}
+				if (item == item_b)
+				{
+					reverse = true;
+					return common_ancestor;
+				}
+			}
+
+			for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
+				it != end_it;
+				++it)
+			{
+				LLFolderViewItem* item = *it;
+
+				if (item == item_a)
+				{
+					reverse = false;
+					return common_ancestor;
+				}
+				if (item == item_b)
+				{
+					reverse = true;
+					return common_ancestor;
+				}
+			}
+			break;
+		}
+
+		item_a = item_a_ancestors.front();
+		item_a_ancestors.pop_front();
+		item_b = item_b_ancestors.front();
+		item_b_ancestors.pop_front();
+	}
+
+	return NULL;
+}
+
+void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
+{
+	bool selecting = start == NULL;
+	if (reverse)
+	{
+		for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
+			it != end_it;
+			++it)
+		{
+			if (*it == end)
+			{
+				return;
+			}
+			if (selecting)
+			{
+				items.push_back(*it);
+			}
+
+			if (*it == start)
+			{
+				selecting = true;
+			}
+		}
+		for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
+			it != end_it;
+			++it)
+		{
+			if (*it == end)
+			{
+				return;
+			}
+
+			if (selecting)
+			{
+				items.push_back(*it);
+			}
+
+			if (*it == start)
+			{
+				selecting = true;
+			}
+		}
+	}
+	else
+	{
+		for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
+			it != end_it;
+			++it)
+		{
+			if (*it == end)
+			{
+				return;
+			}
+
+			if (selecting)
+			{
+				items.push_back(*it);
+			}
+
+			if (*it == start)
+			{
+				selecting = true;
+			}
+		}
+		for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
+			it != end_it;
+			++it)
+		{
+			if (*it == end)
+			{
+				return;
+			}
+
+			if (selecting)
+			{
+				items.push_back(*it);
+			}
+
+			if (*it == start)
+			{
+				selecting = true;
+			}
+		}
+	}
+}
+
+void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
+{
+	if (getRoot()->getAllowMultiSelect() == FALSE) return;
+
+	LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem();
+	if (cur_selected_item == NULL)
+	{
+		cur_selected_item = new_selection;
+	}
+
+
+	bool reverse = false;
+	LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse);
+	if (!common_ancestor) return;
+
+	LLFolderViewItem* last_selected_item_from_cur = cur_selected_item;
+	LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder();
+
+	std::vector<LLFolderViewItem*> items_to_select_forward;
+
+	while(cur_folder != common_ancestor)
+	{
+		cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward);
+			
+		last_selected_item_from_cur = cur_folder;
+		cur_folder = cur_folder->getParentFolder();
+	}
+
+	std::vector<LLFolderViewItem*> items_to_select_reverse;
+
+	LLFolderViewItem* last_selected_item_from_new = new_selection;
+	cur_folder = new_selection->getParentFolder();
+	while(cur_folder != common_ancestor)
+	{
+		cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse);
+
+		last_selected_item_from_new = cur_folder;
+		cur_folder = cur_folder->getParentFolder();
+	}
+
+	common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward);
+
+	for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend();
+		it != end_it;
+		++it)
+	{
+		items_to_select_forward.push_back(*it);
+	}
+
+	LLFolderView* root = getRoot();
+
+	for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
+		it != end_it;
+		++it)
+	{
+		LLFolderViewItem* item = *it;
+		if (item->isSelected())
+		{
+			root->removeFromSelectionList(item);
+		}
+		else
+		{
+			item->selectItem();
+		}
+		root->addToSelectionList(item);
+	}
+
+	if (new_selection->isSelected())
+	{
+		root->removeFromSelectionList(new_selection);
+	}
+	else
+	{
+		new_selection->selectItem();
+	}
+	root->addToSelectionList(new_selection);
+}
+
+
+void LLFolderViewFolder::destroyView()
+{
+	std::for_each(mItems.begin(), mItems.end(), DeletePointer());
+	mItems.clear();
+
+	while (!mFolders.empty())
+	{
+		LLFolderViewFolder *folderp = mFolders.back();
+		folderp->destroyView(); // removes entry from mFolders
+	}
+
+	LLFolderViewItem::destroyView();
+}
+
+// extractItem() removes the specified item from the folder, but
+// doesn't delete it.
+void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
+{
+	items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
+	if(it == mItems.end())
+	{
+		// This is an evil downcast. However, it's only doing
+		// pointer comparison to find if (which it should be ) the
+		// item is in the container, so it's pretty safe.
+		LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item);
+		folders_t::iterator ft;
+		ft = std::find(mFolders.begin(), mFolders.end(), f);
+		if (ft != mFolders.end())
+		{
+			mFolders.erase(ft);
+		}
+	}
+	else
+	{
+		mItems.erase(it);
+	}
+	//item has been removed, need to update filter
+	getViewModelItem()->removeChild(item->getViewModelItem());
+	getViewModelItem()->dirtyFilter();
+	//because an item is going away regardless of filter status, force rearrange
+	requestArrange();
+	removeChild(item);
+}
+
+BOOL LLFolderViewFolder::isMovable()
+{
+	if( !(getViewModelItem()->isItemMovable()) )
+		{
+			return FALSE;
+		}
+
+		for (items_t::iterator iter = mItems.begin();
+			iter != mItems.end();)
+		{
+			items_t::iterator iit = iter++;
+			if(!(*iit)->isMovable())
+			{
+				return FALSE;
+			}
+		}
+
+		for (folders_t::iterator iter = mFolders.begin();
+			iter != mFolders.end();)
+		{
+			folders_t::iterator fit = iter++;
+			if(!(*fit)->isMovable())
+			{
+				return FALSE;
+			}
+		}
+	return TRUE;
+}
+
+
+BOOL LLFolderViewFolder::isRemovable()
+{
+	if( !(getViewModelItem()->isItemRemovable()) )
+		{
+			return FALSE;
+		}
+
+		for (items_t::iterator iter = mItems.begin();
+			iter != mItems.end();)
+		{
+			items_t::iterator iit = iter++;
+			if(!(*iit)->isRemovable())
+			{
+				return FALSE;
+			}
+		}
+
+		for (folders_t::iterator iter = mFolders.begin();
+			iter != mFolders.end();)
+		{
+			folders_t::iterator fit = iter++;
+			if(!(*fit)->isRemovable())
+			{
+				return FALSE;
+			}
+		}
+	return TRUE;
+}
+
+// this is an internal method used for adding items to folders. 
+BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
+{
+	if (item->getParentFolder())
+	{
+		item->getParentFolder()->extractItem(item);
+	}
+	item->setParentFolder(this);
+
+	mItems.push_back(item);
+	
+	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
+	item->setVisible(FALSE);
+	
+	addChild(item);
+	
+	item->getViewModelItem()->dirtyFilter();
+
+	// Handle sorting
+	requestArrange();
+	requestSort();
+
+	getViewModelItem()->addChild(item->getViewModelItem());
+
+	//TODO RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
+	//// Traverse parent folders and update creation date and resort, if necessary
+	//LLFolderViewFolder* parentp = this;
+	//while (parentp)
+	//{
+	//	if (parentp->mSortFunction.isByDate())
+	//	{
+	//		// parent folder doesn't have a time stamp yet, so get it from us
+	//		parentp->requestSort();
+	//	}
+
+	//	parentp = parentp->getParentFolder();
+	//}
+
+	return TRUE;
+}
+
+// this is an internal method used for adding items to folders. 
+BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
+{
+	if (folder->mParentFolder)
+	{
+		folder->mParentFolder->extractItem(folder);
+	}
+	folder->mParentFolder = this;
+	mFolders.push_back(folder);
+	folder->setOrigin(0, 0);
+	folder->reshape(getRect().getWidth(), 0);
+	folder->setVisible(FALSE);
+	addChild( folder );
+	folder->getViewModelItem()->dirtyFilter();
+	// rearrange all descendants too, as our indentation level might have changed
+	folder->requestArrange();
+	requestSort();
+
+	getViewModelItem()->addChild(folder->getViewModelItem());
+
+	return TRUE;
+}
+
+void LLFolderViewFolder::requestArrange()
+{ 
+	mLastArrangeGeneration = -1; 
+	// flag all items up to root
+	if (mParentFolder)
+	{
+		mParentFolder->requestArrange();
+	}
+}
+
+void LLFolderViewFolder::toggleOpen()
+{
+	setOpen(!isOpen());
+}
+
+// Force a folder open or closed
+void LLFolderViewFolder::setOpen(BOOL openitem)
+{
+	setOpenArrangeRecursively(openitem);
+}
+
+void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
+{
+	BOOL was_open = isOpen();
+	mIsOpen = openitem;
+	if(!was_open && openitem)
+	{
+		getViewModelItem()->openItem();
+	}
+	else if(was_open && !openitem)
+	{
+		getViewModelItem()->closeItem();
+	}
+
+	if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
+	{
+		for (folders_t::iterator iter = mFolders.begin();
+			iter != mFolders.end();)
+		{
+			folders_t::iterator fit = iter++;
+			(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN);		/* Flawfinder: ignore */
+		}
+	}
+	if (mParentFolder
+		&&	(recurse == RECURSE_UP
+			|| recurse == RECURSE_UP_DOWN))
+	{
+		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
+	}
+
+	if (was_open != isOpen())
+	{
+		requestArrange();
+	}
+}
+
+BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
+													BOOL drop,
+													EDragAndDropType c_type,
+													void* cargo_data,
+													EAcceptance* accept,
+													std::string& tooltip_msg)
+{
+	BOOL accepted = mViewModelItem->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
+	if (accepted) 
+	{
+		mDragAndDropTarget = TRUE;
+		*accept = ACCEPT_YES_MULTI;
+	}
+	else 
+	{
+		*accept = ACCEPT_NO;
+	}
+
+	// drag and drop to child item, so clear pending auto-opens
+	getRoot()->autoOpenTest(NULL);
+
+	return TRUE;
+}
+
+void LLFolderViewFolder::openItem( void )
+{
+	toggleOpen();
+}
+
+void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
+{
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		functor.doItem((*fit));
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		functor.doItem((*iit));
+	}
+}
+
+void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
+{
+	functor.doFolder(this);
+
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		(*fit)->applyFunctorRecursively(functor);
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		functor.doItem((*iit));
+	}
+}
+
+// LLView functionality
+BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
+										   BOOL drop,
+										   EDragAndDropType cargo_type,
+										   void* cargo_data,
+										   EAcceptance* accept,
+										   std::string& tooltip_msg)
+{
+	BOOL handled = FALSE;
+
+	if (isOpen())
+	{
+		handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
+	}
+
+	if (!handled)
+	{
+		handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
+	}
+
+	return TRUE;
+}
+
+BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
+													   BOOL drop,
+													   EDragAndDropType cargo_type,
+													   void* cargo_data,
+													   EAcceptance* accept,
+													   std::string& tooltip_msg)
+{
+	BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+	
+	if (accepted) 
+	{
+		mDragAndDropTarget = TRUE;
+		*accept = ACCEPT_YES_MULTI;
+	}
+	else 
+	{
+		*accept = ACCEPT_NO;
+	}
+	
+	if (!drop && accepted)
+	{
+		getRoot()->autoOpenTest(this);
+	}
+	
+	return TRUE;
+}
+
+
+BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+	BOOL handled = FALSE;
+
+	if( isOpen() )
+	{
+		handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
+	}
+	if (!handled)
+	{
+		handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
+	}
+	return handled;
+}
+
+
+BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
+{
+	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
+	BOOL handled = LLView::handleHover(x, y, mask);
+
+	if (!handled)
+	{
+		// this doesn't do child processing
+		handled = LLFolderViewItem::handleHover(x, y, mask);
+	}
+
+	return handled;
+}
+
+BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	BOOL handled = FALSE;
+	if( isOpen() )
+	{
+		handled = childrenHandleMouseDown(x,y,mask) != NULL;
+	}
+	if( !handled )
+	{
+		if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
+		{
+			toggleOpen();
+			handled = TRUE;
+		}
+		else
+		{
+			// do normal selection logic
+			handled = LLFolderViewItem::handleMouseDown(x, y, mask);
+		}
+	}
+
+	return handled;
+}
+
+BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+	BOOL handled = FALSE;
+	if( isOpen() )
+	{
+		handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
+	}
+	if( !handled )
+	{
+		if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
+		{
+			// don't select when user double-clicks plus sign
+			// so as not to contradict single-click behavior
+			toggleOpen();
+		}
+		else
+		{
+			getRoot()->setSelection(this, FALSE);
+			toggleOpen();
+		}
+		handled = TRUE;
+	}
+	return handled;
+}
+
+void LLFolderViewFolder::draw()
+{
+	if (mAutoOpenCountdown != 0.f)
+	{
+		mControlLabelRotation = mAutoOpenCountdown * -90.f;
+	}
+	else if (isOpen())
+	{
+		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
+	}
+	else
+	{
+		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
+	}
+
+	LLFolderViewItem::draw();
+
+	// draw children if root folder, or any other folder that is open or animating to closed state
+	if( getRoot() == this || (isOpen() || mCurHeight != mTargetHeight ))
+	{
+		LLView::draw();
+	}
+
+	mExpanderHighlighted = FALSE;
+}
+
+// this does prefix traversal, as folders are listed above their contents
+LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
+{
+	BOOL found_item = FALSE;
+
+	LLFolderViewItem* result = NULL;
+	// when not starting from a given item, start at beginning
+	if(item == NULL)
+	{
+		found_item = TRUE;
+	}
+
+	// find current item among children
+	folders_t::iterator fit = mFolders.begin();
+	folders_t::iterator fend = mFolders.end();
+
+	items_t::iterator iit = mItems.begin();
+	items_t::iterator iend = mItems.end();
+
+	// if not trivially starting at the beginning, we have to find the current item
+	if (!found_item)
+	{
+		// first, look among folders, since they are always above items
+		for(; fit != fend; ++fit)
+		{
+			if(item == (*fit))
+			{
+				found_item = TRUE;
+				// if we are on downwards traversal
+				if (include_children && (*fit)->isOpen())
+				{
+					// look for first descendant
+					return (*fit)->getNextFromChild(NULL, TRUE);
+				}
+				// otherwise advance to next folder
+				++fit;
+				include_children = TRUE;
+				break;
+			}
+		}
+
+		// didn't find in folders?  Check items...
+		if (!found_item)
+		{
+			for(; iit != iend; ++iit)
+			{
+				if(item == (*iit))
+				{
+					found_item = TRUE;
+					// point to next item
+					++iit;
+					break;
+				}
+			}
+		}
+	}
+
+	if (!found_item)
+	{
+		// you should never call this method with an item that isn't a child
+		// so we should always find something
+		llassert(FALSE);
+		return NULL;
+	}
+
+	// at this point, either iit or fit point to a candidate "next" item
+	// if both are out of range, we need to punt up to our parent
+
+	// now, starting from found folder, continue through folders
+	// searching for next visible folder
+	while(fit != fend && !(*fit)->getVisible())
+	{
+		// turn on downwards traversal for next folder
+		++fit;
+	} 
+
+	if (fit != fend)
+	{
+		result = (*fit);
+	}
+	else
+	{
+		// otherwise, scan for next visible item
+		while(iit != iend && !(*iit)->getVisible())
+		{
+			++iit;
+		} 
+
+		// check to see if we have a valid item
+		if (iit != iend)
+		{
+			result = (*iit);
+		}
+	}
+
+	if( !result && mParentFolder )
+	{
+		// If there are no siblings or children to go to, recurse up one level in the tree
+		// and skip children for this folder, as we've already discounted them
+		result = mParentFolder->getNextFromChild(this, FALSE);
+	}
+
+	return result;
+}
+
+// this does postfix traversal, as folders are listed above their contents
+LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
+{
+	BOOL found_item = FALSE;
+
+	LLFolderViewItem* result = NULL;
+	// when not starting from a given item, start at end
+	if(item == NULL)
+	{
+		found_item = TRUE;
+	}
+
+	// find current item among children
+	folders_t::reverse_iterator fit = mFolders.rbegin();
+	folders_t::reverse_iterator fend = mFolders.rend();
+
+	items_t::reverse_iterator iit = mItems.rbegin();
+	items_t::reverse_iterator iend = mItems.rend();
+
+	// if not trivially starting at the end, we have to find the current item
+	if (!found_item)
+	{
+		// first, look among items, since they are always below the folders
+		for(; iit != iend; ++iit)
+		{
+			if(item == (*iit))
+			{
+				found_item = TRUE;
+				// point to next item
+				++iit;
+				break;
+			}
+		}
+
+		// didn't find in items?  Check folders...
+		if (!found_item)
+		{
+			for(; fit != fend; ++fit)
+			{
+				if(item == (*fit))
+				{
+					found_item = TRUE;
+					// point to next folder
+					++fit;
+					break;
+				}
+			}
+		}
+	}
+
+	if (!found_item)
+	{
+		// you should never call this method with an item that isn't a child
+		// so we should always find something
+		llassert(FALSE);
+		return NULL;
+	}
+
+	// at this point, either iit or fit point to a candidate "next" item
+	// if both are out of range, we need to punt up to our parent
+
+	// now, starting from found item, continue through items
+	// searching for next visible item
+	while(iit != iend && !(*iit)->getVisible())
+	{
+		++iit;
+	} 
+
+	if (iit != iend)
+	{
+		// we found an appropriate item
+		result = (*iit);
+	}
+	else
+	{
+		// otherwise, scan for next visible folder
+		while(fit != fend && !(*fit)->getVisible())
+		{
+			++fit;
+		} 
+
+		// check to see if we have a valid folder
+		if (fit != fend)
+		{
+			// try selecting child element of this folder
+			if ((*fit)->isOpen())
+			{
+				result = (*fit)->getPreviousFromChild(NULL);
+			}
+			else
+			{
+				result = (*fit);
+			}
+		}
+	}
+
+	if( !result )
+	{
+		// If there are no siblings or children to go to, recurse up one level in the tree
+		// which gets back to this folder, which will only be visited if it is a valid, visible item
+		result = this;
+	}
+
+	return result;
+}
+
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
new file mode 100644
index 0000000000..9cb885066a
--- /dev/null
+++ b/indra/llui/llfolderviewitem.h
@@ -0,0 +1,420 @@
+/** 
+* @file llfolderviewitem.h
+* @brief Items and folders that can appear in a hierarchical folder view
+*
+* $LicenseInfo:firstyear=2001&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LLFOLDERVIEWITEM_H
+#define LLFOLDERVIEWITEM_H
+
+#include "llview.h"
+#include "lluiimage.h"
+
+class LLFolderView;
+class LLFolderViewModelItem;
+class LLFolderViewFolder;
+class LLFolderViewFunctor;
+class LLFolderViewFilter;
+class LLFolderViewModelInterface;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewItem
+//
+// An instance of this class represents a single item in a folder view
+// such as an inventory item or a file.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderViewItem : public LLView
+{
+public:
+	static void initClass();
+	static void cleanupClass();
+
+	struct Params : public LLInitParam::Block<Params, LLView::Params>
+	{
+		Optional<LLUIImage*>						folder_arrow_image,
+													selection_image;
+		Optional<LLFolderView*>						root;
+		Mandatory<LLFolderViewModelItem*>			listener;
+
+		Optional<S32>								folder_indentation, // pixels
+													item_height,
+													item_top_pad;
+
+		Optional<time_t>							creation_date;
+
+		Params();
+	};
+
+	// layout constants
+	static const S32 LEFT_PAD = 5;
+	// LEFT_INDENTATION is set via folder_indentation above
+	static const S32 ICON_PAD = 2;
+	static const S32 ICON_WIDTH = 16;
+	static const S32 TEXT_PAD = 1;
+	static const S32 TEXT_PAD_RIGHT = 4;
+	static const S32 ARROW_SIZE = 12;
+	static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
+	// animation parameters
+	static const F32 FOLDER_CLOSE_TIME_CONSTANT;
+	static const F32 FOLDER_OPEN_TIME_CONSTANT;
+
+private:
+	BOOL						mIsSelected;
+
+protected:
+	friend class LLUICtrlFactory;
+	friend class LLFolderViewModelItem;
+
+	LLFolderViewItem(const Params& p);
+
+	std::string					mLabel;
+	S32							mLabelWidth;
+	bool						mLabelWidthDirty;
+	LLFolderViewFolder*			mParentFolder;
+	LLFolderViewModelItem*		mViewModelItem;
+	BOOL						mIsCurSelection;
+	BOOL						mSelectPending;
+	LLFontGL::StyleFlags		mLabelStyle;
+	std::string					mLabelSuffix;
+	LLUIImagePtr				mIcon;
+	LLUIImagePtr				mIconOpen;
+	LLUIImagePtr				mIconOverlay;
+	BOOL						mHasVisibleChildren;
+	S32							mIndentation;
+	S32							mItemHeight;
+	S32							mDragStartX,
+								mDragStartY;
+
+	//TODO RN: create interface for string highlighting
+	//std::string::size_type		mStringMatchOffset;
+	F32							mControlLabelRotation;
+	LLFolderView*				mRoot;
+	BOOL						mDragAndDropTarget;
+	bool						mIsMouseOverTitle;
+
+	// this is an internal method used for adding items to folders. A
+	// no-op at this level, but reimplemented in derived classes.
+	virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
+	virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
+
+	static LLFontGL* getLabelFontForStyle(U8 style);
+
+public:
+	BOOL postBuild();
+
+	virtual void openItem( void );
+
+	void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
+
+	virtual ~LLFolderViewItem( void );
+
+	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+	virtual BOOL addToFolder(LLFolderViewFolder* folder);
+
+	// Finds width and height of this object and it's children.  Also
+	// makes sure that this view and it's children are the right size.
+	virtual S32 arrange( S32* width, S32* height );
+	virtual S32 getItemHeight();
+
+	// If 'selection' is 'this' then note that otherwise ignore.
+	// Returns TRUE if this item ends up being selected.
+	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
+
+	// This method is used to set the selection state of an item.
+	// If 'selection' is 'this' then note selection.
+	// Returns TRUE if the selection state of this item was changed.
+	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
+
+	// this method is used to deselect this element
+	void deselectItem();
+
+	// this method is used to select this element
+	virtual void selectItem();
+
+	// gets multiple-element selection
+	virtual std::set<LLFolderViewItem*> getSelectionList() const;
+
+	// Returns true is this object and all of its children can be removed (deleted by user)
+	virtual BOOL isRemovable();
+
+	// Returns true is this object and all of its children can be moved
+	virtual BOOL isMovable();
+
+	// destroys this item recursively
+	virtual void destroyView();
+
+	BOOL isSelected() const { return mIsSelected; }
+
+	void setUnselected() { mIsSelected = FALSE; }
+
+	void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
+
+	BOOL getIsCurSelection() { return mIsCurSelection; }
+
+	BOOL hasVisibleChildren() { return mHasVisibleChildren; }
+
+	// Call through to the viewed object and return true if it can be
+	// removed. Returns true if it's removed.
+	//virtual BOOL removeRecursively(BOOL single_item);
+	BOOL remove();
+
+	// Build an appropriate context menu for the item.	Flags unused.
+	void buildContextMenu(class LLMenuGL& menu, U32 flags);
+
+	// This method returns the actual name of the thing being
+	// viewed. This method will ask the viewed object itself.
+	const std::string& getName( void ) const;
+
+	// This method returns the label displayed on the view. This
+	// method was primarily added to allow sorting on the folder
+	// contents possible before the entire view has been constructed.
+	const std::string& getLabel() const { return mLabel; }
+
+
+	LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
+	const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
+
+	void setParentFolder(LLFolderViewFolder* parent) { mParentFolder = parent; }
+
+	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
+	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
+
+	const LLFolderViewModelItem* getViewModelItem( void ) const { return mViewModelItem; }
+	LLFolderViewModelItem* getViewModelItem( void ) { return mViewModelItem; }
+
+	const LLFolderViewModelInterface* getFolderViewModel( void ) const;
+	LLFolderViewModelInterface* getFolderViewModel( void );
+
+	// just rename the object.
+	void rename(const std::string& new_name);
+
+
+	// Show children (unfortunate that this is called "open")
+	virtual void setOpen(BOOL open = TRUE) {};
+	virtual BOOL isOpen() const { return FALSE; }
+
+	virtual LLFolderView*	getRoot();
+	virtual const LLFolderView*	getRoot() const;
+	BOOL			isDescendantOf( const LLFolderViewFolder* potential_ancestor );
+	S32				getIndentation() { return mIndentation; }
+
+	virtual BOOL	passedFilter(S32 filter_generation = -1);
+
+	// refresh information from the object being viewed.
+	virtual void refresh();
+
+	// LLView functionality
+	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	virtual BOOL handleHover( S32 x, S32 y, MASK mask );
+	virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
+	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+
+	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
+
+	virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
+
+	//	virtual void handleDropped();
+	virtual void draw();
+	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+		EDragAndDropType cargo_type,
+		void* cargo_data,
+		EAcceptance* accept,
+		std::string& tooltip_msg);
+
+private:
+	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewFolder
+//
+// An instance of an LLFolderViewFolder represents a collection of
+// more folders and items. This is used to build the hierarchy of
+// items found in the folder view.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLFolderViewFolder : public LLFolderViewItem
+{
+protected:
+	LLFolderViewFolder( const LLFolderViewItem::Params& );
+	friend class LLUICtrlFactory;
+
+public:
+
+	typedef std::list<LLFolderViewItem*> items_t;
+	typedef std::list<LLFolderViewFolder*> folders_t;
+
+protected:
+	items_t mItems;
+	folders_t mFolders;
+
+	BOOL		mIsOpen;
+	BOOL		mExpanderHighlighted;
+	F32			mCurHeight;
+	F32			mTargetHeight;
+	F32			mAutoOpenCountdown;
+	S32			mLastArrangeGeneration;
+	S32			mLastCalculatedWidth;
+	S32			mMostFilteredDescendantGeneration;
+	bool		mNeedsSort;
+
+public:
+	typedef enum e_recurse_type
+	{
+		RECURSE_NO,
+		RECURSE_UP,
+		RECURSE_DOWN,
+		RECURSE_UP_DOWN
+	} ERecurseType;
+
+
+	virtual ~LLFolderViewFolder( void );
+
+	LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
+	LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE  );
+
+	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+	virtual BOOL addToFolder(LLFolderViewFolder* folder);
+
+	// Finds width and height of this object and it's children.  Also
+	// makes sure that this view and it's children are the right size.
+	virtual S32 arrange( S32* width, S32* height );
+
+	BOOL needsArrange();
+
+	bool descendantsPassedFilter(S32 filter_generation = -1);
+
+	// Passes selection information on to children and record
+	// selection information if necessary.
+	// Returns TRUE if this object (or a child) ends up being selected.
+	// If 'openitem' is TRUE then folders are opened up along the way to the selection.
+	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus = TRUE);
+
+	// This method is used to change the selection of an item.
+	// Recursively traverse all children; if 'selection' is 'this' then change
+	// the select status if necessary.
+	// Returns TRUE if the selection state of this folder, or of a child, was changed.
+	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
+
+	// this method is used to group select items
+	void extendSelectionTo(LLFolderViewItem* selection);
+
+	// Returns true is this object and all of its children can be removed.
+	virtual BOOL isRemovable();
+
+	// Returns true is this object and all of its children can be moved
+	virtual BOOL isMovable();
+
+	// destroys this folder, and all children
+	virtual void destroyView();
+
+	// If this folder can be removed, remove all children that can be
+	// removed, return TRUE if this is empty after the operation and
+	// it's viewed folder object can be removed.
+	//virtual BOOL removeRecursively(BOOL single_item);
+	//virtual BOOL remove();
+
+	// extractItem() removes the specified item from the folder, but
+	// doesn't delete it.
+	virtual void extractItem( LLFolderViewItem* item );
+
+	// This function is called by a child that needs to be resorted.
+	void resort(LLFolderViewItem* item);
+
+	void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
+
+	// folders can be opened. This will usually be called by internal
+	// methods.
+	virtual void toggleOpen();
+
+	// Force a folder open or closed
+	virtual void setOpen(BOOL openitem = TRUE);
+
+	// Called when a child is refreshed.
+	virtual void requestArrange();
+
+	virtual void requestSort();
+
+	// internal method which doesn't update the entire view. This
+	// method was written because the list iterators destroy the state
+	// of other iterations, thus, we can't arrange while iterating
+	// through the children (such as when setting which is selected.
+	virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
+
+	// Get the current state of the folder.
+	virtual BOOL isOpen() const { return mIsOpen; }
+
+	// special case if an object is dropped on the child.
+	BOOL handleDragAndDropFromChild(MASK mask,
+		BOOL drop,
+		EDragAndDropType cargo_type,
+		void* cargo_data,
+		EAcceptance* accept,
+		std::string& tooltip_msg);
+
+	void applyFunctorRecursively(LLFolderViewFunctor& functor);
+
+	// Just apply this functor to the folder's immediate children.
+	void applyFunctorToChildren(LLFolderViewFunctor& functor);
+
+	virtual void openItem( void );
+	virtual BOOL addItem(LLFolderViewItem* item);
+	virtual BOOL addFolder( LLFolderViewFolder* folder);
+
+	// LLView functionality
+	virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
+	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+		EDragAndDropType cargo_type,
+		void* cargo_data,
+		EAcceptance* accept,
+		std::string& tooltip_msg);
+	BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
+									   EDragAndDropType cargo_type,
+									   void* cargo_data,
+									   EAcceptance* accept,
+									   std::string& tooltip_msg);
+	virtual void draw();
+
+	folders_t::iterator getFoldersBegin() { return mFolders.begin(); }
+	folders_t::iterator getFoldersEnd() { return mFolders.end(); }
+	folders_t::size_type getFoldersCount() const { return mFolders.size(); }
+
+	items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
+	items_t::const_iterator getItemsEnd() const { return mItems.end(); }
+	items_t::size_type getItemsCount() const { return mItems.size(); }
+
+	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
+	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);
+
+public:
+	//WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
+	template<typename SORT_FUNC> void sortFolders(const SORT_FUNC& func) { mFolders.sort(func); }
+	template<typename SORT_FUNC> void sortItems(const SORT_FUNC& func) { mItems.sort(func); }
+};
+
+
+#endif  // LLFOLDERVIEWITEM_H
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
new file mode 100644
index 0000000000..dc6e4d754b
--- /dev/null
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -0,0 +1,53 @@
+/** 
+ * @file llfolderviewmodel.cpp
+ * @brief Implementation of the view model collection of classes.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llfolderviewmodel.h"
+#include "lltrans.h"
+
+bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
+{
+	return item->getSortVersion() < mTargetSortVersion;
+}
+
+std::string LLFolderViewModelCommon::getStatusText()
+{
+	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter()->getCurrentGeneration())
+	{
+		return LLTrans::getString("Searching");
+	}
+	else
+	{
+		return getFilter()->getEmptyLookupMessage();
+	}
+}
+
+void LLFolderViewModelCommon::filter()
+{
+	getFilter()->setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
+	mFolderView->getViewModelItem()->filter(*getFilter());
+}
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
new file mode 100644
index 0000000000..0f5f9a1f50
--- /dev/null
+++ b/indra/llui/llfolderviewmodel.h
@@ -0,0 +1,353 @@
+/** 
+ * @file llfolderviewmodel.h
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#ifndef LLFOLDERVIEWMODEL_H
+#define LLFOLDERVIEWMODEL_H
+
+#include "llfontgl.h"	// just for StyleFlags enum
+#include "llfolderview.h"
+
+// These are grouping of inventory types.
+// Order matters when sorting system folders to the top.
+enum EInventorySortGroup
+{
+	SG_SYSTEM_FOLDER,
+	SG_TRASH_FOLDER,
+	SG_NORMAL_FOLDER,
+	SG_ITEM
+};
+
+class LLFontGL;
+class LLInventoryModel;
+class LLMenuGL;
+class LLUIImage;
+class LLUUID;
+class LLFolderViewItem;
+class LLFolderViewFolder;
+
+class LLFolderViewFilter
+{
+public:
+	enum EFilterModified
+	{
+		FILTER_NONE,				// nothing to do, already filtered
+		FILTER_RESTART,				// restart filtering from scratch
+		FILTER_LESS_RESTRICTIVE,	// existing filtered items will certainly pass this filter
+		FILTER_MORE_RESTRICTIVE		// if you didn't pass the previous filter, you definitely won't pass this one
+	};
+
+public:
+
+	LLFolderViewFilter() {}
+	virtual ~LLFolderViewFilter() {}
+
+	// +-------------------------------------------------------------------+
+	// + Execution And Results
+	// +-------------------------------------------------------------------+
+	virtual bool 				check(const LLFolderViewModelItem* item) = 0;
+	virtual bool				checkFolder(const LLFolderViewModelItem* folder) const = 0;
+
+	virtual void 				setEmptyLookupMessage(const std::string& message) = 0;
+	virtual std::string			getEmptyLookupMessage() const = 0;
+
+	virtual bool				showAllResults() const = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Status
+	// +-------------------------------------------------------------------+
+	virtual bool 				isActive() const = 0;
+	virtual bool 				isModified() const = 0;
+	virtual void 				clearModified() = 0;
+	virtual const std::string& 	getName() const = 0;
+	virtual const std::string& 	getFilterText() = 0;
+	//RN: this is public to allow system to externally force a global refilter
+	virtual void 				setModified(EFilterModified behavior = FILTER_RESTART) = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Count
+	// +-------------------------------------------------------------------+
+	virtual void 				setFilterCount(S32 count) = 0;
+	virtual S32 				getFilterCount() const = 0;
+	virtual void 				decrementFilterCount() = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Default
+	// +-------------------------------------------------------------------+
+	virtual bool 				isDefault() const = 0;
+	virtual bool 				isNotDefault() const = 0;
+	virtual void 				markDefault() = 0;
+	virtual void 				resetDefault() = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Generation
+	// +-------------------------------------------------------------------+
+	virtual S32 				getCurrentGeneration() const = 0;
+	virtual S32 				getFirstSuccessGeneration() const = 0;
+	virtual S32 				getFirstRequiredGeneration() const = 0;
+};
+
+class LLFolderViewModelInterface
+{
+public:
+	virtual ~LLFolderViewModelInterface() {}
+	virtual void requestSortAll() = 0;
+
+	virtual void sort(class LLFolderViewFolder*) = 0;
+	virtual void filter() = 0;
+
+	virtual bool contentsReady() = 0;
+	virtual void setFolderView(LLFolderView* folder_view) = 0;
+	virtual LLFolderViewFilter* getFilter() = 0;
+	virtual const LLFolderViewFilter* getFilter() const = 0;
+	virtual std::string getStatusText() = 0;
+
+	virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
+};
+
+class LLFolderViewModelCommon : public LLFolderViewModelInterface
+{
+public:
+	LLFolderViewModelCommon()
+	:	mTargetSortVersion(0),
+		mFolderView(NULL)
+	{}
+
+	virtual void requestSortAll()
+	{
+		// sort everything
+		mTargetSortVersion++;
+	}
+	virtual std::string getStatusText();
+	virtual void filter();
+
+	void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
+
+protected:
+	bool needsSort(class LLFolderViewModelItem* item);
+
+	S32 mTargetSortVersion;
+	LLFolderView* mFolderView;
+
+};
+
+template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
+class LLFolderViewModel : public LLFolderViewModelCommon
+{
+public:
+	LLFolderViewModel(){}
+	virtual ~LLFolderViewModel() {}
+	
+	typedef SORT_TYPE		SortType;
+	typedef ITEM_TYPE		ItemType;
+	typedef FOLDER_TYPE		FolderType;
+	typedef FILTER_TYPE		FilterType;
+	
+	virtual SortType& getSorter()					 { return mSorter; }
+	virtual const SortType& getSorter() const 		 { return mSorter; }
+	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
+
+	virtual FilterType* getFilter() 				 { return &mFilter; }
+	virtual const FilterType* getFilter() const		 { return &mFilter; }
+	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
+
+	// TODO RN: remove this and put all filtering logic in view model
+	// add getStatusText and isFiltering()
+	virtual bool contentsReady()					{ return true; }
+
+
+	struct ViewModelCompare
+	{
+		ViewModelCompare(const SortType& sorter)
+		:	mSorter(sorter)
+		{}
+		
+		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		const SortType& mSorter;
+	};
+
+	void sort(LLFolderViewFolder* folder)
+	{
+		if (needsSort(folder->getViewModelItem()))
+		{
+			folder->sortFolders(ViewModelCompare(getSorter()));
+			folder->sortItems(ViewModelCompare(getSorter()));
+			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
+			folder->requestArrange();
+		}
+	}
+
+protected:
+	SortType		mSorter;
+	FilterType		mFilter;
+};
+
+// This is am abstract base class that users of the folderview classes
+// would use to bridge the folder view with the underlying data
+class LLFolderViewModelItem
+{
+public:
+	virtual ~LLFolderViewModelItem( void ) {};
+
+	virtual void update() {}	//called when drawing
+	virtual const std::string& getName() const = 0;
+	virtual const std::string& getDisplayName() const = 0;
+	virtual const std::string& getSearchableName() const = 0;
+
+	virtual LLPointer<LLUIImage> getIcon() const = 0;
+	virtual LLPointer<LLUIImage> getIconOpen() const { return getIcon(); }
+	virtual LLPointer<LLUIImage> getIconOverlay() const { return NULL; }
+
+	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
+	virtual std::string getLabelSuffix() const = 0;
+
+	virtual void openItem( void ) = 0;
+	virtual void closeItem( void ) = 0;
+	virtual void selectItem(void) = 0;
+
+	virtual BOOL isItemRenameable() const = 0;
+	virtual BOOL renameItem(const std::string& new_name) = 0;
+
+	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder
+	virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
+
+	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed
+	virtual BOOL removeItem() = 0;
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
+
+	virtual BOOL isItemCopyable() const = 0;
+	virtual BOOL copyToClipboard() const = 0;
+	virtual BOOL cutToClipboard() const = 0;
+
+	virtual BOOL isClipboardPasteable() const = 0;
+	virtual void pasteFromClipboard() = 0;
+	virtual void pasteLinkFromClipboard() = 0;
+
+	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
+	
+	virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
+
+	virtual bool filter( LLFolderViewFilter& filter) = 0;
+	virtual bool passedFilter(S32 filter_generation = -1) = 0;
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
+	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) = 0;
+	virtual void dirtyFilter() = 0;
+
+	virtual S32	getLastFilterGeneration() const = 0;
+
+	virtual bool hasChildren() const = 0;
+	virtual void addChild(LLFolderViewModelItem* child) = 0;
+	virtual void removeChild(LLFolderViewModelItem* child) = 0;
+
+	// This method will be called to determine if a drop can be
+	// performed, and will set drop to TRUE if a drop is
+	// requested. Returns TRUE if a drop is possible/happened,
+	// otherwise FALSE.
+	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+							EDragAndDropType cargo_type,
+							void* cargo_data,
+							std::string& tooltip_msg) = 0;
+
+	virtual void requestSort() = 0;
+	virtual S32 getSortVersion() = 0;
+	virtual void setSortVersion(S32 version) = 0;
+	virtual void setParent(LLFolderViewModelItem* parent) = 0;
+
+protected:
+
+	friend class LLFolderViewItem;
+	virtual void setFolderViewItem(LLFolderViewItem* folder_view_item) = 0;
+
+};
+
+class LLFolderViewModelItemCommon : public LLFolderViewModelItem
+{
+public:
+	LLFolderViewModelItemCommon()
+	:	mSortVersion(-1),
+		mPassedFilter(true),
+		mPassedFolderFilter(true),
+		mFolderViewItem(NULL),
+		mLastFilterGeneration(-1),
+		mMostFilteredDescendantGeneration(-1),
+		mParent(NULL)
+	{
+		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
+	}
+
+	void requestSort() { mSortVersion = -1; }
+	S32 getSortVersion() { return mSortVersion; }
+	void setSortVersion(S32 version) { mSortVersion = version;}
+
+	S32	getLastFilterGeneration() const { return mLastFilterGeneration; }
+	void dirtyFilter()
+	{
+		mLastFilterGeneration = -1;
+
+		// bubble up dirty flag all the way to root
+		if (mParent)
+		{
+			mParent->dirtyFilter();
+		}	
+	}
+	virtual void addChild(LLFolderViewModelItem* child) 
+	{ 
+		mChildren.push_back(child); 
+		child->setParent(this); 
+	}
+	virtual void removeChild(LLFolderViewModelItem* child) 
+	{ 
+		mChildren.remove(child); 
+		child->setParent(NULL); 
+	}
+
+protected:
+	virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
+
+	S32						mSortVersion;
+	bool					mPassedFilter;
+	bool					mPassedFolderFilter;
+
+	S32						mLastFilterGeneration;
+	S32						mMostFilteredDescendantGeneration;
+
+
+	typedef std::list<LLFolderViewModelItem*> child_list_t;
+	child_list_t			mChildren;
+	LLFolderViewModelItem*	mParent;
+
+	void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
+	LLFolderViewItem*		mFolderViewItem;
+};
+
+
+#endif // LLFOLDERVIEWMODEL_H
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 64bc70da58..b31b99f47c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -253,9 +253,6 @@ set(viewer_SOURCE_FILES
     llfloaterwhitelistentry.cpp
     llfloaterwindowsize.cpp
     llfloaterworldmap.cpp
-    llfolderview.cpp
-    llfolderviewitem.cpp
-    llfolderviewmodel.cpp
     llfolderviewmodelinventory.cpp
     llfollowcam.cpp
     llfriendcard.cpp
@@ -813,10 +810,7 @@ set(viewer_HEADER_FILES
     llfloaterwhitelistentry.h
     llfloaterwindowsize.h
     llfloaterworldmap.h
-    llfolderview.h
-    llfolderviewmodel.h
     llfolderviewmodelinventory.h
-    llfolderviewitem.h
     llfollowcam.h
     llfriendcard.h
     llgesturelistener.h
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
deleted file mode 100644
index 10677db094..0000000000
--- a/indra/newview/llfolderview.cpp
+++ /dev/null
@@ -1,2105 +0,0 @@
-/** 
- * @file llfolderview.cpp
- * @brief Implementation of the folder view collection of classes.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfolderview.h"
-#include "llfolderviewmodel.h"
-#include "llclipboard.h" // *TODO: remove this once hack below gone.
-#include "llkeyboard.h"
-#include "lllineeditor.h"
-#include "llmenugl.h"
-#include "llpanel.h"
-#include "llscrollcontainer.h" // hack to allow scrolling
-#include "lltextbox.h"
-#include "lltrans.h"
-#include "llui.h"
-#include "lluictrlfactory.h"
-
-// Linden library includes
-#include "lldbstrings.h"
-#include "llfocusmgr.h"
-#include "llfontgl.h"
-#include "llgl.h" 
-#include "llrender.h"
-
-// Third-party library includes
-#include <algorithm>
-
-///----------------------------------------------------------------------------
-/// Local function declarations, constants, enums, and typedefs
-///----------------------------------------------------------------------------
-
-const S32 RENAME_WIDTH_PAD = 4;
-const S32 RENAME_HEIGHT_PAD = 1;
-const S32 AUTO_OPEN_STACK_DEPTH = 16;
-const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH
-			+ LLFolderViewItem::ICON_PAD 
-			+ LLFolderViewItem::ARROW_SIZE 
-			+ LLFolderViewItem::TEXT_PAD 
-			+ /*first few characters*/ 40;
-const S32 MINIMUM_RENAMER_WIDTH = 80;
-
-// *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params.
-const S32 STATUS_TEXT_HPAD = 6;
-const S32 STATUS_TEXT_VPAD = 8;
-
-enum {
-	SIGNAL_NO_KEYBOARD_FOCUS = 1,
-	SIGNAL_KEYBOARD_FOCUS = 2
-};
-
-F32 LLFolderView::sAutoOpenTime = 1.f;
-
-//---------------------------------------------------------------------------
-
-// Tells all folders in a folderview to close themselves
-// For efficiency, calls setOpenArrangeRecursively().
-// The calling function must then call:
-//	LLFolderView* root = getRoot();
-//	if( root )
-//	{
-//		root->arrange( NULL, NULL );
-//		root->scrollToShowSelection();
-//	}
-// to patch things up.
-class LLCloseAllFoldersFunctor : public LLFolderViewFunctor
-{
-public:
-	LLCloseAllFoldersFunctor(BOOL close) { mOpen = !close; }
-	virtual ~LLCloseAllFoldersFunctor() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-
-	BOOL mOpen;
-};
-
-
-void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)
-{
-	folder->setOpenArrangeRecursively(mOpen);
-}
-
-// Do nothing.
-void LLCloseAllFoldersFunctor::doItem(LLFolderViewItem* item)
-{ }
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewScrollContainer
-///----------------------------------------------------------------------------
-
-// virtual
-const LLRect LLFolderViewScrollContainer::getScrolledViewRect() const
-{
-	LLRect rect = LLRect::null;
-	if (mScrolledView)
-	{
-		LLFolderView* folder_view = dynamic_cast<LLFolderView*>(mScrolledView);
-		if (folder_view)
-		{
-			S32 height = folder_view->getRect().getHeight();
-
-			rect = mScrolledView->getRect();
-			rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), height);
-		}
-	}
-
-	return rect;
-}
-
-LLFolderViewScrollContainer::LLFolderViewScrollContainer(const LLScrollContainer::Params& p)
-:	LLScrollContainer(p)
-{}
-
-///----------------------------------------------------------------------------
-/// Class LLFolderView
-///----------------------------------------------------------------------------
-LLFolderView::Params::Params()
-:	task_id("task_id"),
-	title("title"),
-	use_label_suffix("use_label_suffix"),
-	allow_multiselect("allow_multiselect", true),
-	show_empty_message("show_empty_message", true),
-	use_ellipses("use_ellipses", false)
-{
-	folder_indentation = -4;
-}
-
-
-// Default constructor
-LLFolderView::LLFolderView(const Params& p)
-:	LLFolderViewFolder(p),
-	mScrollContainer( NULL ),
-	mPopupMenuHandle(),
-	mAllowMultiSelect(p.allow_multiselect),
-	mShowEmptyMessage(p.show_empty_message),
-	mShowFolderHierarchy(FALSE),
-	mSourceID(p.task_id),
-	mRenameItem( NULL ),
-	mNeedsScroll( FALSE ),
-	mUseLabelSuffix(p.use_label_suffix),
-	mPinningSelectedItem(FALSE),
-	mNeedsAutoSelect( FALSE ),
-	mAutoSelectOverride(FALSE),
-	mNeedsAutoRename(FALSE),
-	mShowSelectionContext(FALSE),
-	mShowSingleSelection(FALSE),
-	mArrangeGeneration(0),
-	mSignalSelectCallback(0),
-	mMinWidth(0),
-	mDragAndDropThisFrame(FALSE),
-	mCallbackRegistrar(NULL),
-	mParentPanel(p.parent_panel),
-	mUseEllipses(p.use_ellipses),
-	mDraggingOverItem(NULL),
-	mStatusTextBox(NULL),
-	mShowItemLinkOverlays(p.show_item_link_overlays),
-	mViewModel(p.view_model)
-{
-	mViewModel->setFolderView(this);
-	mRoot = this;
-
-	LLRect rect = p.rect;
-	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
-	setRect( rect );
-	reshape(rect.getWidth(), rect.getHeight());
-	mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH);
-	mAutoOpenCandidate = NULL;
-	mAutoOpenTimer.stop();
-	mKeyboardSelection = FALSE;
-	mIndentation = p.folder_indentation;
-
-	//clear label
-	// go ahead and render root folder as usual
-	// just make sure the label ("Inventory Folder") never shows up
-	mLabel = LLStringUtil::null;
-
-	// Escape is handled by reverting the rename, not commiting it (default behavior)
-	LLLineEditor::Params params;
-	params.name("ren");
-	params.rect(rect);
-	params.font(getLabelFontForStyle(LLFontGL::NORMAL));
-	params.max_length.bytes(DB_INV_ITEM_NAME_STR_LEN);
-	params.commit_callback.function(boost::bind(&LLFolderView::commitRename, this, _2));
-	params.prevalidate_callback(&LLTextValidate::validateASCIIPrintableNoPipe);
-	params.commit_on_focus_lost(true);
-	params.visible(false);
-	mRenamer = LLUICtrlFactory::create<LLLineEditor> (params);
-	addChild(mRenamer);
-
-	// Textbox
-	LLTextBox::Params text_p;
-	LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-	LLRect new_r = LLRect(rect.mLeft + ICON_PAD,
-			      rect.mTop - TEXT_PAD,
-			      rect.mRight,
-			      rect.mTop - TEXT_PAD - font->getLineHeight());
-	text_p.rect(new_r);
-	text_p.name(std::string(p.name));
-	text_p.font(font);
-	text_p.visible(false);
-	text_p.parse_urls(true);
-	text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047
-	// set text padding the same as in People panel. EXT-7047, EXT-4837
-	text_p.h_pad(STATUS_TEXT_HPAD);
-	text_p.v_pad(STATUS_TEXT_VPAD);
-	mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);
-	mStatusTextBox->setFollowsLeft();
-	mStatusTextBox->setFollowsTop();
-	//addChild(mStatusTextBox);
-
-
-	// make the popup menu available
-	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
-	if (!menu)
-	{
-		menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
-	}
-	menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
-	mPopupMenuHandle = menu->getHandle();
-
-	mViewModelItem->openItem();
-}
-
-// Destroys the object
-LLFolderView::~LLFolderView( void )
-{
-	closeRenamer();
-
-	// The release focus call can potentially call the
-	// scrollcontainer, which can potentially be called with a partly
-	// destroyed scollcontainer. Just null it out here, and no worries
-	// about calling into the invalid scroll container.
-	// Same with the renamer.
-	mScrollContainer = NULL;
-	mRenameItem = NULL;
-	mRenamer = NULL;
-	mStatusTextBox = NULL;
-
-	mAutoOpenItems.removeAllNodes();
-
-	if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
-
-	mAutoOpenItems.removeAllNodes();
-	clearSelection();
-	mItems.clear();
-	mFolders.clear();
-
-	delete mViewModel;
-	mViewModel = NULL;
-}
-
-BOOL LLFolderView::canFocusChildren() const
-{
-	return FALSE;
-}
-
-BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
-{
-	LLFolderViewFolder::addFolder(folder);
-
-	// TODO RN: enforce sort order of My Inventory followed by Library
-	//mFolders.remove(folder);
-	//if (((LLFolderViewModelItemInventory*)folder->getViewModelItem())->getUUID() == gInventory.getLibraryRootFolderID())
-	//{
-	//	mFolders.push_back(folder);
-	//}
-	//else
-	//{
-	//	mFolders.insert(mFolders.begin(), folder);
-	//}
-
-	return TRUE;
-}
-
-void LLFolderView::closeAllFolders()
-{
-	// Close all the folders
-	setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
-	arrangeAll();
-}
-
-void LLFolderView::openTopLevelFolders()
-{
-	for (folders_t::iterator iter = mFolders.begin();
-		 iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		(*fit)->setOpen(TRUE);
-	}
-}
-
-// This view grows and shrinks to enclose all of its children items and folders.
-// *width should be 0
-// conform show folder state works
-S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
-{
-	mMinWidth = 0;
-	S32 target_height;
-
-	LLFolderViewFolder::arrange(&mMinWidth, &target_height);
-
-	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
-	reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
-
-	LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
-	if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
-	{
-		reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
-	}
-
-	// move item renamer text field to item's new position
-	updateRenamerPosition();
-
-	return llround(mTargetHeight);
-}
-
-static LLFastTimer::DeclareTimer FTM_FILTER("Filter Folder View");
-
-void LLFolderView::filter( LLFolderViewFilter& filter )
-{
-	LLFastTimer t2(FTM_FILTER);
-	filter.setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
-
-	getViewModelItem()->filter(filter);
-}
-
-void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
-	LLRect scroll_rect;
-	if (mScrollContainer)
-	{
-		LLView::reshape(width, height, called_from_parent);
-		scroll_rect = mScrollContainer->getContentWindowRect();
-	}
-	width = llmax(mMinWidth, scroll_rect.getWidth());
-	height = llmax(llround(mCurHeight), scroll_rect.getHeight());
-
-	// Restrict width within scroll container's width
-	if (mUseEllipses && mScrollContainer)
-	{
-		width = scroll_rect.getWidth();
-	}
-
-	LLView::reshape(width, height, called_from_parent);
-	mReshapeSignal(mSelectedItems, FALSE);
-}
-
-void LLFolderView::addToSelectionList(LLFolderViewItem* item)
-{
-	if (item->isSelected())
-	{
-		removeFromSelectionList(item);
-	}
-	if (mSelectedItems.size())
-	{
-		mSelectedItems.back()->setIsCurSelection(FALSE);
-	}
-	item->setIsCurSelection(TRUE);
-	mSelectedItems.push_back(item);
-}
-
-void LLFolderView::removeFromSelectionList(LLFolderViewItem* item)
-{
-	if (mSelectedItems.size())
-	{
-		mSelectedItems.back()->setIsCurSelection(FALSE);
-	}
-
-	selected_items_t::iterator item_iter;
-	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end();)
-	{
-		if (*item_iter == item)
-		{
-			item_iter = mSelectedItems.erase(item_iter);
-		}
-		else
-		{
-			++item_iter;
-		}
-	}
-	if (mSelectedItems.size())
-	{
-		mSelectedItems.back()->setIsCurSelection(TRUE);
-	}
-}
-
-LLFolderViewItem* LLFolderView::getCurSelectedItem( void )
-{
-	if(mSelectedItems.size())
-	{
-		LLFolderViewItem* itemp = mSelectedItems.back();
-		llassert(itemp->getIsCurSelection());
-		return itemp;
-	}
-	return NULL;
-}
-
-
-// Record the selected item and pass it down the hierachy.
-BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
-								BOOL take_keyboard_focus)
-{
-	mSignalSelectCallback = take_keyboard_focus ? SIGNAL_KEYBOARD_FOCUS : SIGNAL_NO_KEYBOARD_FOCUS;
-
-	if( selection == this )
-	{
-		return FALSE;
-	}
-
-	if( selection && take_keyboard_focus)
-	{
-		mParentPanel->setFocus(TRUE);
-	}
-
-	// clear selection down here because change of keyboard focus can potentially
-	// affect selection
-	clearSelection();
-
-	if(selection)
-	{
-		addToSelectionList(selection);
-	}
-
-	BOOL rv = LLFolderViewFolder::setSelection(selection, openitem, take_keyboard_focus);
-	if(openitem && selection)
-	{
-		selection->getParentFolder()->requestArrange();
-	}
-
-	llassert(mSelectedItems.size() <= 1);
-
-	return rv;
-}
-
-BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
-	BOOL rv = FALSE;
-
-	// can't select root folder
-	if(!selection || selection == this)
-	{
-		return FALSE;
-	}
-
-	if (!mAllowMultiSelect)
-	{
-		clearSelection();
-	}
-
-	selected_items_t::iterator item_iter;
-	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
-	{
-		if (*item_iter == selection)
-		{
-			break;
-		}
-	}
-
-	BOOL on_list = (item_iter != mSelectedItems.end());
-
-	if(selected && !on_list)
-	{
-		addToSelectionList(selection);
-	}
-	if(!selected && on_list)
-	{
-		removeFromSelectionList(selection);
-	}
-
-	rv = LLFolderViewFolder::changeSelection(selection, selected);
-
-	mSignalSelectCallback = SIGNAL_KEYBOARD_FOCUS;
-	
-	return rv;
-}
-
-static LLFastTimer::DeclareTimer FTM_SANITIZE_SELECTION("Sanitize Selection");
-void LLFolderView::sanitizeSelection()
-{
-	LLFastTimer _(FTM_SANITIZE_SELECTION);
-	// store off current item in case it is automatically deselected
-	// and we want to preserve context
-	LLFolderViewItem* original_selected_item = getCurSelectedItem();
-
-	std::vector<LLFolderViewItem*> items_to_remove;
-	selected_items_t::iterator item_iter;
-	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
-	{
-		LLFolderViewItem* item = *item_iter;
-
-		// ensure that each ancestor is open and potentially passes filtering
-		BOOL visible = item->getViewModelItem()->potentiallyVisible(); // initialize from filter state for this item
-		// modify with parent open and filters states
-		LLFolderViewFolder* parent_folder = item->getParentFolder();
-		// Move up through parent folders and see what's visible
-		while(parent_folder)
-		{
-			visible = visible && parent_folder->isOpen() && parent_folder->getViewModelItem()->potentiallyVisible();
-			parent_folder = parent_folder->getParentFolder();
-		}
-
-		//  deselect item if any ancestor is closed or didn't pass filter requirements.
-		if (!visible)
-		{
-			items_to_remove.push_back(item);
-		}
-
-		// disallow nested selections (i.e. folder items plus one or more ancestors)
-		// could check cached mum selections count and only iterate if there are any
-		// but that may be a premature optimization.
-		selected_items_t::iterator other_item_iter;
-		for (other_item_iter = mSelectedItems.begin(); other_item_iter != mSelectedItems.end(); ++other_item_iter)
-		{
-			LLFolderViewItem* other_item = *other_item_iter;
-			for( parent_folder = other_item->getParentFolder(); parent_folder; parent_folder = parent_folder->getParentFolder())
-			{
-				if (parent_folder == item)
-				{
-					// this is a descendent of the current folder, remove from list
-					items_to_remove.push_back(other_item);
-					break;
-				}
-			}
-		}
-
-		// Don't allow invisible items (such as root folders) to be selected.
-		if (item == getRoot())
-		{
-			items_to_remove.push_back(item);
-		}
-	}
-
-	std::vector<LLFolderViewItem*>::iterator item_it;
-	for (item_it = items_to_remove.begin(); item_it != items_to_remove.end(); ++item_it )
-	{
-		changeSelection(*item_it, FALSE); // toggle selection (also removes from list)
-	}
-
-	// if nothing selected after prior constraints...
-	if (mSelectedItems.empty())
-	{
-		// ...select first available parent of original selection
-		LLFolderViewItem* new_selection = NULL;
-		if (original_selected_item)
-		{
-			for(LLFolderViewFolder* parent_folder = original_selected_item->getParentFolder();
-				parent_folder;
-				parent_folder = parent_folder->getParentFolder())
-			{
-				if (parent_folder->getViewModelItem()->potentiallyVisible())
-				{
-					// give initial selection to first ancestor folder that potentially passes the filter
-					if (!new_selection)
-					{
-						new_selection = parent_folder;
-					}
-
-					// if any ancestor folder of original item is closed, move the selection up 
-					// to the highest closed
-					if (!parent_folder->isOpen())
-					{	
-						new_selection = parent_folder;
-					}
-				}
-			}
-		}
-		else
-		{
-			new_selection = NULL;
-		}
-
-		if (new_selection)
-		{
-			setSelection(new_selection, FALSE, FALSE);
-		}
-	}
-}
-
-void LLFolderView::clearSelection()
-{
-	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); 
-		 item_it != mSelectedItems.end(); 
-		 ++item_it)
-	{
-		(*item_it)->setUnselected();
-	}
-
-	mSelectedItems.clear();
-}
-
-std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const
-{
-	std::set<LLFolderViewItem*> selection;
-	std::copy(mSelectedItems.begin(), mSelectedItems.end(), std::inserter(selection, selection.begin()));
-	return selection;
-}
-
-BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source)
-{
-	std::vector<EDragAndDropType> types;
-	uuid_vec_t cargo_ids;
-	selected_items_t::iterator item_it;
-	BOOL can_drag = TRUE;
-	if (!mSelectedItems.empty())
-	{
-		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-		{
-			EDragAndDropType type = DAD_NONE;
-			LLUUID id = LLUUID::null;
-			can_drag = can_drag && (*item_it)->getViewModelItem()->startDrag(&type, &id);
-
-			types.push_back(type);
-			cargo_ids.push_back(id);
-		}
-
-		LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, source, mSourceID); 
-	}
-	return can_drag;
-}
-
-void LLFolderView::commitRename( const LLSD& data )
-{
-	finishRenamingItem();
-}
-
-void LLFolderView::draw()
-{
-	//LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-
-	// if cursor has moved off of me during drag and drop
-	// close all auto opened folders
-	if (!mDragAndDropThisFrame)
-	{
-		closeAutoOpenedFolders();
-	}
-
-	// while dragging, update selection rendering to reflect single/multi drag status
-	if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
-	{
-		EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
-		if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
-		{
-			setShowSingleSelection(TRUE);
-		}
-		else
-		{
-			setShowSingleSelection(FALSE);
-		}
-	}
-	else
-	{
-		setShowSingleSelection(FALSE);
-	}
-
-
-	if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size())
-	{
-		mSearchString.clear();
-	}
-
-	if (hasVisibleChildren())
-	{
-		mStatusTextBox->setVisible( FALSE );
-	}
-	else if (mShowEmptyMessage)
-	{
-		mStatusTextBox->setValue(getFolderViewModel()->getStatusText());
-		mStatusTextBox->setVisible( TRUE );
-		
-		// firstly reshape message textbox with current size. This is necessary to
-		// LLTextBox::getTextPixelHeight works properly
-		const LLRect local_rect = getLocalRect();
-		mStatusTextBox->setShape(local_rect);
-
-		// get preferable text height...
-		S32 pixel_height = mStatusTextBox->getTextPixelHeight();
-		bool height_changed = local_rect.getHeight() != pixel_height;
-		if (height_changed)
-		{
-			// ... if it does not match current height, lets rearrange current view.
-			// This will indirectly call ::arrange and reshape of the status textbox.
-			// We should call this method to also notify parent about required rect.
-			// See EXT-7564, EXT-7047.
-			S32 height = 0;
-			S32 width = 0;
-			S32 total_height = arrange( &width, &height );
-			notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
-
-			LLUI::popMatrix();
-			LLUI::pushMatrix();
-			LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
-		}
-	}
-
-	// skip over LLFolderViewFolder::draw since we don't want the folder icon, label, 
-	// and arrow for the root folder
-	LLView::draw();
-
-	mDragAndDropThisFrame = FALSE;
-}
-
-void LLFolderView::finishRenamingItem( void )
-{
-	if(!mRenamer)
-	{
-		return;
-	}
-	if( mRenameItem )
-	{
-		mRenameItem->rename( mRenamer->getText() );
-	}
-
-	closeRenamer();
-
-	// List is re-sorted alphabetically, so scroll to make sure the selected item is visible.
-	scrollToShowSelection();
-}
-
-void LLFolderView::closeRenamer( void )
-{
-	if (mRenamer && mRenamer->getVisible())
-	{
-		// Triggers onRenamerLost() that actually closes the renamer.
-		LLUI::removePopup(mRenamer);
-	}
-}
-
-bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
-{
-	LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
-
-	if (item_parent)
-	{
-		for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
-		{
-			const LLFolderViewItem* const selected_item = (*it);
-
-			LLFolderViewItem* parent = item_parent;
-
-			while (parent)
-			{
-				if (selected_item == parent)
-				{
-					return true;
-				}
-
-				parent = dynamic_cast<LLFolderViewItem*>(parent->getParent());
-			}
-		}
-	}
-
-	return false;
-}
-
-void LLFolderView::removeSelectedItems()
-{
-	if(getVisible() && getEnabled())
-	{
-		// just in case we're removing the renaming item.
-		mRenameItem = NULL;
-
-		// create a temporary structure which we will use to remove
-		// items, since the removal will futz with internal data
-		// structures.
-		std::vector<LLFolderViewItem*> items;
-		S32 count = mSelectedItems.size();
-		if(count == 0) return;
-		LLFolderViewItem* item = NULL;
-		selected_items_t::iterator item_it;
-		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-		{
-			item = *item_it;
-			if (item && item->isRemovable())
-			{
-				items.push_back(item);
-			}
-			else
-			{
-				llinfos << "Cannot delete " << item->getName() << llendl;
-				return;
-			}
-		}
-
-		// iterate through the new container.
-		count = items.size();
-		LLUUID new_selection_id;
-		if(count == 1)
-		{
-			LLFolderViewItem* item_to_delete = items[0];
-			LLFolderViewFolder* parent = item_to_delete->getParentFolder();
-			LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE);
-			if (!new_selection)
-			{
-				new_selection = item_to_delete->getPreviousOpenNode(FALSE);
-			}
-			if(parent)
-			{
-				if (item_to_delete->remove())
-				{
-					// change selection on successful delete
-					if (new_selection)
-					{
-						getRoot()->setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
-					}
-					else
-					{
-						getRoot()->setSelection(NULL, mParentPanel->hasFocus());
-					}
-				}
-			}
-			arrangeAll();
-		}
-		else if (count > 1)
-		{
-			LLDynamicArray<LLFolderViewModelItem*> listeners;
-			LLFolderViewModelItem* listener;
-			LLFolderViewItem* last_item = items[count - 1];
-			LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
-			while(new_selection && new_selection->isSelected())
-			{
-				new_selection = new_selection->getNextOpenNode(FALSE);
-			}
-			if (!new_selection)
-			{
-				new_selection = last_item->getPreviousOpenNode(FALSE);
-				while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items)))
-				{
-					new_selection = new_selection->getPreviousOpenNode(FALSE);
-				}
-			}
-			if (new_selection)
-			{
-				getRoot()->setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
-			}
-			else
-			{
-				getRoot()->setSelection(NULL, mParentPanel->hasFocus());
-			}
-
-			for(S32 i = 0; i < count; ++i)
-			{
-				listener = items[i]->getViewModelItem();
-				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItem*>::FAIL))
-				{
-					listeners.put(listener);
-				}
-			}
-			listener = static_cast<LLFolderViewModelItem*>(listeners.get(0));
-			if(listener)
-			{
-				listener->removeBatch(listeners);
-			}
-		}
-		arrangeAll();
-		scrollToShowSelection();
-	}
-}
-
-// TODO RN: abstract 
-// open the selected item.
-void LLFolderView::openSelectedItems( void )
-{
-	//TODO RN: get working again
-	//if(getVisible() && getEnabled())
-	//{
-	//	if (mSelectedItems.size() == 1)
-	//	{
-	//		mSelectedItems.front()->openItem();
-	//	}
-	//	else
-	//	{
-	//		LLMultiPreview* multi_previewp = new LLMultiPreview();
-	//		LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-	//		selected_items_t::iterator item_it;
-	//		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-	//		{
-	//			// IT_{OBJECT,ATTACHMENT} creates LLProperties
-	//			// floaters; others create LLPreviews.  Put
-	//			// each one in the right type of container.
-	//			LLFolderViewModelItemInventory* listener = static_cast<LLFolderViewModelItemInventory*>((*item_it)->getViewModelItem());
-	//			bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
-	//			if (is_prop)
-	//				LLFloater::setFloaterHost(multi_propertiesp);
-	//			else
-	//				LLFloater::setFloaterHost(multi_previewp);
-	//			listener->openItem();
-	//		}
-
-	//		LLFloater::setFloaterHost(NULL);
-	//		// *NOTE: LLMulti* will safely auto-delete when open'd
-	//		// without any children.
-	//		multi_previewp->openFloater(LLSD());
-	//		multi_propertiesp->openFloater(LLSD());
-	//	}
-	//}
-}
-
-void LLFolderView::propertiesSelectedItems( void )
-{
-	//TODO RN: get working again
-	//if(getVisible() && getEnabled())
-	//{
-	//	if (mSelectedItems.size() == 1)
-	//	{
-	//		LLFolderViewItem* folder_item = mSelectedItems.front();
-	//		if(!folder_item) return;
-	//		folder_item->getViewModelItem()->showProperties();
-	//	}
-	//	else
-	//	{
-	//		LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-	//		LLFloater::setFloaterHost(multi_propertiesp);
-
-	//		selected_items_t::iterator item_it;
-	//		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-	//		{
-	//			(*item_it)->getViewModelItem()->showProperties();
-	//		}
-
-	//		LLFloater::setFloaterHost(NULL);
-	//		multi_propertiesp->openFloater(LLSD());
-	//	}
-	//}
-}
-
-
-void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
-{
-	if ((mAutoOpenItems.check() == item) || 
-		(mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH) ||
-		item->isOpen())
-	{
-		return;
-	}
-
-	// close auto-opened folders
-	LLFolderViewFolder* close_item = mAutoOpenItems.check();
-	while (close_item && close_item != item->getParentFolder())
-	{
-		mAutoOpenItems.pop();
-		close_item->setOpenArrangeRecursively(FALSE);
-		close_item = mAutoOpenItems.check();
-	}
-
-	item->requestArrange();
-
-	mAutoOpenItems.push(item);
-	
-	item->setOpen(TRUE);
-	LLRect content_rect = mScrollContainer->getContentWindowRect();
-	LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
-	scrollToShowItem(item, constraint_rect);
-}
-
-void LLFolderView::closeAutoOpenedFolders()
-{
-	while (mAutoOpenItems.check())
-	{
-		LLFolderViewFolder* close_item = mAutoOpenItems.pop();
-		close_item->setOpen(FALSE);
-	}
-
-	if (mAutoOpenCandidate)
-	{
-		mAutoOpenCandidate->setAutoOpenCountdown(0.f);
-	}
-	mAutoOpenCandidate = NULL;
-	mAutoOpenTimer.stop();
-}
-
-BOOL LLFolderView::autoOpenTest(LLFolderViewFolder* folder)
-{
-	if (folder && mAutoOpenCandidate == folder)
-	{
-		if (mAutoOpenTimer.getStarted())
-		{
-			if (!mAutoOpenCandidate->isOpen())
-			{
-				mAutoOpenCandidate->setAutoOpenCountdown(clamp_rescale(mAutoOpenTimer.getElapsedTimeF32(), 0.f, sAutoOpenTime, 0.f, 1.f));
-			}
-			if (mAutoOpenTimer.getElapsedTimeF32() > sAutoOpenTime)
-			{
-				autoOpenItem(folder);
-				mAutoOpenTimer.stop();
-				return TRUE;
-			}
-		}
-		return FALSE;
-	}
-
-	// otherwise new candidate, restart timer
-	if (mAutoOpenCandidate)
-	{
-		mAutoOpenCandidate->setAutoOpenCountdown(0.f);
-	}
-	mAutoOpenCandidate = folder;
-	mAutoOpenTimer.start();
-	return FALSE;
-}
-
-BOOL LLFolderView::canCopy() const
-{
-	if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
-	{
-		return FALSE;
-	}
-	
-	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
-	{
-		const LLFolderViewItem* item = *selected_it;
-		if (!item->getViewModelItem()->isItemCopyable())
-		{
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-
-// copy selected item
-void LLFolderView::copy()
-{
-	// *NOTE: total hack to clear the inventory clipboard
-	LLClipboard::instance().reset();
-	S32 count = mSelectedItems.size();
-	if(getVisible() && getEnabled() && (count > 0))
-	{
-		LLFolderViewModelItem* listener = NULL;
-		selected_items_t::iterator item_it;
-		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-		{
-			listener = (*item_it)->getViewModelItem();
-			if(listener)
-			{
-				listener->copyToClipboard();
-			}
-		}
-	}
-	mSearchString.clear();
-}
-
-BOOL LLFolderView::canCut() const
-{
-	if (!(getVisible() && getEnabled() && (mSelectedItems.size() > 0)))
-	{
-		return FALSE;
-	}
-	
-	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
-	{
-		const LLFolderViewItem* item = *selected_it;
-		const LLFolderViewModelItem* listener = item->getViewModelItem();
-
-		if (!listener || !listener->isItemRemovable())
-		{
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-
-void LLFolderView::cut()
-{
-	// clear the inventory clipboard
-	LLClipboard::instance().reset();
-	S32 count = mSelectedItems.size();
-	if(getVisible() && getEnabled() && (count > 0))
-	{
-		LLFolderViewModelItem* listener = NULL;
-		selected_items_t::iterator item_it;
-		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-		{
-			listener = (*item_it)->getViewModelItem();
-			if(listener)
-			{
-				listener->cutToClipboard();
-				listener->removeItem();
-			}
-		}
-	}
-	mSearchString.clear();
-}
-
-BOOL LLFolderView::canPaste() const
-{
-	if (mSelectedItems.empty())
-	{
-		return FALSE;
-	}
-
-	if(getVisible() && getEnabled())
-	{
-		for (selected_items_t::const_iterator item_it = mSelectedItems.begin();
-			 item_it != mSelectedItems.end(); ++item_it)
-		{
-			// *TODO: only check folders and parent folders of items
-			const LLFolderViewItem* item = (*item_it);
-			const LLFolderViewModelItem* listener = item->getViewModelItem();
-			if(!listener || !listener->isClipboardPasteable())
-			{
-				const LLFolderViewFolder* folderp = item->getParentFolder();
-				listener = folderp->getViewModelItem();
-				if (!listener || !listener->isClipboardPasteable())
-				{
-					return FALSE;
-				}
-			}
-		}
-		return TRUE;
-	}
-	return FALSE;
-}
-
-// paste selected item
-void LLFolderView::paste()
-{
-	if(getVisible() && getEnabled())
-	{
-		// find set of unique folders to paste into
-		std::set<LLFolderViewFolder*> folder_set;
-
-		selected_items_t::iterator selected_it;
-		for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
-		{
-			LLFolderViewItem* item = *selected_it;
-			LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(item);
-			if (folder == NULL)
-			{
-				item = item->getParentFolder();
-			}
-			folder_set.insert(folder);
-		}
-
-		std::set<LLFolderViewFolder*>::iterator set_iter;
-		for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)
-		{
-			LLFolderViewModelItem* listener = (*set_iter)->getViewModelItem();
-			if(listener && listener->isClipboardPasteable())
-			{
-				listener->pasteFromClipboard();
-			}
-		}
-	}
-	mSearchString.clear();
-}
-
-// public rename functionality - can only start the process
-void LLFolderView::startRenamingSelectedItem( void )
-{
-	// make sure selection is visible
-	scrollToShowSelection();
-
-	S32 count = mSelectedItems.size();
-	LLFolderViewItem* item = NULL;
-	if(count > 0)
-	{
-		item = mSelectedItems.front();
-	}
-	if(getVisible() && getEnabled() && (count == 1) && item && item->getViewModelItem() &&
-	   item->getViewModelItem()->isItemRenameable())
-	{
-		mRenameItem = item;
-
-		updateRenamerPosition();
-
-
-		mRenamer->setText(item->getName());
-		mRenamer->selectAll();
-		mRenamer->setVisible( TRUE );
-		// set focus will fail unless item is visible
-		mRenamer->setFocus( TRUE );
-		mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
-		LLUI::addPopup(mRenamer);
-	}
-}
-
-BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
-{
-	BOOL handled = FALSE;
-
-	// SL-51858: Key presses are not being passed to the Popup menu.
-	// A proper fix is non-trivial so instead just close the menu.
-	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
-	if (menu && menu->isOpen())
-	{
-		LLMenuGL::sMenuContainer->hideMenus();
-	}
-
-	LLView *item = NULL;
-	if (getChildCount() > 0)
-	{
-		item = *(getChildList()->begin());
-	}
-
-	switch( key )
-	{
-	case KEY_F2:
-		mSearchString.clear();
-		startRenamingSelectedItem();
-		handled = TRUE;
-		break;
-
-	case KEY_RETURN:
-		if (mask == MASK_NONE)
-		{
-			if( mRenameItem && mRenamer->getVisible() )
-			{
-				finishRenamingItem();
-				mSearchString.clear();
-				handled = TRUE;
-			}
-			else
-			{
-				LLFolderView::openSelectedItems();
-				handled = TRUE;
-			}
-		}
-		break;
-
-	case KEY_ESCAPE:
-		if( mRenameItem && mRenamer->getVisible() )
-		{
-			closeRenamer();
-			handled = TRUE;
-		}
-		mSearchString.clear();
-		break;
-
-	case KEY_PAGE_UP:
-		mSearchString.clear();
-		mScrollContainer->pageUp(30);
-		handled = TRUE;
-		break;
-
-	case KEY_PAGE_DOWN:
-		mSearchString.clear();
-		mScrollContainer->pageDown(30);
-		handled = TRUE;
-		break;
-
-	case KEY_HOME:
-		mSearchString.clear();
-		mScrollContainer->goToTop();
-		handled = TRUE;
-		break;
-
-	case KEY_END:
-		mSearchString.clear();
-		mScrollContainer->goToBottom();
-		break;
-
-	case KEY_DOWN:
-		if((mSelectedItems.size() > 0) && mScrollContainer)
-		{
-			LLFolderViewItem* last_selected = getCurSelectedItem();
-
-			if (!mKeyboardSelection)
-			{
-				setSelection(last_selected, FALSE, TRUE);
-				mKeyboardSelection = TRUE;
-			}
-
-			LLFolderViewItem* next = NULL;
-			if (mask & MASK_SHIFT)
-			{
-				// don't shift select down to children of folders (they are implicitly selected through parent)
-				next = last_selected->getNextOpenNode(FALSE);
-				if (next)
-				{
-					if (next->isSelected())
-					{
-						// shrink selection
-						getRoot()->changeSelection(last_selected, FALSE);
-					}
-					else if (last_selected->getParentFolder() == next->getParentFolder())
-					{
-						// grow selection
-						getRoot()->changeSelection(next, TRUE);
-					}
-				}
-			}
-			else
-			{
-				next = last_selected->getNextOpenNode();
-				if( next )
-				{
-					if (next == last_selected)
-					{
-						//special case for LLAccordionCtrl
-						if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
-						{
-							clearSelection();
-							return TRUE;
-						}
-						return FALSE;
-					}
-					setSelection( next, FALSE, TRUE );
-				}
-				else
-				{
-					//special case for LLAccordionCtrl
-					if(notifyParent(LLSD().with("action","select_next")) > 0 )//message was processed
-					{
-						clearSelection();
-						return TRUE;
-					}
-					return FALSE;
-				}
-			}
-			scrollToShowSelection();
-			mSearchString.clear();
-			handled = TRUE;
-		}
-		break;
-
-	case KEY_UP:
-		if((mSelectedItems.size() > 0) && mScrollContainer)
-		{
-			LLFolderViewItem* last_selected = mSelectedItems.back();
-
-			if (!mKeyboardSelection)
-			{
-				setSelection(last_selected, FALSE, TRUE);
-				mKeyboardSelection = TRUE;
-			}
-
-			LLFolderViewItem* prev = NULL;
-			if (mask & MASK_SHIFT)
-			{
-				// don't shift select down to children of folders (they are implicitly selected through parent)
-				prev = last_selected->getPreviousOpenNode(FALSE);
-				if (prev)
-				{
-					if (prev->isSelected())
-					{
-						// shrink selection
-						getRoot()->changeSelection(last_selected, FALSE);
-					}
-					else if (last_selected->getParentFolder() == prev->getParentFolder())
-					{
-						// grow selection
-						getRoot()->changeSelection(prev, TRUE);
-					}
-				}
-			}
-			else
-			{
-				prev = last_selected->getPreviousOpenNode();
-				if( prev )
-				{
-					if (prev == this)
-					{
-						// If case we are in accordion tab notify parent to go to the previous accordion
-						if(notifyParent(LLSD().with("action","select_prev")) > 0 )//message was processed
-						{
-							clearSelection();
-							return TRUE;
-						}
-
-						return FALSE;
-					}
-					setSelection( prev, FALSE, TRUE );
-				}
-			}
-			scrollToShowSelection();
-			mSearchString.clear();
-
-			handled = TRUE;
-		}
-		break;
-
-	case KEY_RIGHT:
-		if(mSelectedItems.size())
-		{
-			LLFolderViewItem* last_selected = getCurSelectedItem();
-			last_selected->setOpen( TRUE );
-			mSearchString.clear();
-			handled = TRUE;
-		}
-		break;
-
-	case KEY_LEFT:
-		if(mSelectedItems.size())
-		{
-			LLFolderViewItem* last_selected = getCurSelectedItem();
-			LLFolderViewItem* parent_folder = last_selected->getParentFolder();
-			if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())
-			{
-				setSelection(parent_folder, FALSE, TRUE);
-			}
-			else
-			{
-				last_selected->setOpen( FALSE );
-			}
-			mSearchString.clear();
-			scrollToShowSelection();
-			handled = TRUE;
-		}
-		break;
-	}
-
-	if (!handled && mParentPanel->hasFocus())
-	{
-		if (key == KEY_BACKSPACE)
-		{
-			mSearchTimer.reset();
-			if (mSearchString.size())
-			{
-				mSearchString.erase(mSearchString.size() - 1, 1);
-			}
-			search(getCurSelectedItem(), mSearchString, FALSE);
-			handled = TRUE;
-		}
-	}
-
-	return handled;
-}
-
-
-BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
-{
-	if ((uni_char < 0x20) || (uni_char == 0x7F)) // Control character or DEL
-	{
-		return FALSE;
-	}
-
-	if (uni_char > 0x7f)
-	{
-		llwarns << "LLFolderView::handleUnicodeCharHere - Don't handle non-ascii yet, aborting" << llendl;
-		return FALSE;
-	}
-
-	BOOL handled = FALSE;
-	if (mParentPanel->hasFocus())
-	{
-		// SL-51858: Key presses are not being passed to the Popup menu.
-		// A proper fix is non-trivial so instead just close the menu.
-		LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
-		if (menu && menu->isOpen())
-		{
-			LLMenuGL::sMenuContainer->hideMenus();
-		}
-
-		//do text search
-		if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout"))
-		{
-			mSearchString.clear();
-		}
-		mSearchTimer.reset();
-		if (mSearchString.size() < 128)
-		{
-			mSearchString += uni_char;
-		}
-		search(getCurSelectedItem(), mSearchString, FALSE);
-
-		handled = TRUE;
-	}
-
-	return handled;
-}
-
-
-BOOL LLFolderView::canDoDelete() const
-{
-	if (mSelectedItems.size() == 0) return FALSE;
-
-	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-	{
-		if (!(*item_it)->getViewModelItem()->isItemRemovable())
-		{
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-
-void LLFolderView::doDelete()
-{
-	if(mSelectedItems.size() > 0)
-	{				
-		removeSelectedItems();
-	}
-}
-
-
-BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
-{
-	mKeyboardSelection = FALSE;
-	mSearchString.clear();
-
-	mParentPanel->setFocus(TRUE);
-
-	LLEditMenuHandler::gEditMenuHandler = this;
-
-	return LLView::handleMouseDown( x, y, mask );
-}
-
-BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward)
-{
-	// get first selected item
-	LLFolderViewItem* search_item = first_item;
-
-	// make sure search string is upper case
-	std::string upper_case_string = search_string;
-	LLStringUtil::toUpper(upper_case_string);
-
-	// if nothing selected, select first item in folder
-	if (!search_item)
-	{
-		// start from first item
-		search_item = getNextFromChild(NULL);
-	}
-
-	// search over all open nodes for first substring match (with wrapping)
-	BOOL found = FALSE;
-	LLFolderViewItem* original_search_item = search_item;
-	do
-	{
-		// wrap at end
-		if (!search_item)
-		{
-			if (backward)
-			{
-				search_item = getPreviousFromChild(NULL);
-			}
-			else
-			{
-				search_item = getNextFromChild(NULL);
-			}
-			if (!search_item || search_item == original_search_item)
-			{
-				break;
-			}
-		}
-
-		const std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
-		S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
-		if (!current_item_label.compare(0, search_string_length, upper_case_string))
-		{
-			found = TRUE;
-			break;
-		}
-		if (backward)
-		{
-			search_item = search_item->getPreviousOpenNode();
-		}
-		else
-		{
-			search_item = search_item->getNextOpenNode();
-		}
-
-	} while(search_item != original_search_item);
-	
-
-	if (found)
-	{
-		setSelection(search_item, FALSE, TRUE);
-		scrollToShowSelection();
-	}
-
-	return found;
-}
-
-BOOL LLFolderView::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
-	// skip LLFolderViewFolder::handleDoubleClick()
-	return LLView::handleDoubleClick( x, y, mask );
-}
-
-BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
-	// all user operations move keyboard focus to inventory
-	// this way, we know when to stop auto-updating a search
-	mParentPanel->setFocus(TRUE);
-
-	BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL;
-	S32 count = mSelectedItems.size();
-	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
-	if (   handled
-		&& ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible
-		&& menu )
-	{
-		if (mCallbackRegistrar)
-			mCallbackRegistrar->pushScope();
-
-		updateMenuOptions(menu);
-	   
-		menu->updateParent(LLMenuGL::sMenuContainer);
-		LLMenuGL::showPopup(this, menu, x, y);
-		if (mCallbackRegistrar)
-			mCallbackRegistrar->popScope();
-	}
-	else
-	{
-		if (menu && menu->getVisible())
-		{
-			menu->setVisible(FALSE);
-		}
-		setSelection(NULL, FALSE, TRUE);
-	}
-	return handled;
-}
-
-// Add "--no options--" if the menu is completely blank.
-BOOL LLFolderView::addNoOptions(LLMenuGL* menu) const
-{
-	const std::string nooptions_str = "--no options--";
-	LLView *nooptions_item = NULL;
-	
-	const LLView::child_list_t *list = menu->getChildList();
-	for (LLView::child_list_t::const_iterator itor = list->begin(); 
-		 itor != list->end(); 
-		 ++itor)
-	{
-		LLView *menu_item = (*itor);
-		if (menu_item->getVisible())
-		{
-			return FALSE;
-		}
-		std::string name = menu_item->getName();
-		if (menu_item->getName() == nooptions_str)
-		{
-			nooptions_item = menu_item;
-		}
-	}
-	if (nooptions_item)
-	{
-		nooptions_item->setVisible(TRUE);
-		nooptions_item->setEnabled(FALSE);
-		return TRUE;
-	}
-	return FALSE;
-}
-
-BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )
-{
-	return LLView::handleHover( x, y, mask );
-}
-
-BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-									 EDragAndDropType cargo_type,
-									 void* cargo_data, 
-									 EAcceptance* accept,
-									 std::string& tooltip_msg)
-{
-	mDragAndDropThisFrame = TRUE;
-	// have children handle it first
-	BOOL handled = LLView::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data,
-											 accept, tooltip_msg);
-
-	// when drop is not handled by child, it should be handled
-	// by the folder which is the hierarchy root.
-	if (!handled)
-	{
-		handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-	}
-
-	return handled;
-}
-
-void LLFolderView::deleteAllChildren()
-{
-	closeRenamer();
-	if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
-	mPopupMenuHandle = LLHandle<LLView>();
-	mScrollContainer = NULL;
-	mRenameItem = NULL;
-	mRenamer = NULL;
-	mStatusTextBox = NULL;
-	
-	clearSelection();
-	LLView::deleteAllChildren();
-}
-
-void LLFolderView::scrollToShowSelection()
-{
-	if ( mSelectedItems.size() )
-	{
-		mNeedsScroll = TRUE;
-	}
-}
-
-// If the parent is scroll container, scroll it to make the selection
-// is maximally visible.
-void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect)
-{
-	if (!mScrollContainer) return;
-
-	// don't scroll to items when mouse is being used to scroll/drag and drop
-	if (gFocusMgr.childHasMouseCapture(mScrollContainer))
-	{
-		mNeedsScroll = FALSE;
-		return;
-	}
-
-	// if item exists and is in visible portion of parent folder...
-	if(item)
-	{
-		LLRect local_rect = item->getLocalRect();
-		LLRect item_scrolled_rect; // item position relative to display area of scroller
-		LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect();
-		
-		S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); 
-		S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight(); 
-		// when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
-		S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight(); 
-		
-		// get portion of item that we want to see...
-		LLRect item_local_rect = LLRect(item->getIndentation(), 
-										local_rect.getHeight(), 
-										llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()), 
-										llmax(0, local_rect.getHeight() - max_height_to_show));
-
-		LLRect item_doc_rect;
-
-		item->localRectToOtherView(item_local_rect, &item_doc_rect, this); 
-
-		mScrollContainer->scrollToShowRect( item_doc_rect, constraint_rect );
-
-	}
-}
-
-LLRect LLFolderView::getVisibleRect()
-{
-	S32 visible_height = mScrollContainer->getRect().getHeight();
-	S32 visible_width = mScrollContainer->getRect().getWidth();
-	LLRect visible_rect;
-	visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height);
-	return visible_rect;
-}
-
-BOOL LLFolderView::getShowSelectionContext()
-{
-	if (mShowSelectionContext)
-	{
-		return TRUE;
-	}
-	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
-	if (menu && menu->getVisible())
-	{
-		return TRUE;
-	}
-	return FALSE;
-}
-
-void LLFolderView::setShowSingleSelection(BOOL show)
-{
-	if (show != mShowSingleSelection)
-	{
-		mMultiSelectionFadeTimer.reset();
-		mShowSingleSelection = show;
-	}
-}
-
-static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
-static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
-
-// Main idle routine
-void LLFolderView::update()
-{
-	// If this is associated with the user's inventory, don't do anything
-	// until that inventory is loaded up.
-	LLFastTimer t2(FTM_INVENTORY);
-
-	if (getFolderViewModel()->getFilter()->isModified() && getFolderViewModel()->getFilter()->isNotDefault())
-	{
-		mNeedsAutoSelect = TRUE;
-	}
-	getFolderViewModel()->getFilter()->clearModified();
-
-	// filter to determine visibility before arranging
-	filter(*(getFolderViewModel()->getFilter()));
-
-	// automatically show matching items, and select first one if we had a selection
-	if (mNeedsAutoSelect)
-	{
-		LLFastTimer t3(FTM_AUTO_SELECT);
-		// select new item only if a filtered item not currently selected
-		LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
-		if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->getViewModelItem()->potentiallyVisible()))
-		{
-			// these are named variables to get around gcc not binding non-const references to rvalues
-			// and functor application is inherently non-const to allow for stateful functors
-			LLSelectFirstFilteredItem functor;
-			applyFunctorRecursively(functor);
-		}
-
-		// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
-		// Used by LLPlacesFolderView.
-		if (getFolderViewModel()->getFilter()->showAllResults())
-		{
-			// these are named variables to get around gcc not binding non-const references to rvalues
-			// and functor application is inherently non-const to allow for stateful functors
-			LLOpenFilteredFolders functor;
-			applyFunctorRecursively(functor);
-		}
-
-		scrollToShowSelection();
-	}
-
-	BOOL filter_finished = getViewModelItem()->passedFilter()
-						&& mViewModel->contentsReady();
-	if (filter_finished 
-		|| gFocusMgr.childHasKeyboardFocus(getParent()) // assume we are inside a scroll container
-		|| gFocusMgr.childHasMouseCapture(getParent()))
-	{
-		// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
-		mNeedsAutoSelect = FALSE;
-	}
-
-
-	// during filtering process, try to pin selected item's location on screen
-	// this will happen when searching your inventory and when new items arrive
-	if (!filter_finished)
-	{
-		// calculate rectangle to pin item to at start of animated rearrange
-		if (!mPinningSelectedItem && !mSelectedItems.empty())
-		{
-			// lets pin it!
-			mPinningSelectedItem = TRUE;
-
-			LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
-			LLFolderViewItem* selected_item = mSelectedItems.back();
-
-			LLRect item_rect;
-			selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
-			// if item is visible in scrolled region
-			if (visible_content_rect.overlaps(item_rect))
-			{
-				// then attempt to keep it in same place on screen
-				mScrollConstraintRect = item_rect;
-				mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
-			}
-			else
-			{
-				// otherwise we just want it onscreen somewhere
-				LLRect content_rect = mScrollContainer->getContentWindowRect();
-				mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
-			}
-		}
-	}
-	else
-	{
-		// stop pinning selected item after folders stop rearranging
-		if (!needsArrange())
-		{
-			mPinningSelectedItem = FALSE;
-		}
-	}
-
-	LLRect constraint_rect;
-	if (mPinningSelectedItem)
-	{
-		// use last known constraint rect for pinned item
-		constraint_rect = mScrollConstraintRect;
-	}
-	else
-	{
-		// during normal use (page up/page down, etc), just try to fit item on screen
-		LLRect content_rect = mScrollContainer->getContentWindowRect();
-		constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
-	}
-
-	BOOL is_visible = isInVisibleChain();
-
-	if ( is_visible )
-	{
-		sanitizeSelection();
-		if( needsArrange() )
-		{
-			S32 height = 0;
-			S32 width = 0;
-			S32 total_height = arrange( &width, &height );
-			notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
-		}
-	}
-
-	if (mSelectedItems.size() && mNeedsScroll)
-	{
-		scrollToShowItem(mSelectedItems.back(), constraint_rect);
-		// continue scrolling until animated layout change is done
-		if (filter_finished
-			&& (!needsArrange() || !is_visible))
-		{
-			mNeedsScroll = FALSE;
-		}
-	}
-
-	if (mSignalSelectCallback)
-	{
-		//RN: we use keyboard focus as a proxy for user-explicit actions
-		BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS);
-		mSelectSignal(mSelectedItems, take_keyboard_focus);
-	}
-	mSignalSelectCallback = FALSE;
-}
-
-void LLFolderView::dumpSelectionInformation()
-{
-	llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
-	llinfos << "****************************************" << llendl;
-	selected_items_t::iterator item_it;
-	for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-	{
-		llinfos << "  " << (*item_it)->getName() << llendl;
-	}
-	llinfos << "****************************************" << llendl;
-}
-
-void LLFolderView::updateRenamerPosition()
-{
-	if(mRenameItem)
-	{
-		// See also LLFolderViewItem::draw()
-		S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mRenameItem->getIndentation();
-		S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
-		mRenameItem->localPointToScreen( x, y, &x, &y );
-		screenPointToLocal( x, y, &x, &y );
-		mRenamer->setOrigin( x, y );
-
-		LLRect scroller_rect(0, 0, LLUI::getWindowSize().mV[VX], 0);
-		if (mScrollContainer)
-		{
-			scroller_rect = mScrollContainer->getContentWindowRect();
-		}
-
-		S32 width = llmax(llmin(mRenameItem->getRect().getWidth() - x, scroller_rect.getWidth() - x - getRect().mLeft), MINIMUM_RENAMER_WIDTH);
-		S32 height = mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
-		mRenamer->reshape( width, height, TRUE );
-	}
-}
-
-// Update visibility and availability (i.e. enabled/disabled) of context menu items.
-void LLFolderView::updateMenuOptions(LLMenuGL* menu)
-{
-	const LLView::child_list_t *list = menu->getChildList();
-
-	LLView::child_list_t::const_iterator menu_itor;
-	for (menu_itor = list->begin(); menu_itor != list->end(); ++menu_itor)
-	{
-		(*menu_itor)->setVisible(FALSE);
-		(*menu_itor)->pushVisible(TRUE);
-		(*menu_itor)->setEnabled(TRUE);
-	}
-
-	// Successively filter out invalid options
-
-	U32 flags = FIRST_SELECTED_ITEM;
-	for (selected_items_t::iterator item_itor = mSelectedItems.begin();
-			item_itor != mSelectedItems.end();
-			++item_itor)
-	{
-		LLFolderViewItem* selected_item = (*item_itor);
-		selected_item->buildContextMenu(*menu, flags);
-		flags = 0x0;
-	}
-
-	addNoOptions(menu);
-}
-
-// Refresh the context menu (that is already shown).
-void LLFolderView::updateMenu()
-{
-	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
-	if (menu && menu->getVisible())
-	{
-		updateMenuOptions(menu);
-		menu->needsArrange(); // update menu height if needed
-	}
-}
-
-bool LLFolderView::selectFirstItem()
-{
-	for (folders_t::iterator iter = mFolders.begin();
-		 iter != mFolders.end();++iter)
-	{
-		LLFolderViewFolder* folder = (*iter );
-		if (folder->getVisible())
-		{
-			LLFolderViewItem* itemp = folder->getNextFromChild(0,true);
-			if(itemp)
-				setSelection(itemp,FALSE,TRUE);
-			return true;	
-		}
-		
-	}
-	for(items_t::iterator iit = mItems.begin();
-		iit != mItems.end(); ++iit)
-	{
-		LLFolderViewItem* itemp = (*iit);
-		if (itemp->getVisible())
-		{
-			setSelection(itemp,FALSE,TRUE);
-			return true;	
-		}
-	}
-	return false;
-}
-bool LLFolderView::selectLastItem()
-{
-	for(items_t::reverse_iterator iit = mItems.rbegin();
-		iit != mItems.rend(); ++iit)
-	{
-		LLFolderViewItem* itemp = (*iit);
-		if (itemp->getVisible())
-		{
-			setSelection(itemp,FALSE,TRUE);
-			return true;	
-		}
-	}
-	for (folders_t::reverse_iterator iter = mFolders.rbegin();
-		 iter != mFolders.rend();++iter)
-	{
-		LLFolderViewFolder* folder = (*iter);
-		if (folder->getVisible())
-		{
-			LLFolderViewItem* itemp = folder->getPreviousFromChild(0,true);
-			if(itemp)
-				setSelection(itemp,FALSE,TRUE);
-			return true;	
-		}
-	}
-	return false;
-}
-
-
-S32	LLFolderView::notify(const LLSD& info) 
-{
-	if(info.has("action"))
-	{
-		std::string str_action = info["action"];
-		if(str_action == "select_first")
-		{
-			setFocus(true);
-			selectFirstItem();
-			scrollToShowSelection();
-			return 1;
-
-		}
-		else if(str_action == "select_last")
-		{
-			setFocus(true);
-			selectLastItem();
-			scrollToShowSelection();
-			return 1;
-		}
-	}
-	return 0;
-}
-
-
-///----------------------------------------------------------------------------
-/// Local function definitions
-///----------------------------------------------------------------------------
-
-void LLFolderView::onRenamerLost()
-{
-	if (mRenamer && mRenamer->getVisible())
-	{
-		mRenamer->setVisible(FALSE);
-
-		// will commit current name (which could be same as original name)
-		mRenamer->setFocus(FALSE);
-	}
-
-	if( mRenameItem )
-	{
-		setSelection( mRenameItem, TRUE );
-		mRenameItem = NULL;
-	}
-}
-
-S32 LLFolderView::getItemHeight()
-{
-	if(!hasVisibleChildren())
-	{
-		//We need to display status textbox, let's reserve some place for it
-		return llmax(0, mStatusTextBox->getTextPixelHeight());
-	}
-	return 0;
-}
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
deleted file mode 100644
index 78f1d8aff2..0000000000
--- a/indra/newview/llfolderview.h
+++ /dev/null
@@ -1,393 +0,0 @@
-/** 
- * @file llfolderview.h
- * @brief Definition of the folder view collection of classes.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-/**
- *
- * The folder view collection of classes provides an interface for
- * making a 'folder view' similar to the way the a single pane file
- * folder interface works.
- *
- */
-
-#ifndef LL_LLFOLDERVIEW_H
-#define LL_LLFOLDERVIEW_H
-
-#include "llfolderviewitem.h"	// because LLFolderView is-a LLFolderViewFolder
-
-#include "lluictrl.h"
-#include "v4color.h"
-#include "stdenums.h"
-#include "lldepthstack.h"
-#include "lleditmenuhandler.h"
-#include "llfontgl.h"
-#include "llscrollcontainer.h"
-#include "lltooldraganddrop.h"
-
-class LLFolderViewModelInterface;
-class LLFolderViewFolder;
-class LLFolderViewItem;
-class LLFolderViewFilter;
-class LLPanel;
-class LLLineEditor;
-class LLMenuGL;
-class LLUICtrl;
-class LLTextBox;
-
-/**
- * Class LLFolderViewScrollContainer
- *
- * A scroll container which provides the information about the height
- * of currently displayed folder view contents.
- * Used for updating vertical scroll bar visibility in inventory panel.
- * See LLScrollContainer::calcVisibleSize().
- */
-class LLFolderViewScrollContainer : public LLScrollContainer
-{
-public:
-	/*virtual*/ ~LLFolderViewScrollContainer() {};
-	/*virtual*/ const LLRect getScrolledViewRect() const;
-
-protected:
-	LLFolderViewScrollContainer(const LLScrollContainer::Params& p);
-	friend class LLUICtrlFactory;
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderView
-//
-// The LLFolderView represents the root level folder view object. 
-// It manages the screen region of the folder view.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
-	{
-		Mandatory<LLPanel*>	    parent_panel;
-		Optional<LLUUID>        task_id;
-		Optional<std::string>   title;
-		Optional<bool>			use_label_suffix,
-								allow_multiselect,
-								show_empty_message,
-								use_ellipses,
-								show_item_link_overlays;
-		Mandatory<LLFolderViewModelInterface*>	view_model;
-
-		Params();
-	};
-
-	friend class LLFolderViewScrollContainer;
-
-	LLFolderView(const Params&);
-	virtual ~LLFolderView( void );
-
-	virtual BOOL canFocusChildren() const;
-
-	virtual const LLFolderView*	getRoot() const { return this; }
-	virtual LLFolderView*	getRoot() { return this; }
-
-	LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; }
-	const LLFolderViewModelInterface* getFolderViewModel() const { return mViewModel; }
-
-	void setFilterPermMask(PermissionMask filter_perm_mask);
-	
-	typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
-	void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
-	void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
-	
-	bool getAllowMultiSelect() { return mAllowMultiSelect; }
-
-	// Close all folders in the view
-	void closeAllFolders();
-	void openTopLevelFolders();
-
-	virtual BOOL addFolder( LLFolderViewFolder* folder);
-
-	// Find width and height of this object and its children. Also
-	// makes sure that this view and its children are the right size.
-	virtual S32 arrange( S32* width, S32* height );
-	virtual S32 getItemHeight();
-
-	void arrangeAll() { mArrangeGeneration++; }
-	S32 getArrangeGeneration() { return mArrangeGeneration; }
-
-	// applies filters to control visibility of items
-	virtual void filter( LLFolderViewFilter& filter);
-
-	// Get the last selected item
-	virtual LLFolderViewItem* getCurSelectedItem( void );
-
-	// Record the selected item and pass it down the hierarchy.
-	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
-		BOOL take_keyboard_focus = TRUE);
-
-	// This method is used to toggle the selection of an item. Walks
-	// children, and keeps track of selected objects.
-	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
-	virtual std::set<LLFolderViewItem*> getSelectionList() const;
-	S32 getNumSelectedItems() { return mSelectedItems.size(); }
-
-	// Make sure if ancestor is selected, descendants are not
-	void sanitizeSelection();
-	virtual void clearSelection();
-	void addToSelectionList(LLFolderViewItem* item);
-	void removeFromSelectionList(LLFolderViewItem* item);
-
-	BOOL startDrag(LLToolDragAndDrop::ESource source);
-	void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
-	void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
-	LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
-
-	// Deletion functionality
- 	void removeSelectedItems();
-
-	// Open the selected item
-	void openSelectedItems( void );
-	void propertiesSelectedItems( void );
-
-	void autoOpenItem(LLFolderViewFolder* item);
-	void closeAutoOpenedFolders();
-	BOOL autoOpenTest(LLFolderViewFolder* item);
-	BOOL isOpen() const { return TRUE; } // root folder always open
-
-	// Copy & paste
-	virtual void	copy();
-	virtual BOOL	canCopy() const;
-
-	virtual void	cut();
-	virtual BOOL	canCut() const;
-
-	virtual void	paste();
-	virtual BOOL	canPaste() const;
-
-	virtual void	doDelete();
-	virtual BOOL	canDoDelete() const;
-
-	// Public rename functionality - can only start the process
-	void startRenamingSelectedItem( void );
-
-	// LLView functionality
-	///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
-	/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
-	/*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char);
-	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
-	/*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
-	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
-	/*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
-	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-								   EDragAndDropType cargo_type,
-								   void* cargo_data,
-								   EAcceptance* accept,
-								   std::string& tooltip_msg);
-	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
-	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) { setShowSelectionContext(FALSE); }
-	virtual void draw();
-	virtual void deleteAllChildren();
-
-	void scrollToShowSelection();
-	void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
-	void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
-	LLRect getVisibleRect();
-
-	BOOL search(LLFolderViewItem* first_item, const std::string &search_string, BOOL backward);
-	void setShowSelectionContext(BOOL show) { mShowSelectionContext = show; }
-	BOOL getShowSelectionContext();
-	void setShowSingleSelection(BOOL show);
-	BOOL getShowSingleSelection() { return mShowSingleSelection; }
-	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
-	bool getUseEllipses() { return mUseEllipses; }
-
-	void	update();						// needs to be called periodically (e.g. once per frame)
-
-	BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
-	BOOL needsAutoRename() { return mNeedsAutoRename; }
-	void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
-	void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
-	void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
-
-	bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
-
-	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
-
-	LLPanel* getParentPanel() { return mParentPanel; }
-	// DEBUG only
-	void dumpSelectionInformation();
-
-	virtual S32	notify(const LLSD& info) ;
-	
-	bool useLabelSuffix() { return mUseLabelSuffix; }
-	void updateMenu();
-
-private:
-	void updateMenuOptions(LLMenuGL* menu);
-	void updateRenamerPosition();
-
-protected:
-	LLScrollContainer* mScrollContainer;  // NULL if this is not a child of a scroll container.
-
-	void commitRename( const LLSD& data );
-	void onRenamerLost();
-
-	void finishRenamingItem( void );
-	void closeRenamer( void );
-
-	bool selectFirstItem();
-	bool selectLastItem();
-	
-	BOOL addNoOptions(LLMenuGL* menu) const;
-
-
-protected:
-	LLHandle<LLView>					mPopupMenuHandle;
-	
-	typedef std::deque<LLFolderViewItem*> selected_items_t;
-	selected_items_t				mSelectedItems;
-	BOOL							mKeyboardSelection;
-	BOOL							mAllowMultiSelect;
-	BOOL							mShowEmptyMessage;
-	BOOL							mShowFolderHierarchy;
-	LLUUID							mSourceID;
-
-	// Renaming variables and methods
-	LLFolderViewItem*				mRenameItem;  // The item currently being renamed
-	LLLineEditor*					mRenamer;
-
-	BOOL							mNeedsScroll;
-	BOOL							mPinningSelectedItem;
-	LLRect							mScrollConstraintRect;
-	BOOL							mNeedsAutoSelect;
-	BOOL							mAutoSelectOverride;
-	BOOL							mNeedsAutoRename;
-	bool							mUseLabelSuffix;
-	bool							mShowItemLinkOverlays;
-	
-	LLDepthStack<LLFolderViewFolder>	mAutoOpenItems;
-	LLFolderViewFolder*				mAutoOpenCandidate;
-	LLFrameTimer					mAutoOpenTimer;
-	LLFrameTimer					mSearchTimer;
-	std::string						mSearchString;
-	BOOL							mShowSelectionContext;
-	BOOL							mShowSingleSelection;
-	LLFrameTimer					mMultiSelectionFadeTimer;
-	S32								mArrangeGeneration;
-
-	signal_t						mSelectSignal;
-	signal_t						mReshapeSignal;
-	S32								mSignalSelectCallback;
-	S32								mMinWidth;
-	BOOL							mDragAndDropThisFrame;
-	
-	LLPanel*						mParentPanel;
-	
-	LLFolderViewModelInterface*		mViewModel;
-
-	/**
-	 * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
-	 * NOTE: For now it's used only to cut LLFolderViewItem::mLabel text for Landmarks in Places Panel.
-	 */
-	bool							mUseEllipses; // See EXT-719
-
-	/**
-	 * Contains item under mouse pointer while dragging
-	 */
-	LLFolderViewItem*				mDraggingOverItem; // See EXT-719
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;
-	
-public:
-	static F32 sAutoOpenTime;
-	LLTextBox*						mStatusTextBox;
-
-};
-
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFunctor
-//
-// Simple abstract base class for applying a functor to folders and
-// items in a folder view hierarchy. This is suboptimal for algorithms
-// that only work folders or only work on items, but I'll worry about
-// that later when it's determined to be too slow.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLFolderViewFunctor
-{
-public:
-	virtual ~LLFolderViewFunctor() {}
-	virtual void doFolder(LLFolderViewFolder* folder) = 0;
-	virtual void doItem(LLFolderViewItem* item) = 0;
-};
-
-class LLSelectFirstFilteredItem : public LLFolderViewFunctor
-{
-public:
-	LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
-	virtual ~LLSelectFirstFilteredItem() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-	BOOL wasItemSelected() { return mItemSelected; }
-protected:
-	BOOL mItemSelected;
-};
-
-class LLOpenFilteredFolders : public LLFolderViewFunctor
-{
-public:
-	LLOpenFilteredFolders()  {}
-	virtual ~LLOpenFilteredFolders() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-};
-
-class LLSaveFolderState : public LLFolderViewFunctor
-{
-public:
-	LLSaveFolderState() : mApply(FALSE) {}
-	virtual ~LLSaveFolderState() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item) {}
-	void setApply(BOOL apply);
-	void clearOpenFolders() { mOpenFolders.clear(); }
-protected:
-	std::set<LLUUID> mOpenFolders;
-	BOOL mApply;
-};
-
-class LLOpenFoldersWithSelection : public LLFolderViewFunctor
-{
-public:
-	LLOpenFoldersWithSelection() {}
-	virtual ~LLOpenFoldersWithSelection() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-};
-
-// Flags for buildContextMenu()
-const U32 SUPPRESS_OPEN_ITEM = 0x1;
-const U32 FIRST_SELECTED_ITEM = 0x2;
-
-#endif // LL_LLFOLDERVIEW_H
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
deleted file mode 100644
index dee3fe7218..0000000000
--- a/indra/newview/llfolderviewitem.cpp
+++ /dev/null
@@ -1,2060 +0,0 @@
-/** 
-* @file llfolderviewitem.cpp
-* @brief Items and folders that can appear in a hierarchical folder view
-*
-* $LicenseInfo:firstyear=2001&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-* 
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-* 
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-* 
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-* 
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-* $/LicenseInfo$
-*/
-#include "llviewerprecompiledheaders.h"
-
-#include "llfolderviewitem.h"
-
-// viewer includes
-#include "llfolderview.h"
-#include "llfolderviewmodel.h"
-#include "llpanel.h"
-
-// linden library includes
-#include "llclipboard.h"
-#include "llfocusmgr.h"		// gFocusMgr
-#include "lltrans.h"
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewItem
-///----------------------------------------------------------------------------
-
-static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
-
-// statics 
-std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
-
-// only integers can be initialized in header
-const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
-const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
-
-const LLColor4U DEFAULT_WHITE(255, 255, 255);
-
-
-//static
-LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
-{
-	LLFontGL* rtn = sFonts[style];
-	if (!rtn) // grab label font with this style, lazily
-	{
-		LLFontDescriptor labelfontdesc("SansSerif", "Small", style);
-		rtn = LLFontGL::getFont(labelfontdesc);
-		if (!rtn)
-		{
-			rtn = LLFontGL::getFontDefault();
-		}
-		sFonts[style] = rtn;
-	}
-	return rtn;
-}
-
-//static
-void LLFolderViewItem::initClass()
-{
-}
-
-//static
-void LLFolderViewItem::cleanupClass()
-{
-	sFonts.clear();
-}
-
-
-// NOTE: Optimize this, we call it a *lot* when opening a large inventory
-LLFolderViewItem::Params::Params()
-:	root(),
-	listener(),
-	folder_arrow_image("folder_arrow_image"),
-	folder_indentation("folder_indentation"),
-	selection_image("selection_image"),
-	item_height("item_height"),
-	item_top_pad("item_top_pad"),
-	creation_date()
-{}
-
-// Default constructor
-LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
-:	LLView(p),
-	mLabelWidth(0),
-	mLabelWidthDirty(false),
-	mParentFolder( NULL ),
-	mIsSelected( FALSE ),
-	mIsCurSelection( FALSE ),
-	mSelectPending(FALSE),
-	mLabelStyle( LLFontGL::NORMAL ),
-	mHasVisibleChildren(FALSE),
-	mIndentation(0),
-	mItemHeight(p.item_height),
-	//TODO RN: create interface for string highlighting
-	//mStringMatchOffset(std::string::npos),
-	mControlLabelRotation(0.f),
-	mDragAndDropTarget(FALSE),
-	mLabel(p.name),
-	mRoot(p.root),
-	mViewModelItem(p.listener),
-	mIsMouseOverTitle(false)
-{
-	if (mViewModelItem)
-	{
-		mViewModelItem->setFolderViewItem(this);
-	}
-}
-
-BOOL LLFolderViewItem::postBuild()
-{
-	refresh();
-	return TRUE;
-}
-
-// Destroys the object
-LLFolderViewItem::~LLFolderViewItem( void )
-{
-	delete mViewModelItem;
-	mViewModelItem = NULL;
-}
-
-LLFolderView* LLFolderViewItem::getRoot()
-{
-	return mRoot;
-}
-
-const LLFolderView* LLFolderViewItem::getRoot() const
-{
-	return mRoot;
-}
-// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
-BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
-{
-	LLFolderViewItem* root = this;
-	while( root->mParentFolder )
-	{
-		if( root->mParentFolder == potential_ancestor )
-		{
-			return TRUE;
-		}
-		root = root->mParentFolder;
-	}
-	return FALSE;
-}
-
-LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
-{
-	if (!mParentFolder)
-	{
-		return NULL;
-	}
-
-	LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
-	while(itemp && !itemp->getVisible())
-	{
-		LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
-		if (itemp == next_itemp) 
-		{
-			// hit last item
-			return itemp->getVisible() ? itemp : this;
-		}
-		itemp = next_itemp;
-	}
-
-	return itemp;
-}
-
-LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
-{
-	if (!mParentFolder)
-	{
-		return NULL;
-	}
-
-	LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
-
-	// Skip over items that are invisible or are hidden from the UI.
-	while(itemp && !itemp->getVisible())
-	{
-		LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
-		if (itemp == next_itemp) 
-		{
-			// hit first item
-			return itemp->getVisible() ? itemp : this;
-		}
-		itemp = next_itemp;
-	}
-
-	return itemp;
-}
-
-BOOL LLFolderViewItem::passedFilter(S32 filter_generation) 
-{
-	return getViewModelItem()->passedFilter(filter_generation);
-}
-
-void LLFolderViewItem::refresh()
-{ 
-	LLFolderViewModelItem& vmi = *getViewModelItem();
-
-	mLabel = vmi.getDisplayName();
-
-	setToolTip(mLabel);
-	mIcon = vmi.getIcon();
-	mIconOpen = vmi.getIconOpen();
-	mIconOverlay = vmi.getIconOverlay();
-
-	if (mRoot->useLabelSuffix())
-	{
-		mLabelStyle = vmi.getLabelStyle();
-		mLabelSuffix = vmi.getLabelSuffix();
-	}
-
-	//TODO RN: make sure this logic still fires
-	//std::string searchable_label(mLabel);
-	//searchable_label.append(mLabelSuffix);
-	//LLStringUtil::toUpper(searchable_label);
-
-	//if (mSearchableLabel.compare(searchable_label))
-	//{
-	//	mSearchableLabel.assign(searchable_label);
-	//	vmi.dirtyFilter();
-	//	// some part of label has changed, so overall width has potentially changed, and sort order too
-	//	if (mParentFolder)
-	//	{
-	//		mParentFolder->requestSort();
-	//		mParentFolder->requestArrange();
-	//	}
-	//}
-
-	mLabelWidthDirty = true;
-	vmi.dirtyFilter();
-}
-
-// Utility function for LLFolderView
-void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
-									 BOOL take_keyboard_focus)
-{
-	LLFolderView* root = getRoot();
-	if (getParentFolder())
-	{
-		getParentFolder()->requestArrange();
-	}
-	if(set_selection)
-	{
-		getRoot()->setSelection(this, TRUE, take_keyboard_focus);
-		if(root)
-		{
-			root->scrollToShowSelection();
-		}
-	}		
-}
-
-
-std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const
-{
-	std::set<LLFolderViewItem*> selection;
-	return selection;
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
-{
-	return folder->addItem(this);
-}
-
-
-// Finds width and height of this object and its children.  Also
-// makes sure that this view and its children are the right size.
-S32 LLFolderViewItem::arrange( S32* width, S32* height )
-{
-	const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-	S32 indentation = p.folder_indentation();
-	// Only indent deeper items in hierarchy
-	mIndentation = (getParentFolder())
-		? getParentFolder()->getIndentation() + indentation
-		: 0;
-	if (mLabelWidthDirty)
-	{
-		mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + TEXT_PAD_RIGHT; 
-		mLabelWidthDirty = false;
-	}
-
-	*width = llmax(*width, mLabelWidth + mIndentation); 
-
-	// determine if we need to use ellipses to avoid horizontal scroll. EXT-719
-	bool use_ellipses = getRoot()->getUseEllipses();
-	if (use_ellipses)
-	{
-		// limit to set rect to avoid horizontal scrollbar
-		*width = llmin(*width, getRoot()->getRect().getWidth());
-	}
-	*height = getItemHeight();
-	return *height;
-}
-
-S32 LLFolderViewItem::getItemHeight()
-{
-	return mItemHeight;
-}
-
-// *TODO: This can be optimized a lot by simply recording that it is
-// selected in the appropriate places, and assuming that set selection
-// means 'deselect' for a leaf item. Do this optimization after
-// multiple selection is implemented to make sure it all plays nice
-// together.
-BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
-{
-	if (selection == this && !mIsSelected)
-	{
-		selectItem();
-	}
-	else if (mIsSelected)	// Deselect everything else.
-	{
-		deselectItem();
-	}
-	return mIsSelected;
-}
-
-BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
-	if (selection == this)
-	{
-		if (mIsSelected)
-		{
-			deselectItem();
-		}
-		else
-		{
-			selectItem();
-		}
-		return TRUE;
-	}
-	return FALSE;
-}
-
-void LLFolderViewItem::deselectItem(void)
-{
-	mIsSelected = FALSE;
-}
-
-void LLFolderViewItem::selectItem(void)
-{
-	if (mIsSelected == FALSE)
-	{
-		getViewModelItem()->selectItem();
-		mIsSelected = TRUE;
-	}
-}
-
-BOOL LLFolderViewItem::isMovable()
-{
-	return getViewModelItem()->isItemMovable();
-}
-
-BOOL LLFolderViewItem::isRemovable()
-{
-	return getViewModelItem()->isItemRemovable();
-}
-
-void LLFolderViewItem::destroyView()
-{
-	getRoot()->removeFromSelectionList(this);
-
-	if (mParentFolder)
-	{
-		// removeView deletes me
-		mParentFolder->extractItem(this);
-	}
-	delete this;
-}
-
-// Call through to the viewed object and return true if it can be
-// removed.
-//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
-BOOL LLFolderViewItem::remove()
-{
-	if(!isRemovable())
-	{
-		return FALSE;
-	}
-	return getViewModelItem()->removeItem();
-}
-
-// Build an appropriate context menu for the item.
-void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
-	getViewModelItem()->buildContextMenu(menu, flags);
-}
-
-void LLFolderViewItem::openItem( void )
-{
-	getViewModelItem()->openItem();
-}
-
-void LLFolderViewItem::rename(const std::string& new_name)
-{
-	if( !new_name.empty() )
-	{
-		getViewModelItem()->renameItem(new_name);
-
-			if(mParentFolder)
-			{
-				mParentFolder->requestSort();
-			}
-		}
-	}
-
-const std::string& LLFolderViewItem::getName( void ) const
-{
-	return getViewModelItem()->getName();
-}
-
-// LLView functionality
-BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
-	if(!mIsSelected)
-	{
-		getRoot()->setSelection(this, FALSE);
-	}
-	make_ui_sound("UISndClick");
-	return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
-{
-	if (LLView::childrenHandleMouseDown(x, y, mask))
-	{
-		return TRUE;
-	}
-	
-	// No handler needed for focus lost since this class has no
-	// state that depends on it.
-	gFocusMgr.setMouseCapture( this );
-
-	if (!mIsSelected)
-	{
-		if(mask & MASK_CONTROL)
-		{
-			getRoot()->changeSelection(this, !mIsSelected);
-		}
-		else if (mask & MASK_SHIFT)
-		{
-			getParentFolder()->extendSelectionTo(this);
-		}
-		else
-		{
-			getRoot()->setSelection(this, FALSE);
-		}
-		make_ui_sound("UISndClick");
-	}
-	else
-	{
-		mSelectPending = TRUE;
-	}
-
-	if( isMovable() )
-	{
-		S32 screen_x;
-		S32 screen_y;
-		localPointToScreen(x, y, &screen_x, &screen_y );
-		LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y );
-	}
-	return TRUE;
-}
-
-BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
-{
-	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
-
-	if( hasMouseCapture() && isMovable() )
-	{
-		S32 screen_x;
-		S32 screen_y;
-		localPointToScreen(x, y, &screen_x, &screen_y );
-		BOOL can_drag = TRUE;
-		if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
-		{
-			LLFolderView* root = getRoot();
-
-			if(root->getCurSelectedItem())
-			{
-				LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD;
-
-				// *TODO: push this into listener and remove
-				// dependency on llagent
-				src = getViewModelItem()->getDragSource();
-
-				can_drag = root->startDrag(src);
-				if (can_drag)
-				{
-					// if (getViewModelItem()) getViewModelItem()->startDrag();
-					// RN: when starting drag and drop, clear out last auto-open
-					root->autoOpenTest(NULL);
-					root->setShowSelectionContext(TRUE);
-
-					// Release keyboard focus, so that if stuff is dropped into the
-					// world, pressing the delete key won't blow away the inventory
-					// item.
-					gFocusMgr.setKeyboardFocus(NULL);
-
-					return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
-				}
-			}
-		}
-
-		if (can_drag)
-		{
-			getWindow()->setCursor(UI_CURSOR_ARROW);
-		}
-		else
-		{
-			getWindow()->setCursor(UI_CURSOR_NOLOCKED);
-		}
-		return TRUE;
-	}
-	else
-	{
-		if (getRoot())
-		{
-			getRoot()->setShowSelectionContext(FALSE);
-		}
-		getWindow()->setCursor(UI_CURSOR_ARROW);
-		// let parent handle this then...
-		return FALSE;
-	}
-}
-
-
-BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
-	getViewModelItem()->openItem();
-	return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
-{
-	if (LLView::childrenHandleMouseUp(x, y, mask))
-	{
-		return TRUE;
-	}
-	
-	// if mouse hasn't moved since mouse down...
-	if ( pointInView(x, y) && mSelectPending )
-	{
-		//...then select
-		if(mask & MASK_CONTROL)
-		{
-			getRoot()->changeSelection(this, !mIsSelected);
-		}
-		else if (mask & MASK_SHIFT)
-		{
-			getParentFolder()->extendSelectionTo(this);
-		}
-		else
-		{
-			getRoot()->setSelection(this, FALSE);
-		}
-	}
-
-	mSelectPending = FALSE;
-
-	if( hasMouseCapture() )
-	{
-		if (getRoot())
-		{
-		getRoot()->setShowSelectionContext(FALSE);
-		}
-		gFocusMgr.setMouseCapture( NULL );
-	}
-	return TRUE;
-}
-
-void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	mIsMouseOverTitle = false;
-}
-
-BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-										 EDragAndDropType cargo_type,
-										 void* cargo_data,
-										 EAcceptance* accept,
-										 std::string& tooltip_msg)
-{
-	BOOL handled = FALSE;
-	BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
-		handled = accepted;
-		if (accepted)
-		{
-			mDragAndDropTarget = TRUE;
-			*accept = ACCEPT_YES_MULTI;
-		}
-		else
-		{
-			*accept = ACCEPT_NO;
-		}
-	if(mParentFolder && !handled)
-	{
-		// store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event.
-		mRoot->setDraggingOverItem(this);
-		handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
-		mRoot->setDraggingOverItem(NULL);
-	}
-	if (handled)
-	{
-		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
-	}
-
-	return handled;
-}
-
-void LLFolderViewItem::draw()
-{
-	static LLUIColor sFgColor 			= LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightBgColor 	= LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightFgColor 	= LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
-	static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
-	static LLUIColor sFilterBGColor 	= LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
-	static LLUIColor sFilterTextColor 	= LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
-	static LLUIColor sSuffixColor 		= LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
-	static LLUIColor sLibraryColor 		= LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
-	static LLUIColor sLinkColor 		= LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
-	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
-	static LLUIColor sMouseOverColor 	= LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
-
-	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-	const S32 TOP_PAD = default_params.item_top_pad;
-	const S32 FOCUS_LEFT = 1;
-	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-
-	getViewModelItem()->update();
-
-	//--------------------------------------------------------------------------------//
-	// Draw open folder arrow
-	//
-	if (hasVisibleChildren() || getViewModelItem()->hasChildren())
-	{
-		LLUIImage* arrow_image = default_params.folder_arrow_image;
-		gl_draw_scaled_rotated_image(
-			mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
-			ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
-	}
-
-
-	//--------------------------------------------------------------------------------//
-	// Draw highlight for selected items
-	//
-	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
-	const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
-	const S32 focus_top = getRect().getHeight();
-	const S32 focus_bottom = getRect().getHeight() - mItemHeight;
-	const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
-	if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		LLColor4 bg_color = sHighlightBgColor;
-		if (!mIsCurSelection)
-		{
-			// do time-based fade of extra objects
-			F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
-			if (getRoot() && getRoot()->getShowSingleSelection())
-			{
-				// fading out
-				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
-			}
-			else
-			{
-				// fading in
-				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
-			}
-		}
-		gl_rect_2d(FOCUS_LEFT,
-				   focus_top, 
-				   getRect().getWidth() - 2,
-				   focus_bottom,
-				   bg_color, filled);
-		if (mIsCurSelection)
-		{
-			gl_rect_2d(FOCUS_LEFT, 
-					   focus_top, 
-					   getRect().getWidth() - 2,
-					   focus_bottom,
-					   sFocusOutlineColor, FALSE);
-		}
-		if (folder_open)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_bottom + 1, // overlap with bottom edge of above rect
-					   getRect().getWidth() - 2,
-					   0,
-					   sFocusOutlineColor, FALSE);
-			if (show_context)
-			{
-				gl_rect_2d(FOCUS_LEFT,
-						   focus_bottom + 1,
-						   getRect().getWidth() - 2,
-						   0,
-						   sHighlightBgColor, TRUE);
-			}
-		}
-	}
-	else if (mIsMouseOverTitle)
-	{
-		gl_rect_2d(FOCUS_LEFT,
-			focus_top, 
-			getRect().getWidth() - 2,
-			focus_bottom,
-			sMouseOverColor, FALSE);
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Draw DragNDrop highlight
-	//
-	if (mDragAndDropTarget)
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gl_rect_2d(FOCUS_LEFT, 
-				   focus_top, 
-				   getRect().getWidth() - 2,
-				   focus_bottom,
-				   sHighlightBgColor, FALSE);
-		if (folder_open)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_bottom + 1, // overlap with bottom edge of above rect
-					   getRect().getWidth() - 2,
-					   0,
-					   sHighlightBgColor, FALSE);
-		}
-		mDragAndDropTarget = FALSE;
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Draw open icon
-	//
-	const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
-	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
- 	{
-		mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
-	}
-	else if (mIcon)
-	{
- 		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
- 	}
-
-	if (mIconOverlay && getRoot()->showItemLinkOverlays())
-	{
-		mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Exit if no label to draw
-	//
-	if (mLabel.empty())
-	{
-		return;
-	}
-
-	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
-	//TODO RN: implement this in terms of getColor()
-	//if (highlight_link) color = sLinkColor;
-	//if (gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
-	
-	F32 right_x  = 0;
-	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
-
-	//--------------------------------------------------------------------------------//
-	// Draw the actual label text
-	//
-	font->renderUTF8(mLabel, 0, text_left, y, color,
-					 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-					 S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);
-
-	//--------------------------------------------------------------------------------//
-	// Draw label suffix
-	//
-	if (!mLabelSuffix.empty())
-	{
-		font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
-						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-						  S32_MAX, S32_MAX, &right_x, FALSE );
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Highlight string match
-	//
-	//TODO RN: expose interface for highlighting
-	//if (mStringMatchOffset != std::string::npos)
-	//{
-	//	// don't draw backgrounds for zero-length strings
-	//	S32 filter_string_length = getRoot()->getFilterSubString().size();
-	//	if (filter_string_length > 0)
-	//	{
-	//		std::string combined_string = mLabel + mLabelSuffix;
-	//		S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
-	//		S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
-	//		S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
-	//		S32 top = getRect().getHeight() - TOP_PAD;
-	//	
-	//		LLUIImage* box_image = default_params.selection_image;
-	//		LLRect box_rect(left, top, right, bottom);
-	//		box_image->draw(box_rect, sFilterBGColor);
-	//		F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
-	//		F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-	//		font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
-	//						  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-	//						  filter_string_length, S32_MAX, &right_x, FALSE );
-	//	}
-	//}
-}
-
-const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
-	{
-	return getRoot()->getFolderViewModel();
-}
-
-LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
-		{
-	return getRoot()->getFolderViewModel();
-}
-
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewFolder
-///----------------------------------------------------------------------------
-
-LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): 
-	LLFolderViewItem( p ),
-	mIsOpen(FALSE),
-	mExpanderHighlighted(FALSE),
-	mCurHeight(0.f),
-	mTargetHeight(0.f),
-	mAutoOpenCountdown(0.f),
-	mLastArrangeGeneration( -1 ),
-	mLastCalculatedWidth(0)
-{
-}
-
-// Destroys the object
-LLFolderViewFolder::~LLFolderViewFolder( void )
-{
-	// The LLView base class takes care of object destruction. make sure that we
-	// don't have mouse or keyboard focus
-	gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
-{
-	return folder->addFolder(this);
-}
-
-static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
-
-// Finds width and height of this object and its children. Also
-// makes sure that this view and its children are the right size.
-S32 LLFolderViewFolder::arrange( S32* width, S32* height )
-{
-	// sort before laying out contents
-	getRoot()->getFolderViewModel()->sort(this);
-
-	LLFastTimer t2(FTM_ARRANGE);
-
-	// evaluate mHasVisibleChildren
-	mHasVisibleChildren = false;
-	if (getViewModelItem()->descendantsPassedFilter())
-	{
-		// We have to verify that there's at least one child that's not filtered out
-		bool found = false;
-		// Try the items first
-		for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
-		{
-			LLFolderViewItem* itemp = (*iit);
-			found = itemp->passedFilter();
-			if (found)
-				break;
-		}
-		if (!found)
-		{
-			// If no item found, try the folders
-			for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
-			{
-				LLFolderViewFolder* folderp = (*fit);
-				found = folderp->passedFilter();
-				if (found)
-					break;
-			}
-		}
-
-		mHasVisibleChildren = found;
-	}
-
-	// calculate height as a single item (without any children), and reshapes rectangle to match
-	LLFolderViewItem::arrange( width, height );
-
-	// clamp existing animated height so as to never get smaller than a single item
-	mCurHeight = llmax((F32)*height, mCurHeight);
-
-	// initialize running height value as height of single item in case we have no children
-	F32 running_height = (F32)*height;
-	F32 target_height = (F32)*height;
-
-	// are my children visible?
-	if (needsArrange())
-	{
-		// set last arrange generation first, in case children are animating
-		// and need to be arranged again
-		mLastArrangeGeneration = getRoot()->getArrangeGeneration();
-		if (isOpen())
-		{
-			// Add sizes of children
-			S32 parent_item_height = getRect().getHeight();
-
-			for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
-			{
-				LLFolderViewFolder* folderp = (*fit);
-				folderp->setVisible(folderp->passedFilter()); // passed filter or has descendants that passed filter
-
-				if (folderp->getVisible())
-				{
-					S32 child_width = *width;
-					S32 child_height = 0;
-					S32 child_top = parent_item_height - llround(running_height);
-
-					target_height += folderp->arrange( &child_width, &child_height );
-
-					running_height += (F32)child_height;
-					*width = llmax(*width, child_width);
-					folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
-				}
-			}
-			for(items_t::iterator iit = mItems.begin();
-				iit != mItems.end(); ++iit)
-			{
-				LLFolderViewItem* itemp = (*iit);
-				itemp->setVisible(itemp->passedFilter());
-
-				if (itemp->getVisible())
-				{
-					S32 child_width = *width;
-					S32 child_height = 0;
-					S32 child_top = parent_item_height - llround(running_height);
-
-					target_height += itemp->arrange( &child_width, &child_height );
-					// don't change width, as this item is as wide as its parent folder by construction
-					itemp->reshape( itemp->getRect().getWidth(), child_height);
-
-					running_height += (F32)child_height;
-					*width = llmax(*width, child_width);
-					itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
-				}
-			}
-		}
-
-		mTargetHeight = target_height;
-		// cache this width so next time we can just return it
-		mLastCalculatedWidth = *width;
-	}
-	else
-	{
-		// just use existing width
-		*width = mLastCalculatedWidth;
-	}
-
-	// animate current height towards target height
-	if (llabs(mCurHeight - mTargetHeight) > 1.f)
-	{
-		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
-
-		requestArrange();
-
-		// hide child elements that fall out of current animated height
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			// number of pixels that bottom of folder label is from top of parent folder
-			if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() 
-				> llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
-			{
-				// hide if beyond current folder height
-				(*fit)->setVisible(FALSE);
-			}
-		}
-
-		for (items_t::iterator iter = mItems.begin();
-			iter != mItems.end();)
-		{
-			items_t::iterator iit = iter++;
-			// number of pixels that bottom of item label is from top of parent folder
-			if (getRect().getHeight() - (*iit)->getRect().mBottom
-				> llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
-			{
-				(*iit)->setVisible(FALSE);
-			}
-		}
-	}
-	else
-	{
-		mCurHeight = mTargetHeight;
-	}
-
-	// don't change width as this item is already as wide as its parent folder
-	reshape(getRect().getWidth(),llround(mCurHeight));
-
-	// pass current height value back to parent
-	*height = llround(mCurHeight);
-
-	return llround(mTargetHeight);
-}
-
-BOOL LLFolderViewFolder::needsArrange()
-{
-	return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); 
-}
-
-void LLFolderViewFolder::requestSort()
-{
-	getViewModelItem()->requestSort();
-}
-
-//TODO RN: get height resetting working
-//void LLFolderViewFolder::setPassedFilter(BOOL passed, BOOL passed_folder, S32 filter_generation)
-//{
-//	// if this folder is now filtered, but wasn't before
-//	// (it just passed)
-//	if (passed && !passedFilter(filter_generation))
-//	{
-//		// reset current height, because last time we drew it
-//		// it might have had more visible items than now
-//		mCurHeight = 0.f;
-//	}
-//
-//	LLFolderViewItem::setPassedFilter(passed, passed_folder, filter_generation);
-//}
-
-
-// Passes selection information on to children and record selection
-// information if necessary.
-BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
-                                      BOOL take_keyboard_focus)
-{
-	BOOL rv = FALSE;
-	if (selection == this)
-	{
-		if (!isSelected())
-		{
-			selectItem();
-		}
-		rv = TRUE;
-	}
-	else
-	{
-		if (isSelected())
-		{
-			deselectItem();
-		}
-		rv = FALSE;
-	}
-	BOOL child_selected = FALSE;
-
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
-		{
-			rv = TRUE;
-			child_selected = TRUE;
-		}
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
-		{
-			rv = TRUE;
-			child_selected = TRUE;
-		}
-	}
-	if(openitem && child_selected)
-	{
-		setOpenArrangeRecursively(TRUE);
-	}
-	return rv;
-}
-
-// This method is used to change the selection of an item.
-// Recursively traverse all children; if 'selection' is 'this' then change
-// the select status if necessary.
-// Returns TRUE if the selection state of this folder, or of a child, was changed.
-BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
-	BOOL rv = FALSE;
-	if(selection == this)
-	{
-		if (isSelected() != selected)
-		{
-			rv = TRUE;
-			if (selected)
-			{
-				selectItem();
-			}
-			else
-			{
-				deselectItem();
-			}
-		}
-	}
-
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		if((*fit)->changeSelection(selection, selected))
-		{
-			rv = TRUE;
-		}
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		if((*iit)->changeSelection(selection, selected))
-		{
-			rv = TRUE;
-		}
-	}
-	return rv;
-}
-
-LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
-{
-	if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
-
-	std::deque<LLFolderViewFolder*> item_a_ancestors;
-
-	LLFolderViewFolder* parent = item_a->getParentFolder();
-	while(parent)
-	{
-		item_a_ancestors.push_back(parent);
-		parent = parent->getParentFolder();
-	}
-
-	std::deque<LLFolderViewFolder*> item_b_ancestors;
-	
-	parent = item_b->getParentFolder();
-	while(parent)
-	{
-		item_b_ancestors.push_back(parent);
-		parent = parent->getParentFolder();
-	}
-
-	LLFolderViewFolder* common_ancestor = item_a->getRoot();
-
-	while(item_a_ancestors.size() > item_b_ancestors.size())
-	{
-		item_a = item_a_ancestors.front();
-		item_a_ancestors.pop_front();
-	}
-
-	while(item_b_ancestors.size() > item_a_ancestors.size())
-	{
-		item_b = item_b_ancestors.front();
-		item_b_ancestors.pop_front();
-	}
-
-	while(item_a_ancestors.size())
-	{
-		common_ancestor = item_a_ancestors.front();
-
-		if (item_a_ancestors.front() == item_b_ancestors.front())
-		{
-			// which came first, sibling a or sibling b?
-			for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
-				it != end_it;
-				++it)
-			{
-				LLFolderViewItem* item = *it;
-
-				if (item == item_a)
-				{
-					reverse = false;
-					return common_ancestor;
-				}
-				if (item == item_b)
-				{
-					reverse = true;
-					return common_ancestor;
-				}
-			}
-
-			for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
-				it != end_it;
-				++it)
-			{
-				LLFolderViewItem* item = *it;
-
-				if (item == item_a)
-				{
-					reverse = false;
-					return common_ancestor;
-				}
-				if (item == item_b)
-				{
-					reverse = true;
-					return common_ancestor;
-				}
-			}
-			break;
-		}
-
-		item_a = item_a_ancestors.front();
-		item_a_ancestors.pop_front();
-		item_b = item_b_ancestors.front();
-		item_b_ancestors.pop_front();
-	}
-
-	return NULL;
-}
-
-void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
-{
-	bool selecting = start == NULL;
-	if (reverse)
-	{
-		for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
-			it != end_it;
-			++it)
-		{
-			if (*it == end)
-			{
-				return;
-			}
-			if (selecting)
-			{
-				items.push_back(*it);
-			}
-
-			if (*it == start)
-			{
-				selecting = true;
-			}
-		}
-		for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
-			it != end_it;
-			++it)
-		{
-			if (*it == end)
-			{
-				return;
-			}
-
-			if (selecting)
-			{
-				items.push_back(*it);
-			}
-
-			if (*it == start)
-			{
-				selecting = true;
-			}
-		}
-	}
-	else
-	{
-		for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
-			it != end_it;
-			++it)
-		{
-			if (*it == end)
-			{
-				return;
-			}
-
-			if (selecting)
-			{
-				items.push_back(*it);
-			}
-
-			if (*it == start)
-			{
-				selecting = true;
-			}
-		}
-		for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
-			it != end_it;
-			++it)
-		{
-			if (*it == end)
-			{
-				return;
-			}
-
-			if (selecting)
-			{
-				items.push_back(*it);
-			}
-
-			if (*it == start)
-			{
-				selecting = true;
-			}
-		}
-	}
-}
-
-void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
-{
-	if (getRoot()->getAllowMultiSelect() == FALSE) return;
-
-	LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem();
-	if (cur_selected_item == NULL)
-	{
-		cur_selected_item = new_selection;
-	}
-
-
-	bool reverse = false;
-	LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse);
-	if (!common_ancestor) return;
-
-	LLFolderViewItem* last_selected_item_from_cur = cur_selected_item;
-	LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder();
-
-	std::vector<LLFolderViewItem*> items_to_select_forward;
-
-	while(cur_folder != common_ancestor)
-	{
-		cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward);
-			
-		last_selected_item_from_cur = cur_folder;
-		cur_folder = cur_folder->getParentFolder();
-	}
-
-	std::vector<LLFolderViewItem*> items_to_select_reverse;
-
-	LLFolderViewItem* last_selected_item_from_new = new_selection;
-	cur_folder = new_selection->getParentFolder();
-	while(cur_folder != common_ancestor)
-	{
-		cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse);
-
-		last_selected_item_from_new = cur_folder;
-		cur_folder = cur_folder->getParentFolder();
-	}
-
-	common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward);
-
-	for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend();
-		it != end_it;
-		++it)
-	{
-		items_to_select_forward.push_back(*it);
-	}
-
-	LLFolderView* root = getRoot();
-
-	for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
-		it != end_it;
-		++it)
-	{
-		LLFolderViewItem* item = *it;
-		if (item->isSelected())
-		{
-			root->removeFromSelectionList(item);
-		}
-		else
-		{
-			item->selectItem();
-		}
-		root->addToSelectionList(item);
-	}
-
-	if (new_selection->isSelected())
-	{
-		root->removeFromSelectionList(new_selection);
-	}
-	else
-	{
-		new_selection->selectItem();
-	}
-	root->addToSelectionList(new_selection);
-}
-
-
-void LLFolderViewFolder::destroyView()
-{
-	std::for_each(mItems.begin(), mItems.end(), DeletePointer());
-	mItems.clear();
-
-	while (!mFolders.empty())
-	{
-		LLFolderViewFolder *folderp = mFolders.back();
-		folderp->destroyView(); // removes entry from mFolders
-	}
-
-	LLFolderViewItem::destroyView();
-}
-
-// extractItem() removes the specified item from the folder, but
-// doesn't delete it.
-void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
-{
-	items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
-	if(it == mItems.end())
-	{
-		// This is an evil downcast. However, it's only doing
-		// pointer comparison to find if (which it should be ) the
-		// item is in the container, so it's pretty safe.
-		LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item);
-		folders_t::iterator ft;
-		ft = std::find(mFolders.begin(), mFolders.end(), f);
-		if (ft != mFolders.end())
-		{
-			mFolders.erase(ft);
-		}
-	}
-	else
-	{
-		mItems.erase(it);
-	}
-	//item has been removed, need to update filter
-	getViewModelItem()->removeChild(item->getViewModelItem());
-	getViewModelItem()->dirtyFilter();
-	//because an item is going away regardless of filter status, force rearrange
-	requestArrange();
-	removeChild(item);
-}
-
-BOOL LLFolderViewFolder::isMovable()
-{
-	if( !(getViewModelItem()->isItemMovable()) )
-		{
-			return FALSE;
-		}
-
-		for (items_t::iterator iter = mItems.begin();
-			iter != mItems.end();)
-		{
-			items_t::iterator iit = iter++;
-			if(!(*iit)->isMovable())
-			{
-				return FALSE;
-			}
-		}
-
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			if(!(*fit)->isMovable())
-			{
-				return FALSE;
-			}
-		}
-	return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::isRemovable()
-{
-	if( !(getViewModelItem()->isItemRemovable()) )
-		{
-			return FALSE;
-		}
-
-		for (items_t::iterator iter = mItems.begin();
-			iter != mItems.end();)
-		{
-			items_t::iterator iit = iter++;
-			if(!(*iit)->isRemovable())
-			{
-				return FALSE;
-			}
-		}
-
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			if(!(*fit)->isRemovable())
-			{
-				return FALSE;
-			}
-		}
-	return TRUE;
-}
-
-// this is an internal method used for adding items to folders. 
-BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
-{
-	if (item->getParentFolder())
-	{
-		item->getParentFolder()->extractItem(item);
-	}
-	item->setParentFolder(this);
-
-	mItems.push_back(item);
-	
-	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
-	item->setVisible(FALSE);
-	
-	addChild(item);
-	
-	item->getViewModelItem()->dirtyFilter();
-
-	// Handle sorting
-	requestArrange();
-	requestSort();
-
-	getViewModelItem()->addChild(item->getViewModelItem());
-
-	//TODO RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
-	//// Traverse parent folders and update creation date and resort, if necessary
-	//LLFolderViewFolder* parentp = this;
-	//while (parentp)
-	//{
-	//	if (parentp->mSortFunction.isByDate())
-	//	{
-	//		// parent folder doesn't have a time stamp yet, so get it from us
-	//		parentp->requestSort();
-	//	}
-
-	//	parentp = parentp->getParentFolder();
-	//}
-
-	return TRUE;
-}
-
-// this is an internal method used for adding items to folders. 
-BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
-{
-	if (folder->mParentFolder)
-	{
-		folder->mParentFolder->extractItem(folder);
-	}
-	folder->mParentFolder = this;
-	mFolders.push_back(folder);
-	folder->setOrigin(0, 0);
-	folder->reshape(getRect().getWidth(), 0);
-	folder->setVisible(FALSE);
-	addChild( folder );
-	folder->getViewModelItem()->dirtyFilter();
-	// rearrange all descendants too, as our indentation level might have changed
-	folder->requestArrange();
-	requestSort();
-
-	getViewModelItem()->addChild(folder->getViewModelItem());
-
-	return TRUE;
-}
-
-void LLFolderViewFolder::requestArrange()
-{ 
-	mLastArrangeGeneration = -1; 
-	// flag all items up to root
-	if (mParentFolder)
-	{
-		mParentFolder->requestArrange();
-	}
-}
-
-void LLFolderViewFolder::toggleOpen()
-{
-	setOpen(!isOpen());
-}
-
-// Force a folder open or closed
-void LLFolderViewFolder::setOpen(BOOL openitem)
-{
-	setOpenArrangeRecursively(openitem);
-}
-
-void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
-	BOOL was_open = isOpen();
-	mIsOpen = openitem;
-	if(!was_open && openitem)
-	{
-		getViewModelItem()->openItem();
-	}
-	else if(was_open && !openitem)
-	{
-		getViewModelItem()->closeItem();
-	}
-
-	if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
-	{
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN);		/* Flawfinder: ignore */
-		}
-	}
-	if (mParentFolder
-		&&	(recurse == RECURSE_UP
-			|| recurse == RECURSE_UP_DOWN))
-	{
-		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
-	}
-
-	if (was_open != isOpen())
-	{
-		requestArrange();
-	}
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
-													BOOL drop,
-													EDragAndDropType c_type,
-													void* cargo_data,
-													EAcceptance* accept,
-													std::string& tooltip_msg)
-{
-	BOOL accepted = mViewModelItem->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
-	if (accepted) 
-	{
-		mDragAndDropTarget = TRUE;
-		*accept = ACCEPT_YES_MULTI;
-	}
-	else 
-	{
-		*accept = ACCEPT_NO;
-	}
-
-	// drag and drop to child item, so clear pending auto-opens
-	getRoot()->autoOpenTest(NULL);
-
-	return TRUE;
-}
-
-void LLFolderViewFolder::openItem( void )
-{
-	toggleOpen();
-}
-
-void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
-{
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		functor.doItem((*fit));
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		functor.doItem((*iit));
-	}
-}
-
-void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
-{
-	functor.doFolder(this);
-
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		(*fit)->applyFunctorRecursively(functor);
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		functor.doItem((*iit));
-	}
-}
-
-// LLView functionality
-BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
-										   BOOL drop,
-										   EDragAndDropType cargo_type,
-										   void* cargo_data,
-										   EAcceptance* accept,
-										   std::string& tooltip_msg)
-{
-	BOOL handled = FALSE;
-
-	if (isOpen())
-	{
-		handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
-	}
-
-	if (!handled)
-	{
-		handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-
-		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
-	}
-
-	return TRUE;
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
-													   BOOL drop,
-													   EDragAndDropType cargo_type,
-													   void* cargo_data,
-													   EAcceptance* accept,
-													   std::string& tooltip_msg)
-{
-	BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
-	
-	if (accepted) 
-	{
-		mDragAndDropTarget = TRUE;
-		*accept = ACCEPT_YES_MULTI;
-	}
-	else 
-	{
-		*accept = ACCEPT_NO;
-	}
-	
-	if (!drop && accepted)
-	{
-		getRoot()->autoOpenTest(this);
-	}
-	
-	return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
-	BOOL handled = FALSE;
-
-	if( isOpen() )
-	{
-		handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
-	}
-	if (!handled)
-	{
-		handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
-	}
-	return handled;
-}
-
-
-BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
-{
-	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
-
-	BOOL handled = LLView::handleHover(x, y, mask);
-
-	if (!handled)
-	{
-		// this doesn't do child processing
-		handled = LLFolderViewItem::handleHover(x, y, mask);
-	}
-
-	return handled;
-}
-
-BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
-{
-	BOOL handled = FALSE;
-	if( isOpen() )
-	{
-		handled = childrenHandleMouseDown(x,y,mask) != NULL;
-	}
-	if( !handled )
-	{
-		if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
-		{
-			toggleOpen();
-			handled = TRUE;
-		}
-		else
-		{
-			// do normal selection logic
-			handled = LLFolderViewItem::handleMouseDown(x, y, mask);
-		}
-	}
-
-	return handled;
-}
-
-BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
-	BOOL handled = FALSE;
-	if( isOpen() )
-	{
-		handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
-	}
-	if( !handled )
-	{
-		if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
-		{
-			// don't select when user double-clicks plus sign
-			// so as not to contradict single-click behavior
-			toggleOpen();
-		}
-		else
-		{
-			getRoot()->setSelection(this, FALSE);
-			toggleOpen();
-		}
-		handled = TRUE;
-	}
-	return handled;
-}
-
-void LLFolderViewFolder::draw()
-{
-	if (mAutoOpenCountdown != 0.f)
-	{
-		mControlLabelRotation = mAutoOpenCountdown * -90.f;
-	}
-	else if (isOpen())
-	{
-		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
-	}
-	else
-	{
-		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
-	}
-
-	LLFolderViewItem::draw();
-
-	// draw children if root folder, or any other folder that is open or animating to closed state
-	if( getRoot() == this || (isOpen() || mCurHeight != mTargetHeight ))
-	{
-		LLView::draw();
-	}
-
-	mExpanderHighlighted = FALSE;
-}
-
-// this does prefix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
-{
-	BOOL found_item = FALSE;
-
-	LLFolderViewItem* result = NULL;
-	// when not starting from a given item, start at beginning
-	if(item == NULL)
-	{
-		found_item = TRUE;
-	}
-
-	// find current item among children
-	folders_t::iterator fit = mFolders.begin();
-	folders_t::iterator fend = mFolders.end();
-
-	items_t::iterator iit = mItems.begin();
-	items_t::iterator iend = mItems.end();
-
-	// if not trivially starting at the beginning, we have to find the current item
-	if (!found_item)
-	{
-		// first, look among folders, since they are always above items
-		for(; fit != fend; ++fit)
-		{
-			if(item == (*fit))
-			{
-				found_item = TRUE;
-				// if we are on downwards traversal
-				if (include_children && (*fit)->isOpen())
-				{
-					// look for first descendant
-					return (*fit)->getNextFromChild(NULL, TRUE);
-				}
-				// otherwise advance to next folder
-				++fit;
-				include_children = TRUE;
-				break;
-			}
-		}
-
-		// didn't find in folders?  Check items...
-		if (!found_item)
-		{
-			for(; iit != iend; ++iit)
-			{
-				if(item == (*iit))
-				{
-					found_item = TRUE;
-					// point to next item
-					++iit;
-					break;
-				}
-			}
-		}
-	}
-
-	if (!found_item)
-	{
-		// you should never call this method with an item that isn't a child
-		// so we should always find something
-		llassert(FALSE);
-		return NULL;
-	}
-
-	// at this point, either iit or fit point to a candidate "next" item
-	// if both are out of range, we need to punt up to our parent
-
-	// now, starting from found folder, continue through folders
-	// searching for next visible folder
-	while(fit != fend && !(*fit)->getVisible())
-	{
-		// turn on downwards traversal for next folder
-		++fit;
-	} 
-
-	if (fit != fend)
-	{
-		result = (*fit);
-	}
-	else
-	{
-		// otherwise, scan for next visible item
-		while(iit != iend && !(*iit)->getVisible())
-		{
-			++iit;
-		} 
-
-		// check to see if we have a valid item
-		if (iit != iend)
-		{
-			result = (*iit);
-		}
-	}
-
-	if( !result && mParentFolder )
-	{
-		// If there are no siblings or children to go to, recurse up one level in the tree
-		// and skip children for this folder, as we've already discounted them
-		result = mParentFolder->getNextFromChild(this, FALSE);
-	}
-
-	return result;
-}
-
-// this does postfix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
-{
-	BOOL found_item = FALSE;
-
-	LLFolderViewItem* result = NULL;
-	// when not starting from a given item, start at end
-	if(item == NULL)
-	{
-		found_item = TRUE;
-	}
-
-	// find current item among children
-	folders_t::reverse_iterator fit = mFolders.rbegin();
-	folders_t::reverse_iterator fend = mFolders.rend();
-
-	items_t::reverse_iterator iit = mItems.rbegin();
-	items_t::reverse_iterator iend = mItems.rend();
-
-	// if not trivially starting at the end, we have to find the current item
-	if (!found_item)
-	{
-		// first, look among items, since they are always below the folders
-		for(; iit != iend; ++iit)
-		{
-			if(item == (*iit))
-			{
-				found_item = TRUE;
-				// point to next item
-				++iit;
-				break;
-			}
-		}
-
-		// didn't find in items?  Check folders...
-		if (!found_item)
-		{
-			for(; fit != fend; ++fit)
-			{
-				if(item == (*fit))
-				{
-					found_item = TRUE;
-					// point to next folder
-					++fit;
-					break;
-				}
-			}
-		}
-	}
-
-	if (!found_item)
-	{
-		// you should never call this method with an item that isn't a child
-		// so we should always find something
-		llassert(FALSE);
-		return NULL;
-	}
-
-	// at this point, either iit or fit point to a candidate "next" item
-	// if both are out of range, we need to punt up to our parent
-
-	// now, starting from found item, continue through items
-	// searching for next visible item
-	while(iit != iend && !(*iit)->getVisible())
-	{
-		++iit;
-	} 
-
-	if (iit != iend)
-	{
-		// we found an appropriate item
-		result = (*iit);
-	}
-	else
-	{
-		// otherwise, scan for next visible folder
-		while(fit != fend && !(*fit)->getVisible())
-		{
-			++fit;
-		} 
-
-		// check to see if we have a valid folder
-		if (fit != fend)
-		{
-			// try selecting child element of this folder
-			if ((*fit)->isOpen())
-			{
-				result = (*fit)->getPreviousFromChild(NULL);
-			}
-			else
-			{
-				result = (*fit);
-			}
-		}
-	}
-
-	if( !result )
-	{
-		// If there are no siblings or children to go to, recurse up one level in the tree
-		// which gets back to this folder, which will only be visited if it is a valid, visible item
-		result = this;
-	}
-
-	return result;
-}
-
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
deleted file mode 100644
index 92923e82da..0000000000
--- a/indra/newview/llfolderviewitem.h
+++ /dev/null
@@ -1,418 +0,0 @@
-/** 
-* @file llfolderviewitem.h
-* @brief Items and folders that can appear in a hierarchical folder view
-*
-* $LicenseInfo:firstyear=2001&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-* 
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-* 
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-* 
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-* 
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-* $/LicenseInfo$
-*/
-#ifndef LLFOLDERVIEWITEM_H
-#define LLFOLDERVIEWITEM_H
-
-#include "llview.h"
-#include "lluiimage.h"
-
-class LLFolderView;
-class LLFolderViewModelItem;
-class LLFolderViewFolder;
-class LLFolderViewFunctor;
-class LLFolderViewFilter;
-class LLFolderViewModelInterface;
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewItem
-//
-// An instance of this class represents a single item in a folder view
-// such as an inventory item or a file.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewItem : public LLView
-{
-public:
-	static void initClass();
-	static void cleanupClass();
-
-	struct Params : public LLInitParam::Block<Params, LLView::Params>
-	{
-		Optional<LLUIImage*>						folder_arrow_image,
-													selection_image;
-		Optional<LLFolderView*>						root;
-		Mandatory<LLFolderViewModelItem*>			listener;
-
-		Optional<S32>								folder_indentation, // pixels
-													item_height,
-													item_top_pad;
-
-		Optional<time_t>							creation_date;
-
-		Params();
-	};
-
-	// layout constants
-	static const S32 LEFT_PAD = 5;
-	// LEFT_INDENTATION is set via folder_indentation above
-	static const S32 ICON_PAD = 2;
-	static const S32 ICON_WIDTH = 16;
-	static const S32 TEXT_PAD = 1;
-	static const S32 TEXT_PAD_RIGHT = 4;
-	static const S32 ARROW_SIZE = 12;
-	static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
-	// animation parameters
-	static const F32 FOLDER_CLOSE_TIME_CONSTANT;
-	static const F32 FOLDER_OPEN_TIME_CONSTANT;
-
-private:
-	BOOL						mIsSelected;
-
-protected:
-	friend class LLUICtrlFactory;
-	friend class LLFolderViewModelItem;
-
-	LLFolderViewItem(const Params& p);
-
-	std::string					mLabel;
-	S32							mLabelWidth;
-	bool						mLabelWidthDirty;
-	LLFolderViewFolder*			mParentFolder;
-	LLFolderViewModelItem*		mViewModelItem;
-	BOOL						mIsCurSelection;
-	BOOL						mSelectPending;
-	LLFontGL::StyleFlags		mLabelStyle;
-	std::string					mLabelSuffix;
-	LLUIImagePtr				mIcon;
-	LLUIImagePtr				mIconOpen;
-	LLUIImagePtr				mIconOverlay;
-	BOOL						mHasVisibleChildren;
-	S32							mIndentation;
-	S32							mItemHeight;
-
-	//TODO RN: create interface for string highlighting
-	//std::string::size_type		mStringMatchOffset;
-	F32							mControlLabelRotation;
-	LLFolderView*				mRoot;
-	BOOL						mDragAndDropTarget;
-	bool						mIsMouseOverTitle;
-
-	// this is an internal method used for adding items to folders. A
-	// no-op at this level, but reimplemented in derived classes.
-	virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
-	virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
-
-	static LLFontGL* getLabelFontForStyle(U8 style);
-
-public:
-	BOOL postBuild();
-
-	virtual void openItem( void );
-
-	void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
-
-	virtual ~LLFolderViewItem( void );
-
-	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-	virtual BOOL addToFolder(LLFolderViewFolder* folder);
-
-	// Finds width and height of this object and it's children.  Also
-	// makes sure that this view and it's children are the right size.
-	virtual S32 arrange( S32* width, S32* height );
-	virtual S32 getItemHeight();
-
-	// If 'selection' is 'this' then note that otherwise ignore.
-	// Returns TRUE if this item ends up being selected.
-	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
-
-	// This method is used to set the selection state of an item.
-	// If 'selection' is 'this' then note selection.
-	// Returns TRUE if the selection state of this item was changed.
-	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
-	// this method is used to deselect this element
-	void deselectItem();
-
-	// this method is used to select this element
-	virtual void selectItem();
-
-	// gets multiple-element selection
-	virtual std::set<LLFolderViewItem*> getSelectionList() const;
-
-	// Returns true is this object and all of its children can be removed (deleted by user)
-	virtual BOOL isRemovable();
-
-	// Returns true is this object and all of its children can be moved
-	virtual BOOL isMovable();
-
-	// destroys this item recursively
-	virtual void destroyView();
-
-	BOOL isSelected() const { return mIsSelected; }
-
-	void setUnselected() { mIsSelected = FALSE; }
-
-	void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
-
-	BOOL getIsCurSelection() { return mIsCurSelection; }
-
-	BOOL hasVisibleChildren() { return mHasVisibleChildren; }
-
-	// Call through to the viewed object and return true if it can be
-	// removed. Returns true if it's removed.
-	//virtual BOOL removeRecursively(BOOL single_item);
-	BOOL remove();
-
-	// Build an appropriate context menu for the item.	Flags unused.
-	void buildContextMenu(class LLMenuGL& menu, U32 flags);
-
-	// This method returns the actual name of the thing being
-	// viewed. This method will ask the viewed object itself.
-	const std::string& getName( void ) const;
-
-	// This method returns the label displayed on the view. This
-	// method was primarily added to allow sorting on the folder
-	// contents possible before the entire view has been constructed.
-	const std::string& getLabel() const { return mLabel; }
-
-
-	LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
-	const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
-
-	void setParentFolder(LLFolderViewFolder* parent) { mParentFolder = parent; }
-
-	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
-	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
-
-	const LLFolderViewModelItem* getViewModelItem( void ) const { return mViewModelItem; }
-	LLFolderViewModelItem* getViewModelItem( void ) { return mViewModelItem; }
-
-	const LLFolderViewModelInterface* getFolderViewModel( void ) const;
-	LLFolderViewModelInterface* getFolderViewModel( void );
-
-	// just rename the object.
-	void rename(const std::string& new_name);
-
-
-	// Show children (unfortunate that this is called "open")
-	virtual void setOpen(BOOL open = TRUE) {};
-	virtual BOOL isOpen() const { return FALSE; }
-
-	virtual LLFolderView*	getRoot();
-	virtual const LLFolderView*	getRoot() const;
-	BOOL			isDescendantOf( const LLFolderViewFolder* potential_ancestor );
-	S32				getIndentation() { return mIndentation; }
-
-	virtual BOOL	passedFilter(S32 filter_generation = -1);
-
-	// refresh information from the object being viewed.
-	virtual void refresh();
-
-	// LLView functionality
-	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
-	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
-	virtual BOOL handleHover( S32 x, S32 y, MASK mask );
-	virtual BOOL handleMouseUp( S32 x, S32 y, MASK mask );
-	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
-
-	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
-
-	virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
-
-	//	virtual void handleDropped();
-	virtual void draw();
-	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
-
-private:
-	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
-};
-
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFolder
-//
-// An instance of an LLFolderViewFolder represents a collection of
-// more folders and items. This is used to build the hierarchy of
-// items found in the folder view.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-class LLFolderViewFolder : public LLFolderViewItem
-{
-protected:
-	LLFolderViewFolder( const LLFolderViewItem::Params& );
-	friend class LLUICtrlFactory;
-
-public:
-
-	typedef std::list<LLFolderViewItem*> items_t;
-	typedef std::list<LLFolderViewFolder*> folders_t;
-
-protected:
-	items_t mItems;
-	folders_t mFolders;
-
-	BOOL		mIsOpen;
-	BOOL		mExpanderHighlighted;
-	F32			mCurHeight;
-	F32			mTargetHeight;
-	F32			mAutoOpenCountdown;
-	S32			mLastArrangeGeneration;
-	S32			mLastCalculatedWidth;
-	S32			mMostFilteredDescendantGeneration;
-	bool		mNeedsSort;
-
-public:
-	typedef enum e_recurse_type
-	{
-		RECURSE_NO,
-		RECURSE_UP,
-		RECURSE_DOWN,
-		RECURSE_UP_DOWN
-	} ERecurseType;
-
-
-	virtual ~LLFolderViewFolder( void );
-
-	LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
-	LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE  );
-
-	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-	virtual BOOL addToFolder(LLFolderViewFolder* folder);
-
-	// Finds width and height of this object and it's children.  Also
-	// makes sure that this view and it's children are the right size.
-	virtual S32 arrange( S32* width, S32* height );
-
-	BOOL needsArrange();
-
-	bool descendantsPassedFilter(S32 filter_generation = -1);
-
-	// Passes selection information on to children and record
-	// selection information if necessary.
-	// Returns TRUE if this object (or a child) ends up being selected.
-	// If 'openitem' is TRUE then folders are opened up along the way to the selection.
-	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus = TRUE);
-
-	// This method is used to change the selection of an item.
-	// Recursively traverse all children; if 'selection' is 'this' then change
-	// the select status if necessary.
-	// Returns TRUE if the selection state of this folder, or of a child, was changed.
-	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
-
-	// this method is used to group select items
-	void extendSelectionTo(LLFolderViewItem* selection);
-
-	// Returns true is this object and all of its children can be removed.
-	virtual BOOL isRemovable();
-
-	// Returns true is this object and all of its children can be moved
-	virtual BOOL isMovable();
-
-	// destroys this folder, and all children
-	virtual void destroyView();
-
-	// If this folder can be removed, remove all children that can be
-	// removed, return TRUE if this is empty after the operation and
-	// it's viewed folder object can be removed.
-	//virtual BOOL removeRecursively(BOOL single_item);
-	//virtual BOOL remove();
-
-	// extractItem() removes the specified item from the folder, but
-	// doesn't delete it.
-	virtual void extractItem( LLFolderViewItem* item );
-
-	// This function is called by a child that needs to be resorted.
-	void resort(LLFolderViewItem* item);
-
-	void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
-
-	// folders can be opened. This will usually be called by internal
-	// methods.
-	virtual void toggleOpen();
-
-	// Force a folder open or closed
-	virtual void setOpen(BOOL openitem = TRUE);
-
-	// Called when a child is refreshed.
-	virtual void requestArrange();
-
-	virtual void requestSort();
-
-	// internal method which doesn't update the entire view. This
-	// method was written because the list iterators destroy the state
-	// of other iterations, thus, we can't arrange while iterating
-	// through the children (such as when setting which is selected.
-	virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
-
-	// Get the current state of the folder.
-	virtual BOOL isOpen() const { return mIsOpen; }
-
-	// special case if an object is dropped on the child.
-	BOOL handleDragAndDropFromChild(MASK mask,
-		BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
-
-	void applyFunctorRecursively(LLFolderViewFunctor& functor);
-
-	// Just apply this functor to the folder's immediate children.
-	void applyFunctorToChildren(LLFolderViewFunctor& functor);
-
-	virtual void openItem( void );
-	virtual BOOL addItem(LLFolderViewItem* item);
-	virtual BOOL addFolder( LLFolderViewFolder* folder);
-
-	// LLView functionality
-	virtual BOOL handleHover(S32 x, S32 y, MASK mask);
-	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
-	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
-	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
-	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
-	BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
-									   EDragAndDropType cargo_type,
-									   void* cargo_data,
-									   EAcceptance* accept,
-									   std::string& tooltip_msg);
-	virtual void draw();
-
-	folders_t::iterator getFoldersBegin() { return mFolders.begin(); }
-	folders_t::iterator getFoldersEnd() { return mFolders.end(); }
-	folders_t::size_type getFoldersCount() const { return mFolders.size(); }
-
-	items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
-	items_t::const_iterator getItemsEnd() const { return mItems.end(); }
-	items_t::size_type getItemsCount() const { return mItems.size(); }
-
-	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
-	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);
-
-public:
-	//WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
-	template<typename SORT_FUNC> void sortFolders(const SORT_FUNC& func) { mFolders.sort(func); }
-	template<typename SORT_FUNC> void sortItems(const SORT_FUNC& func) { mItems.sort(func); }
-};
-
-
-#endif  // LLFOLDERVIEWITEM_H
diff --git a/indra/newview/llfolderviewmodel.cpp b/indra/newview/llfolderviewmodel.cpp
deleted file mode 100644
index ca6225aca7..0000000000
--- a/indra/newview/llfolderviewmodel.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/** 
- * @file llfolderviewmodel.cpp
- * @brief Implementation of the view model collection of classes.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfolderviewmodel.h"
-#include "lltrans.h"
-
-bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
-{
-	return item->getSortVersion() < mTargetSortVersion;
-}
-
-std::string LLFolderViewModelCommon::getStatusText()
-{
-	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter()->getCurrentGeneration())
-	{
-		return LLTrans::getString("Searching");
-	}
-	else
-	{
-		return getFilter()->getEmptyLookupMessage();
-	}
-}
-
-void LLFolderViewModelCommon::filter()
-{
-	getFilter()->setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
-	mFolderView->getViewModelItem()->filter(*getFilter());
-}
diff --git a/indra/newview/llfolderviewmodel.h b/indra/newview/llfolderviewmodel.h
deleted file mode 100644
index 079409c2a4..0000000000
--- a/indra/newview/llfolderviewmodel.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/** 
- * @file llfolderviewmodel.h
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-#ifndef LLFOLDERVIEWMODEL_H
-#define LLFOLDERVIEWMODEL_H
-
-#include "llfontgl.h"	// just for StyleFlags enum
-#include "llfolderview.h"
-
-// These are grouping of inventory types.
-// Order matters when sorting system folders to the top.
-enum EInventorySortGroup
-{
-	SG_SYSTEM_FOLDER,
-	SG_TRASH_FOLDER,
-	SG_NORMAL_FOLDER,
-	SG_ITEM
-};
-
-class LLFontGL;
-class LLInventoryModel;
-class LLMenuGL;
-class LLUIImage;
-class LLUUID;
-class LLFolderViewItem;
-class LLFolderViewFolder;
-
-class LLFolderViewFilter
-{
-public:
-	enum EFilterModified
-	{
-		FILTER_NONE,				// nothing to do, already filtered
-		FILTER_RESTART,				// restart filtering from scratch
-		FILTER_LESS_RESTRICTIVE,	// existing filtered items will certainly pass this filter
-		FILTER_MORE_RESTRICTIVE		// if you didn't pass the previous filter, you definitely won't pass this one
-	};
-
-public:
-
-	LLFolderViewFilter() {}
-	virtual ~LLFolderViewFilter() {}
-
-	// +-------------------------------------------------------------------+
-	// + Execution And Results
-	// +-------------------------------------------------------------------+
-	virtual bool 				check(const LLFolderViewModelItem* item) = 0;
-	virtual bool				check(const LLInventoryItem* item) = 0;
-	virtual bool				checkFolder(const LLFolderViewModelItem* folder) const = 0;
-	virtual bool				checkFolder(const LLUUID& folder_id) const = 0;
-
-	virtual void 				setEmptyLookupMessage(const std::string& message) = 0;
-	virtual std::string			getEmptyLookupMessage() const = 0;
-
-	virtual bool				showAllResults() const = 0;
-
-	// +-------------------------------------------------------------------+
-	// + Status
-	// +-------------------------------------------------------------------+
-	virtual bool 				isActive() const = 0;
-	virtual bool 				isModified() const = 0;
-	virtual void 				clearModified() = 0;
-	virtual const std::string& 	getName() const = 0;
-	virtual const std::string& 	getFilterText() = 0;
-	//RN: this is public to allow system to externally force a global refilter
-	virtual void 				setModified(EFilterModified behavior = FILTER_RESTART) = 0;
-
-	// +-------------------------------------------------------------------+
-	// + Count
-	// +-------------------------------------------------------------------+
-	virtual void 				setFilterCount(S32 count) = 0;
-	virtual S32 				getFilterCount() const = 0;
-	virtual void 				decrementFilterCount() = 0;
-
-	// +-------------------------------------------------------------------+
-	// + Default
-	// +-------------------------------------------------------------------+
-	virtual bool 				isDefault() const = 0;
-	virtual bool 				isNotDefault() const = 0;
-	virtual void 				markDefault() = 0;
-	virtual void 				resetDefault() = 0;
-
-	// +-------------------------------------------------------------------+
-	// + Generation
-	// +-------------------------------------------------------------------+
-	virtual S32 				getCurrentGeneration() const = 0;
-	virtual S32 				getFirstSuccessGeneration() const = 0;
-	virtual S32 				getFirstRequiredGeneration() const = 0;
-};
-
-class LLFolderViewModelInterface
-{
-public:
-	virtual void requestSortAll() = 0;
-
-	virtual void sort(class LLFolderViewFolder*) = 0;
-	virtual void filter() = 0;
-
-	virtual bool contentsReady() = 0;
-	virtual void setFolderView(LLFolderView* folder_view) = 0;
-	virtual LLFolderViewFilter* getFilter() = 0;
-	virtual const LLFolderViewFilter* getFilter() const = 0;
-	virtual std::string getStatusText() = 0;
-};
-
-class LLFolderViewModelCommon : public LLFolderViewModelInterface
-{
-public:
-	LLFolderViewModelCommon()
-	:	mTargetSortVersion(0),
-		mFolderView(NULL)
-	{}
-
-	virtual void requestSortAll()
-	{
-		// sort everything
-		mTargetSortVersion++;
-	}
-	virtual std::string getStatusText();
-	virtual void filter();
-
-	void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
-
-protected:
-	bool needsSort(class LLFolderViewModelItem* item);
-
-	S32 mTargetSortVersion;
-	LLFolderView* mFolderView;
-
-};
-
-template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
-class LLFolderViewModel : public LLFolderViewModelCommon
-{
-public:
-	LLFolderViewModel(){}
-	virtual ~LLFolderViewModel() {}
-	
-	typedef SORT_TYPE		SortType;
-	typedef ITEM_TYPE		ItemType;
-	typedef FOLDER_TYPE		FolderType;
-	typedef FILTER_TYPE		FilterType;
-	
-	virtual SortType& getSorter()					 { return mSorter; }
-	virtual const SortType& getSorter() const 		 { return mSorter; }
-	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
-
-	virtual FilterType* getFilter() 				 { return &mFilter; }
-	virtual const FilterType* getFilter() const		 { return &mFilter; }
-	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
-
-	// TODO RN: remove this and put all filtering logic in view model
-	// add getStatusText and isFiltering()
-	virtual bool contentsReady()					{ return true; }
-
-
-	struct ViewModelCompare
-	{
-		ViewModelCompare(const SortType& sorter)
-		:	mSorter(sorter)
-		{}
-		
-		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
-		{
-			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
-		}
-
-		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
-		{
-			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
-		}
-
-		const SortType& mSorter;
-	};
-
-	void sort(LLFolderViewFolder* folder)
-	{
-		if (needsSort(folder->getViewModelItem()))
-		{
-			folder->sortFolders(ViewModelCompare(getSorter()));
-			folder->sortItems(ViewModelCompare(getSorter()));
-			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
-			folder->requestArrange();
-		}
-	}
-
-protected:
-	SortType		mSorter;
-	FilterType		mFilter;
-};
-
-// This is am abstract base class that users of the folderview classes
-// would use to bridge the folder view with the underlying data
-class LLFolderViewModelItem
-{
-public:
-	virtual ~LLFolderViewModelItem( void ) {};
-
-	virtual void update() {}	//called when drawing
-	virtual const std::string& getName() const = 0;
-	virtual const std::string& getDisplayName() const = 0;
-	virtual const std::string& getSearchableName() const = 0;
-
-	virtual LLPointer<LLUIImage> getIcon() const = 0;
-	virtual LLPointer<LLUIImage> getIconOpen() const { return getIcon(); }
-	virtual LLPointer<LLUIImage> getIconOverlay() const { return NULL; }
-
-	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
-	virtual std::string getLabelSuffix() const = 0;
-
-	virtual void openItem( void ) = 0;
-	virtual void closeItem( void ) = 0;
-	virtual void selectItem(void) = 0;
-
-	virtual BOOL isItemRenameable() const = 0;
-	virtual BOOL renameItem(const std::string& new_name) = 0;
-
-	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder
-	virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
-
-	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed
-	virtual BOOL removeItem() = 0;
-	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
-
-	virtual BOOL isItemCopyable() const = 0;
-	virtual BOOL copyToClipboard() const = 0;
-	virtual BOOL cutToClipboard() const = 0;
-
-	virtual BOOL isClipboardPasteable() const = 0;
-	virtual void pasteFromClipboard() = 0;
-	virtual void pasteLinkFromClipboard() = 0;
-
-	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
-	
-	virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
-
-	virtual bool filter( LLFolderViewFilter& filter) = 0;
-	virtual bool passedFilter(S32 filter_generation = -1) = 0;
-	virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
-	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) = 0;
-	virtual void dirtyFilter() = 0;
-
-	virtual S32	getLastFilterGeneration() const = 0;
-
-	// This method should be called when a drag begins. returns TRUE
-	// if the drag can begin, otherwise FALSE.
-	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
-	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
-	
-	virtual bool hasChildren() const = 0;
-	virtual void addChild(LLFolderViewModelItem* child) = 0;
-	virtual void removeChild(LLFolderViewModelItem* child) = 0;
-
-	// This method will be called to determine if a drop can be
-	// performed, and will set drop to TRUE if a drop is
-	// requested. Returns TRUE if a drop is possible/happened,
-	// otherwise FALSE.
-	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
-							EDragAndDropType cargo_type,
-							void* cargo_data,
-							std::string& tooltip_msg) = 0;
-
-	virtual void requestSort() = 0;
-	virtual S32 getSortVersion() = 0;
-	virtual void setSortVersion(S32 version) = 0;
-	virtual void setParent(LLFolderViewModelItem* parent) = 0;
-
-protected:
-
-	friend class LLFolderViewItem;
-	virtual void setFolderViewItem(LLFolderViewItem* folder_view_item) = 0;
-
-};
-
-class LLFolderViewModelItemCommon : public LLFolderViewModelItem
-{
-public:
-	LLFolderViewModelItemCommon()
-	:	mSortVersion(-1),
-		mPassedFilter(true),
-		mPassedFolderFilter(true),
-		mFolderViewItem(NULL),
-		mLastFilterGeneration(-1),
-		mMostFilteredDescendantGeneration(-1),
-		mParent(NULL)
-	{
-		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
-	}
-
-	void requestSort() { mSortVersion = -1; }
-	S32 getSortVersion() { return mSortVersion; }
-	void setSortVersion(S32 version) { mSortVersion = version;}
-
-	S32	getLastFilterGeneration() const { return mLastFilterGeneration; }
-	void dirtyFilter()
-	{
-		mLastFilterGeneration = -1;
-
-		// bubble up dirty flag all the way to root
-		if (mParent)
-		{
-			mParent->dirtyFilter();
-		}	
-	}
-	virtual void addChild(LLFolderViewModelItem* child) 
-	{ 
-		mChildren.push_back(child); 
-		child->setParent(this); 
-	}
-	virtual void removeChild(LLFolderViewModelItem* child) 
-	{ 
-		mChildren.remove(child); 
-		child->setParent(NULL); 
-	}
-
-protected:
-	virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
-
-	S32						mSortVersion;
-	bool					mPassedFilter;
-	bool					mPassedFolderFilter;
-
-	S32						mLastFilterGeneration;
-	S32						mMostFilteredDescendantGeneration;
-
-
-	typedef std::list<LLFolderViewModelItem*> child_list_t;
-	child_list_t			mChildren;
-	LLFolderViewModelItem*	mParent;
-
-	void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
-	LLFolderViewItem*		mFolderViewItem;
-};
-
-
-#endif // LLFOLDERVIEWMODEL_H
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 99831c61bf..d23b4af8cb 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -28,12 +28,38 @@
 #include "llfolderviewmodelinventory.h"
 #include "llinventorymodelbackgroundfetch.h"
 #include "llinventorypanel.h"
+#include "lltooldraganddrop.h"
 
 //
 // class LLFolderViewModelInventory
 //
 static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort");
 
+bool LLFolderViewModelInventory::startDrag(std::vector<LLFolderViewModelItem*>& items)
+{
+	std::vector<EDragAndDropType> types;
+	uuid_vec_t cargo_ids;
+	std::vector<LLFolderViewModelItem*>::iterator item_it;
+	bool can_drag = true;
+	if (!items.empty())
+	{
+		for (item_it = items.begin(); item_it != items.end(); ++item_it)
+		{
+			EDragAndDropType type = DAD_NONE;
+			LLUUID id = LLUUID::null;
+			can_drag = can_drag && static_cast<LLFolderViewModelItemInventory*>(*item_it)->startDrag(&type, &id);
+
+			types.push_back(type);
+			cargo_ids.push_back(id);
+		}
+
+		LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, 
+			static_cast<LLFolderViewModelItemInventory*>(items.front())->getDragSource(), mTaskID); 
+	}
+	return can_drag;
+}
+
+
 void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
 {
 	LLFastTimer _(FTM_INVENTORY_SORT);
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index a8fe3f57ea..12a977b28b 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -29,6 +29,9 @@
 #define LL_LLFOLDERVIEWMODELINVENTORY_H
 
 #include "llinventoryfilter.h"
+#include "llinventory.h"
+#include "llwearabletype.h"
+#include "lltooldraganddrop.h"
 
 class LLFolderViewModelItemInventory
 	:	public LLFolderViewModelItemCommon
@@ -62,6 +65,10 @@ public:
 	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
 	virtual bool filter( LLFolderViewFilter& filter);
 	virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+
+	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
+	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
+
 protected:
 	class LLFolderViewModelInventory* mRootViewModel;
 };
@@ -97,11 +104,13 @@ class LLFolderViewModelInventory
 public:
 	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t;
 
-	virtual ~LLFolderViewModelInventory() {}
+	void setTaskID(const LLUUID& id) {mTaskID = id;}
 
 	void sort(LLFolderViewFolder* folder);
-
 	bool contentsReady();
+	bool startDrag(std::vector<LLFolderViewModelItem*>& items);
 
+private:
+	LLUUID mTaskID;
 };
 #endif // LL_LLFOLDERVIEWMODELINVENTORY_H
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 9615f3f44d..f68cf07d8c 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -65,8 +65,6 @@ public:
 	virtual const std::string& getSearchableName() const { return mName; }
 	virtual const LLUUID& getUUID() const { return mUUID; }
 	virtual time_t getCreationDate() const { return 0; }
-	virtual PermissionMask getPermissionMask() const { return PERM_ALL; }
-	virtual LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
 	virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
 	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
 	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
@@ -88,8 +86,6 @@ public:
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
 	virtual BOOL isUpToDate() const { return TRUE; }
 	virtual bool hasChildren() const { return FALSE; }
-	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
-	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
 
 	virtual bool potentiallyVisible() { return true; }
 	virtual bool filter( LLFolderViewFilter& filter) { return true; }
@@ -107,11 +103,6 @@ public:
 
 	void setVisibleIfDetached(BOOL visible);
 	
-	// This method should be called when a drag begins.
-	// Returns TRUE if the drag can begin, FALSE otherwise.
-	virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_PEOPLE; }
-	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const { return FALSE; }
-	
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
 	// requested. 
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index e235d9cf5f..b4a91ca0f7 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -35,6 +35,7 @@
 #include "llinventorypanel.h"
 #include "llviewercontrol.h"
 #include "llwearable.h"
+#include "lltooldraganddrop.h"
 
 class LLInventoryFilter;
 class LLInventoryPanel;
@@ -119,7 +120,7 @@ public:
 	void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items, 
 							 menuentry_vec_t &disabled_items, U32 flags);
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-        virtual LLToolDragAndDrop::ESource getDragSource() const;
+    virtual LLToolDragAndDrop::ESource getDragSource() const;
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index fed9893158..0aa67cddca 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -571,7 +571,24 @@ void LLInventoryPanel::onIdle(void *userdata)
 void LLInventoryPanel::idle(void* user_data)
 {
 	LLInventoryPanel* panel = (LLInventoryPanel*)user_data;
-	panel->mFolderRoot->doIdle();
+	panel->mFolderRoot->update();
+	// while dragging, update selection rendering to reflect single/multi drag status
+	if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+	{
+		EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
+		if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
+		{
+			panel->mFolderRoot->setShowSingleSelection(TRUE);
+		}
+		else
+		{
+			panel->mFolderRoot->setShowSingleSelection(FALSE);
+		}
+	}
+	else
+	{
+		panel->mFolderRoot->setShowSingleSelection(FALSE);
+	}
 }
 
 
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 002c0c1113..ca20051a51 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1557,7 +1557,6 @@ void LLPanelObjectInventory::reset()
 	LLFolderView::Params p;
 	p.name = "task inventory";
 	p.title = "task inventory";
-	p.task_id = getTaskUUID();
 	p.parent_panel = this;
 	p.tool_tip= LLTrans::getString("PanelContentsTooltip");
 	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
@@ -1823,6 +1822,7 @@ void LLPanelObjectInventory::refresh()
 		removeVOInventoryListener();
 		clearContents();
 	}
+	mInventoryViewModel.setTaskID(mTaskUUID);
 	//llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl;
 }
 
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 4a9e106687..cb59f704a5 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -58,6 +58,7 @@
 #include "lltoolmgr.h"
 #include "lltoolpipette.h"
 #include "llfiltereditor.h"
+#include "llwindow.h"
 
 #include "lltool.h"
 #include "llviewerwindow.h"
-- 
cgit v1.2.3


From d3edb1c466f42e2c46c77e43b26d700c6298b8d6 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 4 Jul 2012 00:30:00 -0700
Subject: CHUI-101 WIP Make LLFolderview general purpose partial fix for crash
 on startup

---
 indra/llui/llfolderview.cpp            |  4 ++--
 indra/llui/llfolderviewitem.h          |  2 +-
 indra/newview/llimfloatercontainer.cpp | 17 ++++++++++++++---
 indra/newview/llimfloatercontainer.h   |  1 +
 4 files changed, 18 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 0d3bc44ae4..990b79a30b 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1798,8 +1798,8 @@ void LLFolderView::update()
 	BOOL filter_finished = getViewModelItem()->passedFilter()
 						&& mViewModel->contentsReady();
 	if (filter_finished 
-		|| gFocusMgr.childHasKeyboardFocus(getParent()) // assume we are inside a scroll container
-		|| gFocusMgr.childHasMouseCapture(getParent()))
+		|| gFocusMgr.childHasKeyboardFocus(mParentPanel)
+		|| gFocusMgr.childHasMouseCapture(mParentPanel))
 	{
 		// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
 		mNeedsAutoSelect = FALSE;
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 9cb885066a..50d3e0580e 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -53,7 +53,7 @@ public:
 	{
 		Optional<LLUIImage*>						folder_arrow_image,
 													selection_image;
-		Optional<LLFolderView*>						root;
+		Mandatory<LLFolderView*>					root;
 		Mandatory<LLFolderViewModelItem*>			listener;
 
 		Optional<S32>								folder_indentation, // pixels
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 261b5f33a2..2b943df48f 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -47,8 +47,9 @@
 // LLIMFloaterContainer
 //
 LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
-:	LLMultiFloater(seed)
-	,mExpandCollapseBtn(NULL)
+:	LLMultiFloater(seed),
+	mExpandCollapseBtn(NULL),
+	mFolders(NULL)
 {
 	// Firstly add our self to IMSession observers, so we catch session events
     LLIMMgr::getInstance()->addSessionObserver(this);
@@ -90,6 +91,16 @@ BOOL LLIMFloaterContainer::postBuild()
 	
 	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
+	LLFolderView::Params p;
+	//TODO RN: define view model for conversations
+	//p.view_model = ?;
+	p.parent_panel = mConversationsListPanel;
+	p.rect = mConversationsListPanel->getLocalRect();
+	p.follows.flags = FOLLOWS_ALL;
+
+	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
+	mConversationsListPanel->addChild(mFolders);
+
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
 
@@ -512,7 +523,7 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
 	//params.icon = bridge->getIcon();
 	//params.icon_open = bridge->getOpenIcon();
 	//params.creation_date = bridge->getCreationDate();
-	//params.root = mFolderRoot;
+	params.root = mFolders;
 	params.listener = item;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index f68cf07d8c..890a115a04 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -194,6 +194,7 @@ private:
 	LLPanel* mConversationsListPanel;	// This is the widget we add items to (i.e. clickable title for each conversation)
 	conversations_items_map mConversationsItems;
 	conversations_widgets_map mConversationsWidgets;
+	LLFolderView* mFolders;
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H
-- 
cgit v1.2.3


From 22f8301b1dea787e0adda80b2625a8d7d9ddbda4 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Wed, 4 Jul 2012 17:18:48 +0300
Subject: CHUI-172 CHUI-183 FIX Disabled applying stored rect dimensions when
 Nearby chat is hosted in Conversations floater.

---
 indra/newview/llimconversation.cpp |  4 ----
 indra/newview/llnearbychat.cpp     | 32 +++++++++++++++++++-------------
 2 files changed, 19 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index acdd7ba46a..c855a844cf 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -254,9 +254,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 	if (mDragHandle)
 	{
 		mDragHandle->setTitleVisible(!is_hosted);
-		setCanDrag(!is_hosted);
 	}
-	setCanResize(!is_hosted);
 
 	// The button (>>) should be disabled for torn off P2P conversations.
 	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat);
@@ -349,8 +347,6 @@ void LLIMConversation::onOpen(const LLSD& key)
 		host_floater->collapseMessagesPane(false);
 	}
 
-	setCanResize(TRUE);
-
 	updateHeaderAndToolbar();
 }
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a81d6b4025..13e9eeee66 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -364,20 +364,18 @@ void LLNearbyChat::onOpen(const LLSD& key)
 
 bool LLNearbyChat::applyRectControl()
 {
-	bool rect_controlled = LLFloater::applyRectControl();
+	bool is_torn_off = getHost() == NULL;
 
-/*	if (!mNearbyChat->getVisible())
+	// Resize is limited to torn off floaters.
+	// A hosted floater is not resizable.
+	if (is_torn_off)
 	{
-		reshape(getRect().getWidth(), getMinHeight());
-		enableResizeCtrls(true, true, false);
-	}
-	else
-	{*/
 		enableResizeCtrls(true);
-		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-//	}
+	}
 	
-	return rect_controlled;
+	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
+
+	return LLFloater::applyRectControl();
 }
 
 void LLNearbyChat::onChatFontChange(LLFontGL* fontp)
@@ -408,9 +406,17 @@ void LLNearbyChat::showHistory()
 {
 	openFloater();
 	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-	reshape(getRect().getWidth(), mExpandedHeight);
-	enableResizeCtrls(true);
-	storeRectControl();
+
+	bool is_torn_off = getHost() == NULL;
+
+	// Reshape and enable resize controls only if it's a torn off floater.
+	// Otherwise all the size changes should be handled by LLIMFloaterContainer.
+	if (is_torn_off)
+	{
+		reshape(getRect().getWidth(), mExpandedHeight);
+		enableResizeCtrls(true);
+		storeRectControl();
+	}
 }
 
 std::string LLNearbyChat::getCurrentChat()
-- 
cgit v1.2.3


From e0eeed2680a2c6ba1055ac2a9f6465cb8004b7d6 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Wed, 4 Jul 2012 20:53:47 +0300
Subject: CHUI-189 FIXED (Blocked objects by name are not sorted correctly)

- Fixed sort criteria. It's needed to take into account that objects in mute list are represented by two types: LLMute::BY_NAME and LLMute::OBJECT
---
 indra/newview/llblocklist.cpp | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index cb68f677eb..0165a9c4e8 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -267,9 +267,15 @@ bool LLBlockListNameTypeComparator::doCompare(const LLBlockedListItem* blocked_i
 	LLMute::EType type1 = blocked_item1->getType();
 	LLMute::EType type2 = blocked_item2->getType();
 
-	if (type1 != type2)
+	// if mute type is LLMute::BY_NAME or LLMute::OBJECT it means that this mute is an object
+	bool both_mutes_are_objects = (LLMute::OBJECT == type1 || LLMute::BY_NAME == type1) && (LLMute::OBJECT == type2 || LLMute::BY_NAME == type2);
+
+	// mute types may be different, but since both LLMute::BY_NAME and LLMute::OBJECT types represent objects
+	// it's needed to perform additional checking of both_mutes_are_objects variable
+	if (type1 != type2 && !both_mutes_are_objects)
 	{
-		return type1 > type2;
+		// objects in block list go first, so return true if mute type is not an avatar
+		return LLMute::AGENT != type1;
 	}
 
 	return NAME_COMPARATOR.compare(blocked_item1, blocked_item2);
-- 
cgit v1.2.3


From 1fa326ccdbb9b99fedac0b4cdab232ec1fbe8d74 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Wed, 4 Jul 2012 21:13:25 +0300
Subject: CHUI-136 ADDITIONAL FIX (Implement new design for blocked list on the
 people floater)

- Disabled object profile functionality according to the spec
---
 indra/newview/llblocklist.cpp | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index 0165a9c4e8..066cb71677 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -195,7 +195,13 @@ bool LLBlockList::isActionEnabled(const LLSD& userdata)
 
 	const std::string command_name = userdata.asString();
 
-	if ("unblock_item" == command_name || "profile_item" == command_name)
+	if ("profile_item" == command_name)
+	{
+		LLBlockedListItem* item = getBlockedItem();
+		action_enabled = item && (LLMute::AGENT == item->getType());
+	}
+
+	if ("unblock_item" == command_name)
 	{
 		action_enabled = getSelectedItem() != NULL;
 	}
@@ -227,10 +233,6 @@ void LLBlockList::onCustomAction(const LLSD& userdata)
 			LLAvatarActions::showProfile(item->getUUID());
 			break;
 
-		case LLMute::OBJECT:
-			LLFloaterSidePanelContainer::showPanel("inventory", LLSD().with("id", item->getUUID()));
-			break;
-
 		default:
 			break;
 		}
-- 
cgit v1.2.3


From ff448aed525b8c1d2f05b6a5816ba6855707e4b8 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 5 Jul 2012 19:23:34 +0300
Subject: CHUI-200 FIXED Show correct and localized name of the nearby chat In
 the conversations list

---
 indra/newview/llimfloatercontainer.cpp | 4 ----
 indra/newview/llnearbychat.cpp         | 5 ++++-
 2 files changed, 4 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 08ace601a3..134623722c 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -534,10 +534,6 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
     mFloater(floaterp),
     mContainer(containerp)
 {
-    // Hack: the nearby chat has no name so we catch that case and impose one
-	// Of course, we won't be doing this in the final code
-	if (name == "")
-		mName = "Nearby Chat";
 }
 
 // Virtual action callbacks
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 13e9eeee66..644304aff3 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -158,6 +158,10 @@ BOOL LLNearbyChat::postBuild()
 
 	enableResizeCtrls(true, true, false);
 
+	// title must be defined BEFORE call addToHost() because
+	// it is used for show the item's name in the conversations list
+	setTitle(getString("NearbyChatTitle"));
+
 	addToHost();
 
 	//for menu
@@ -182,7 +186,6 @@ BOOL LLNearbyChat::postBuild()
 		loadHistory();
 	}
 
-	setTitle(getString("NearbyChatTitle"));
 
 	return LLIMConversation::postBuild();
 }
-- 
cgit v1.2.3


From 89d8a49f28dac5d99ec05a5201203ec57f72be02 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 5 Jul 2012 14:14:35 +0300
Subject: CHUI-197 FIXED Conversation names updating when checked corresponding
 preference

---
 indra/newview/llimfloatercontainer.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 134623722c..30a77bef98 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -104,6 +104,8 @@ BOOL LLIMFloaterContainer::postBuild()
 
 	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
 	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
+	LLAvatarNameCache::addUseDisplayNamesCallback(
+			boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
 	return TRUE;
 }
-- 
cgit v1.2.3


From c76c73770bf1a4095100cdb79021826ebebbd2f0 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 4 Jul 2012 17:57:46 +0300
Subject: CHUI-195 FIXED Starting ad-hoc conference call does not open
 Conversations floater

---
 indra/newview/llimview.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 79018ec366..cdbb7c7cca 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2583,7 +2583,6 @@ LLUUID LLIMMgr::addSession(
 	LLDynamicArray<LLUUID> ids;
 	ids.put(other_participant_id);
 	LLUUID session_id = addSession(name, dialog, other_participant_id, ids, voice);
-	notifyObserverSessionVoiceOrIMStarted(session_id);
 	return session_id;
 }
 
@@ -2653,6 +2652,8 @@ LLUUID LLIMMgr::addSession(
 		noteMutedUsers(session_id, ids);
 	}
 
+	notifyObserverSessionVoiceOrIMStarted(session_id);
+
 	return session_id;
 }
 
-- 
cgit v1.2.3


From 73ad740443e615467f7e14fe4fb3f04d8abe2f9c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 4 Jul 2012 16:45:02 +0300
Subject: CHUI-170 FIXED Save Torn off state of Nearby Chat between sessions

---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 indra/newview/llimconversation.cpp      |  8 +-------
 indra/newview/llimconversation.h        |  2 +-
 indra/newview/llimfloatercontainer.cpp  |  5 ++---
 indra/newview/llnearbychat.cpp          | 27 ++++++++++++++++++++++++---
 indra/newview/llnearbychat.h            |  2 ++
 6 files changed, 41 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4a586b02af..da3ff2d1ee 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1639,6 +1639,17 @@
       <key>Value</key>
       <string />
     </map>
+    <key>NearbyChatIsNotTornOff</key>
+    <map>
+      <key>Comment</key>
+      <string>saving torn-off state of the nearby chat between sessions</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>CloseChatOnReturn</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index c855a844cf..3c6c5c3898 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -55,12 +55,6 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)
 {
 	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
 			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2));
-//	mCommitCallbackRegistrar.add("IMSession.ExpCollapseBtn.Click",
-//			boost::bind(&LLIMConversation::onSlide,  this));
-//	mCommitCallbackRegistrar.add("IMSession.CloseBtn.Click",
-//			boost::bind(&LLFloater::onClickClose, this));
-	mCommitCallbackRegistrar.add("IMSession.TearOffBtn.Click",
-			boost::bind(&LLIMConversation::onTearOffClicked, this));
 	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
 			boost::bind(&LLIMConversation::onIMCompactExpandedMenuItemCheck, this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
@@ -366,7 +360,7 @@ void LLIMConversation::onClose(bool app_quitting)
 
 void LLIMConversation::onTearOffClicked()
 {
-	onClickTearOff(this);
+	LLFloater::onClickTearOff(this);
 	updateHeaderAndToolbar();
 }
 
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 50663137ac..682779a44b 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -78,7 +78,7 @@ protected:
 	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
 	static void onSlide(LLIMConversation *self);
-	void onTearOffClicked();
+	virtual void onTearOffClicked();
 
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 30a77bef98..546eccbd04 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -302,9 +302,8 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	if (visible)
 	{
 		// Make sure we have the Nearby Chat present when showing the conversation container
-		LLUUID nearbychat_uuid = LLUUID::null;	// Hacky but true: the session id for nearby chat is always null
-		LLFloater* floaterp = findConversationItem(nearbychat_uuid);
-		if (floaterp == NULL)
+		LLFloater* nearby_chat = LLFloaterReg::findInstance("chat_bar");
+		if (nearby_chat == NULL)
 		{
 			// If not found, force the creation of the nearby chat conversation panel
 			// *TODO: find a way to move this to XML as a default panel or something like that
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 644304aff3..384762549a 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -345,15 +345,36 @@ void LLNearbyChat::enableDisableCallBtn()
 	getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/);
 }
 
+void LLNearbyChat::onTearOffClicked()
+{
+	LLIMConversation::onTearOffClicked();
+
+	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+
+	// see CHUI-170: Save torn-off state of the nearby chat between sessions
+	BOOL in_the_multifloater = (getHost() == im_box);
+	gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
+}
+
 void LLNearbyChat::addToHost()
 {
-	if (LLIMConversation::isChatMultiTab())
+	if ( LLIMConversation::isChatMultiTab())
 	{
 		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-
 		if (im_box)
 		{
-			im_box->addFloater(this, FALSE, LLTabContainer::END);
+			if (gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
+			{
+				im_box->addFloater(this, TRUE, LLTabContainer::END);
+			}
+			else
+			{
+				// setting of the "potential" host: this sequence sets
+				// LLFloater::mHostHandle = NULL (a current host), but
+				// LLFloater::mLastHostHandle = im_box (a "future" host)
+				setHost(im_box);
+				setHost(NULL);
+			}
 		}
 	}
 }
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 61404df942..90feb71488 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -101,6 +101,8 @@ protected:
 
 	void onToggleNearbyChatPanel();
 
+	/*virtual*/ void onTearOffClicked();
+
 	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
 	EChatType processChatTypeTriggers(EChatType type, std::string &str);
 
-- 
cgit v1.2.3


From ec15ff6350c0997421cf2884e40aa9feaa070d4d Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 5 Jul 2012 16:42:20 -0700
Subject: CHUI-98 : WIP, use the refactored folder view for conversation view
 list

---
 indra/llui/llfolderview.cpp            | 36 ++++++++++-----
 indra/newview/llimfloatercontainer.cpp | 23 +++++++++-
 indra/newview/llimfloatercontainer.h   | 83 ++++++++++++++++++++++++++++++++++
 3 files changed, 128 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 990b79a30b..92e3b7a8e9 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -320,10 +320,10 @@ S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
 
 	LLFolderViewFolder::arrange(&mMinWidth, &target_height);
 
-	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
+	LLRect scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 	reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
 
-	LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
+	LLRect new_scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 	if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
 	{
 		reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
@@ -945,7 +945,7 @@ void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
 	mAutoOpenItems.push(item);
 	
 	item->setOpen(TRUE);
-	LLRect content_rect = mScrollContainer->getContentWindowRect();
+	LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 	LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
 	scrollToShowItem(item, constraint_rect);
 }
@@ -1225,25 +1225,37 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 
 	case KEY_PAGE_UP:
 		mSearchString.clear();
-		mScrollContainer->pageUp(30);
+		if (mScrollContainer)
+		{
+			mScrollContainer->pageUp(30);
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_PAGE_DOWN:
 		mSearchString.clear();
-		mScrollContainer->pageDown(30);
+		if (mScrollContainer)
+		{
+			mScrollContainer->pageDown(30);
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_HOME:
 		mSearchString.clear();
-		mScrollContainer->goToTop();
+		if (mScrollContainer)
+		{
+			mScrollContainer->goToTop();
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_END:
 		mSearchString.clear();
-		mScrollContainer->goToBottom();
+		if (mScrollContainer)
+		{
+			mScrollContainer->goToBottom();
+		}
 		break;
 
 	case KEY_DOWN:
@@ -1719,8 +1731,8 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
 
 LLRect LLFolderView::getVisibleRect()
 {
-	S32 visible_height = mScrollContainer->getRect().getHeight();
-	S32 visible_width = mScrollContainer->getRect().getWidth();
+	S32 visible_height = (mScrollContainer ? mScrollContainer->getRect().getHeight() : 0);
+	S32 visible_width  = (mScrollContainer ? mScrollContainer->getRect().getWidth()  : 0);
 	LLRect visible_rect;
 	visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height);
 	return visible_rect;
@@ -1816,7 +1828,7 @@ void LLFolderView::update()
 			// lets pin it!
 			mPinningSelectedItem = TRUE;
 
-			LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
+			LLRect visible_content_rect = (mScrollContainer ? mScrollContainer->getVisibleContentRect() : LLRect());
 			LLFolderViewItem* selected_item = mSelectedItems.back();
 
 			LLRect item_rect;
@@ -1831,7 +1843,7 @@ void LLFolderView::update()
 			else
 			{
 				// otherwise we just want it onscreen somewhere
-				LLRect content_rect = mScrollContainer->getContentWindowRect();
+				LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 				mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
 			}
 		}
@@ -1854,7 +1866,7 @@ void LLFolderView::update()
 	else
 	{
 		// during normal use (page up/page down, etc), just try to fit item on screen
-		LLRect content_rect = mScrollContainer->getContentWindowRect();
+		LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 		constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
 	}
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 2b943df48f..be38eddbaf 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -91,12 +91,14 @@ BOOL LLIMFloaterContainer::postBuild()
 	
 	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
+	mRoot = new LLConversationItem();
 	LLFolderView::Params p;
-	//TODO RN: define view model for conversations
-	//p.view_model = ?;
+	// CHUI-98 : View Model for conversations
+	p.view_model = &mConversationViewModel;
 	p.parent_panel = mConversationsListPanel;
 	p.rect = mConversationsListPanel->getLocalRect();
 	p.follows.flags = FOLLOWS_ALL;
+	p.listener = mRoot;
 
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	mConversationsListPanel->addChild(mFolders);
@@ -544,6 +546,15 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
 		mName = "Nearby Chat";
 }
 
+LLConversationItem::LLConversationItem() :
+	mName(""),
+	mUUID(),
+	mFloater(NULL),
+	mContainer(NULL)
+{
+}
+
+
 // Virtual action callbacks
 void LLConversationItem::selectItem(void)
 {
@@ -589,4 +600,12 @@ void LLConversationItem::showProperties(void)
 {
 }
 
+bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
+{
+	// We compare only by name for the moment
+	// *TODO : Implement the sorting by date
+	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+	return (compare < 0);
+}
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 890a115a04..f146e65897 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -57,6 +57,7 @@ class LLConversationItem : public LLFolderViewModelItemCommon
 {
 public:
 	LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
+	LLConversationItem();
 	virtual ~LLConversationItem() {}
 
 	// Stub those things we won't really be using in this conversation context
@@ -120,6 +121,86 @@ private:
     LLFloater* mFloater;
     LLIMFloaterContainer* mContainer;
 };
+
+// We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
+// We just stubb everything for the moment.
+class LLConversationFilter : public LLFolderViewFilter
+{
+public:
+		
+	enum ESortOrderType
+	{
+		SO_NAME = 0,						// Sort inventory by name
+		SO_DATE = 0x1,						// Sort inventory by date
+	};
+
+	LLConversationFilter() { mEmpty = ""; }
+	~LLConversationFilter() {}
+		
+	bool 				check(const LLFolderViewModelItem* item) { return true; }
+	bool				checkFolder(const LLFolderViewModelItem* folder) const { return true; }
+	void 				setEmptyLookupMessage(const std::string& message) { }
+	std::string			getEmptyLookupMessage() const { return mEmpty; }
+	bool				showAllResults() const { return true; }
+		
+	bool 				isActive() const { return false; }
+	bool 				isModified() const { return false; }
+	void 				clearModified() { }
+	const std::string& 	getName() const { return mEmpty; }
+	const std::string& 	getFilterText() { return mEmpty; }
+	void 				setModified(EFilterModified behavior = FILTER_RESTART) { }
+		
+	void 				setFilterCount(S32 count) { }
+	S32 				getFilterCount() const { return 0; }
+	void 				decrementFilterCount() { }
+		
+	bool 				isDefault() const { return true; }
+	bool 				isNotDefault() const { return false; }
+	void 				markDefault() { }
+	void 				resetDefault() { }
+		
+	S32 				getCurrentGeneration() const { return 0; }
+	S32 				getFirstSuccessGeneration() const { return 0; }
+	S32 				getFirstRequiredGeneration() const { return 0; }
+private:
+	std::string mEmpty;
+};
+
+class LLConversationSort
+{
+public:
+	LLConversationSort(U32 order = 0)
+	:	mSortOrder(order),
+	mByDate(false),
+	mByName(false)
+	{
+		mByDate = (order & LLConversationFilter::SO_DATE);
+		mByName = (order & LLConversationFilter::SO_NAME);
+	}
+	
+	bool isByDate() const { return mByDate; }
+	U32 getSortOrder() const { return mSortOrder; }
+	
+	bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
+private:
+	U32  mSortOrder;
+	bool mByDate;
+	bool mByName;
+};
+
+class LLConversationViewModel
+:	public LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter>
+{
+public:
+	typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t;
+	
+	void sort(LLFolderViewFolder* folder) { } // *TODO : implement conversation sort
+	bool contentsReady() { return true; }	// *TODO : we need to check that participants names are available somewhat
+	bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items
+	
+private:
+};
+
 // CHUI-137 : End
 
 class LLIMFloaterContainer
@@ -189,6 +270,8 @@ public:
 	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
 	LLFloater* findConversationItem(LLUUID& uuid);
 private:
+	LLConversationViewModel mConversationViewModel;
+	LLConversationItem* mRoot; 
 	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 	// Conversation list data
 	LLPanel* mConversationsListPanel;	// This is the widget we add items to (i.e. clickable title for each conversation)
-- 
cgit v1.2.3


From c3e048a2f14b08ec4428ea9f5a10f17de154e1fc Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 6 Jul 2012 13:30:05 +0300
Subject: build fix

---
 indra/newview/llimfloatercontainer.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 546eccbd04..f3b97776fc 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -37,6 +37,7 @@
 #include "llagent.h"
 #include "llavataractions.h"
 #include "llavatariconctrl.h"
+#include "llavatarnamecache.h"
 #include "llgroupiconctrl.h"
 #include "llfloateravatarpicker.h"
 #include "llimview.h"
-- 
cgit v1.2.3


From 9ab042dd1d003da15dd579f366db04d4aae3ff6b Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 6 Jul 2012 17:49:02 +0300
Subject: CHUI-196 FIXED (Chat text entry area gets resized unexpectedly with
 certain user display names)

- Fixed label length calculating
---
 indra/llui/lltextbase.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 3b3bc64c5b..a7bc6bbb77 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -510,7 +510,7 @@ void LLTextBase::drawText()
 	}
 	else if (text_len <= 0 && !mLabel.empty() && !hasFocus())
 	{
-		text_len = mLabel.length();
+		text_len = mLabel.getWString().length();
 	}
 
 	S32 selection_left = -1;
@@ -1816,7 +1816,7 @@ void LLTextBase::resetLabel()
 		style->setColor(mTentativeFgColor);
 		LLStyleConstSP sp(style);
 
-		LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, getLabel().length() + 1, *this);
+		LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, mLabel.getWString().length() + 1, *this);
 		insertSegment(label);
 	}
 }
@@ -2988,7 +2988,7 @@ const LLWString& LLLabelTextSegment::getWText()	const
 /*virtual*/
 const S32 LLLabelTextSegment::getLength() const
 {
-	return mEditor.getLabel().length();
+	return mEditor.getWlabel().length();
 }
 
 //
-- 
cgit v1.2.3


From 0b8a57cab8628ba064a14250a140ca9615669d2c Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Sat, 7 Jul 2012 00:50:31 +0300
Subject: Linux build fix. LLFolderViewModelItem placed before the call to a
 method of this class in LLFolderViewModel::sort().

---
 indra/llui/llfolderviewmodel.h | 207 ++++++++++++++++++++---------------------
 1 file changed, 103 insertions(+), 104 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 0f5f9a1f50..268ae8eea8 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -107,110 +107,6 @@ public:
 	virtual S32 				getFirstRequiredGeneration() const = 0;
 };
 
-class LLFolderViewModelInterface
-{
-public:
-	virtual ~LLFolderViewModelInterface() {}
-	virtual void requestSortAll() = 0;
-
-	virtual void sort(class LLFolderViewFolder*) = 0;
-	virtual void filter() = 0;
-
-	virtual bool contentsReady() = 0;
-	virtual void setFolderView(LLFolderView* folder_view) = 0;
-	virtual LLFolderViewFilter* getFilter() = 0;
-	virtual const LLFolderViewFilter* getFilter() const = 0;
-	virtual std::string getStatusText() = 0;
-
-	virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
-};
-
-class LLFolderViewModelCommon : public LLFolderViewModelInterface
-{
-public:
-	LLFolderViewModelCommon()
-	:	mTargetSortVersion(0),
-		mFolderView(NULL)
-	{}
-
-	virtual void requestSortAll()
-	{
-		// sort everything
-		mTargetSortVersion++;
-	}
-	virtual std::string getStatusText();
-	virtual void filter();
-
-	void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
-
-protected:
-	bool needsSort(class LLFolderViewModelItem* item);
-
-	S32 mTargetSortVersion;
-	LLFolderView* mFolderView;
-
-};
-
-template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
-class LLFolderViewModel : public LLFolderViewModelCommon
-{
-public:
-	LLFolderViewModel(){}
-	virtual ~LLFolderViewModel() {}
-	
-	typedef SORT_TYPE		SortType;
-	typedef ITEM_TYPE		ItemType;
-	typedef FOLDER_TYPE		FolderType;
-	typedef FILTER_TYPE		FilterType;
-	
-	virtual SortType& getSorter()					 { return mSorter; }
-	virtual const SortType& getSorter() const 		 { return mSorter; }
-	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
-
-	virtual FilterType* getFilter() 				 { return &mFilter; }
-	virtual const FilterType* getFilter() const		 { return &mFilter; }
-	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
-
-	// TODO RN: remove this and put all filtering logic in view model
-	// add getStatusText and isFiltering()
-	virtual bool contentsReady()					{ return true; }
-
-
-	struct ViewModelCompare
-	{
-		ViewModelCompare(const SortType& sorter)
-		:	mSorter(sorter)
-		{}
-		
-		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
-		{
-			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
-		}
-
-		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
-		{
-			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
-		}
-
-		const SortType& mSorter;
-	};
-
-	void sort(LLFolderViewFolder* folder)
-	{
-		if (needsSort(folder->getViewModelItem()))
-		{
-			folder->sortFolders(ViewModelCompare(getSorter()));
-			folder->sortItems(ViewModelCompare(getSorter()));
-			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
-			folder->requestArrange();
-		}
-	}
-
-protected:
-	SortType		mSorter;
-	FilterType		mFilter;
-};
-
 // This is am abstract base class that users of the folderview classes
 // would use to bridge the folder view with the underlying data
 class LLFolderViewModelItem
@@ -349,5 +245,108 @@ protected:
 	LLFolderViewItem*		mFolderViewItem;
 };
 
+class LLFolderViewModelInterface
+{
+public:
+	virtual ~LLFolderViewModelInterface() {}
+	virtual void requestSortAll() = 0;
+
+	virtual void sort(class LLFolderViewFolder*) = 0;
+	virtual void filter() = 0;
+
+	virtual bool contentsReady() = 0;
+	virtual void setFolderView(LLFolderView* folder_view) = 0;
+	virtual LLFolderViewFilter* getFilter() = 0;
+	virtual const LLFolderViewFilter* getFilter() const = 0;
+	virtual std::string getStatusText() = 0;
+
+	virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
+};
+
+class LLFolderViewModelCommon : public LLFolderViewModelInterface
+{
+public:
+	LLFolderViewModelCommon()
+	:	mTargetSortVersion(0),
+		mFolderView(NULL)
+	{}
+
+	virtual void requestSortAll()
+	{
+		// sort everything
+		mTargetSortVersion++;
+	}
+	virtual std::string getStatusText();
+	virtual void filter();
+
+	void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
+
+protected:
+	bool needsSort(class LLFolderViewModelItem* item);
+
+	S32 mTargetSortVersion;
+	LLFolderView* mFolderView;
+
+};
+
+template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
+class LLFolderViewModel : public LLFolderViewModelCommon
+{
+public:
+	LLFolderViewModel(){}
+	virtual ~LLFolderViewModel() {}
+
+	typedef SORT_TYPE		SortType;
+	typedef ITEM_TYPE		ItemType;
+	typedef FOLDER_TYPE		FolderType;
+	typedef FILTER_TYPE		FilterType;
+
+	virtual SortType& getSorter()					 { return mSorter; }
+	virtual const SortType& getSorter() const 		 { return mSorter; }
+	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
+
+	virtual FilterType* getFilter() 				 { return &mFilter; }
+	virtual const FilterType* getFilter() const		 { return &mFilter; }
+	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
+
+	// TODO RN: remove this and put all filtering logic in view model
+	// add getStatusText and isFiltering()
+	virtual bool contentsReady()					{ return true; }
+
+
+	struct ViewModelCompare
+	{
+		ViewModelCompare(const SortType& sorter)
+		:	mSorter(sorter)
+		{}
+
+		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		const SortType& mSorter;
+	};
+
+	void sort(LLFolderViewFolder* folder)
+	{
+		if (needsSort(folder->getViewModelItem()))
+		{
+			folder->sortFolders(ViewModelCompare(getSorter()));
+			folder->sortItems(ViewModelCompare(getSorter()));
+			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
+			folder->requestArrange();
+		}
+	}
+
+protected:
+	SortType		mSorter;
+	FilterType		mFilter;
+};
 
 #endif // LLFOLDERVIEWMODEL_H
-- 
cgit v1.2.3


From c9e11635488720626601b7b4a7926f09031a6908 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Sat, 7 Jul 2012 01:10:30 +0300
Subject: Another Linux build fix.

---
 indra/llui/llfolderview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 92e3b7a8e9..8ade17b763 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1927,7 +1927,7 @@ void LLFolderView::updateRenamerPosition()
 		screenPointToLocal( x, y, &x, &y );
 		mRenamer->setOrigin( x, y );
 
-		LLRect scroller_rect(0, 0, LLUI::getWindowSize().mV[VX], 0);
+		LLRect scroller_rect(0, 0, (S32)LLUI::getWindowSize().mV[VX], 0);
 		if (mScrollContainer)
 		{
 			scroller_rect = mScrollContainer->getContentWindowRect();
-- 
cgit v1.2.3


From b490266226ac79cc7570ff7ee921506e941cce16 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 9 Jul 2012 11:49:43 -0700
Subject: CHUI-98 : WIP. Clean up conversation list data structure and comments

---
 indra/newview/llimfloatercontainer.cpp | 14 +++++++-------
 indra/newview/llimfloatercontainer.h   | 10 +++++-----
 2 files changed, 12 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index be38eddbaf..d343c8be24 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -49,7 +49,7 @@
 LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 :	LLMultiFloater(seed),
 	mExpandCollapseBtn(NULL),
-	mFolders(NULL)
+	mConversationsRoot(NULL)
 {
 	// Firstly add our self to IMSession observers, so we catch session events
     LLIMMgr::getInstance()->addSessionObserver(this);
@@ -91,17 +91,17 @@ BOOL LLIMFloaterContainer::postBuild()
 	
 	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
-	mRoot = new LLConversationItem();
-	LLFolderView::Params p;
 	// CHUI-98 : View Model for conversations
+	LLConversationItem* base_item = new LLConversationItem();
+	LLFolderView::Params p;
 	p.view_model = &mConversationViewModel;
 	p.parent_panel = mConversationsListPanel;
 	p.rect = mConversationsListPanel->getLocalRect();
 	p.follows.flags = FOLLOWS_ALL;
-	p.listener = mRoot;
+	p.listener = base_item;
 
-	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
-	mConversationsListPanel->addChild(mFolders);
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+	mConversationsListPanel->addChild(mConversationsRoot);
 
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
@@ -525,7 +525,7 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
 	//params.icon = bridge->getIcon();
 	//params.icon_open = bridge->getOpenIcon();
 	//params.creation_date = bridge->getCreationDate();
-	params.root = mFolders;
+	params.root = mConversationsRoot;
 	params.listener = item;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index f146e65897..8f0ec27905 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -264,20 +264,20 @@ private:
 	LLLayoutPanel* mConversationsPane;
 	LLLayoutStack* mConversationsStack;
 	
-	// CHUI-137 : Temporary implementation of conversations list
+	// Conversation list implementation
 public:
 	void removeConversationListItem(LLFloater* floaterp, bool change_focus = true);
 	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
 	LLFloater* findConversationItem(LLUUID& uuid);
 private:
-	LLConversationViewModel mConversationViewModel;
-	LLConversationItem* mRoot; 
 	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
+
 	// Conversation list data
-	LLPanel* mConversationsListPanel;	// This is the widget we add items to (i.e. clickable title for each conversation)
+	LLPanel* mConversationsListPanel;	// This is the main widget we add conversation widget to
 	conversations_items_map mConversationsItems;
 	conversations_widgets_map mConversationsWidgets;
-	LLFolderView* mFolders;
+	LLConversationViewModel mConversationViewModel;
+	LLFolderView* mConversationsRoot;
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H
-- 
cgit v1.2.3


From b203fe12f8ea19ee80d9de1ac6ff4ebbc3bdb493 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Tue, 10 Jul 2012 16:49:49 +0300
Subject: CHUI-201 FIX for crash when leaving a voice call via the end call
 prompt. Fixed the problem with confirmLeaveCallCallback() firing after the
 chat floater is destroyed.

---
 indra/newview/llimfloater.cpp | 57 +++++++++++++++++++++++--------------------
 indra/newview/llimfloater.h   |  2 ++
 2 files changed, 33 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index a506f0f9f3..23c97c5345 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -118,6 +118,35 @@ void LLIMFloater::refresh()
 	}
 }
 
+// virtual
+void LLIMFloater::onClickCloseBtn()
+{
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
+				mSessionID);
+
+	if (session == NULL)
+	{
+		llwarns << "Empty session." << llendl;
+		return;
+	}
+
+	bool is_call_with_chat = session->isGroupSessionType()
+			|| session->isAdHocSessionType() || session->isP2PSessionType();
+
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+	if (is_call_with_chat && voice_channel != NULL
+			&& voice_channel->isActive())
+	{
+		LLSD payload;
+		payload["session_id"] = mSessionID;
+		LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+		return;
+	}
+
+	LLIMConversation::onClickCloseBtn();
+}
+
 /* static */
 void LLIMFloater::newIMCallback(const LLSD& data)
 {
@@ -407,8 +436,7 @@ void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids)
 		bool is_voice_call = voice_channel != NULL && voice_channel->isActive();
 
 		// then we can close the current session
-		gIMMgr->leaveSession(mSessionID);
-		LLIMConversation::onClose(false);
+		onClose(false);
 
 		// Start a new ad hoc voice call if we invite new participants to a P2P call,
 		// or start a text chat otherwise.
@@ -667,29 +695,6 @@ LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
 
 void LLIMFloater::onClose(bool app_quitting)
 {
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				mSessionID);
-
-	if (session == NULL)
-	{
-		llwarns << "Empty session." << llendl;
-		return;
-	}
-
-	bool is_call_with_chat = session->isGroupSessionType()
-			|| session->isAdHocSessionType() || session->isP2PSessionType();
-
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-	if (is_call_with_chat && voice_channel != NULL
-			&& voice_channel->isActive())
-	{
-		LLSD payload;
-		payload["session_id"] = mSessionID;
-		LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
-		return;
-	}
-
 	setTyping(false);
 
 	// The source of much argument and design thrashing
@@ -1278,7 +1283,7 @@ void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD&
 	const LLSD& payload = notification["payload"];
 	LLUUID session_id = payload["session_id"];
 
-	LLFloater* im_floater = LLFloaterReg::findInstance("impanel", session_id);
+	LLFloater* im_floater = findInstance(session_id);
 	if (option == 0 && im_floater != NULL)
 	{
 		im_floater->closeFloater();
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 2e8fc84746..2ac11ded20 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -132,6 +132,8 @@ private:
 
 	/*virtual*/ void refresh();
 
+	/*virtual*/ void onClickCloseBtn();
+
 	// Update the window title, input field help text, etc.
 	void updateSessionName(const std::string& ui_title, const std::string& ui_label);
 
-- 
cgit v1.2.3


From aafbf0d21301ccaf2e447a556d08e6686f519d4d Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Wed, 11 Jul 2012 17:19:22 +0300
Subject: CHUI-203 FIXED Conversations floater resizing when it is opened with
 FUI Chat button.

---
 indra/newview/llimfloatercontainer.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index e9144a4969..f54b3672e5 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -393,7 +393,9 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 {
 	LLRect floater_rect = getRect();
 	floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
-	setShape(floater_rect);
+
+	// Set by_user = true so that reshaped rect is saved in user_settings.
+	setShape(floater_rect, true);
 
 	updateResizeLimits();
 
-- 
cgit v1.2.3


From 6dff1477d5898c54ea0a08aa72bd099b628433e7 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 12 Jul 2012 16:36:01 +0300
Subject: CHUI-199 FIXED Save positioning of conversations between sessions

---
 indra/newview/llimconversation.cpp                 | 33 ++++++++++++++++++----
 indra/newview/llimconversation.h                   |  1 +
 indra/newview/llimfloatercontainer.cpp             | 19 -------------
 indra/newview/llimfloatercontainer.h               |  1 -
 .../skins/default/xui/en/floater_im_session.xml    |  1 +
 5 files changed, 30 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 3c6c5c3898..4774cc2d5a 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -219,16 +219,39 @@ void LLIMConversation::updateHeaderAndToolbar()
 {
 	bool is_hosted = getHost() != NULL;
 
-	if (is_hosted)
+	if (mWasHosted != is_hosted)
 	{
-		for (S32 i = 0; i < BUTTON_COUNT; i++)
+		mWasHosted = is_hosted;
+		LLView* floater_contents = getChild<LLView>("contents_view");
+		LLRect contents_rect = floater_contents->getRect();
+
+		if (is_hosted)
 		{
-			if (mButtons[i])
+			for (S32 i = 0; i < BUTTON_COUNT; i++)
 			{
-				// Hide the standard header buttons in a docked IM floater.
-				mButtons[i]->setVisible(false);
+				if (mButtons[i])
+				{
+					// Hide the standard header buttons in a docked IM floater.
+					mButtons[i]->setVisible(false);
+				}
 			}
+
+			// we don't show the header when the floater is hosted, so reshape floater contents
+			// to occupy the header space.
+			LLRect floater_rect = getRect();
+			contents_rect.setOriginAndSize(
+					contents_rect.mLeft,
+					contents_rect.mBottom,
+					floater_rect.getWidth(),
+					floater_rect.getHeight());
 		}
+		else
+		{
+			// reduce the floater contents height by header height
+			contents_rect.mTop -= getHeaderHeight();
+		}
+
+		floater_contents->setShape(contents_rect);
 	}
 
 	// Participant list should be visible only in torn off floaters.
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 682779a44b..19d1e523f0 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -91,6 +91,7 @@ protected:
 
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
+	bool mWasHosted;
 
 	LLLayoutPanel* mParticipantListPanel;
 	LLParticipantList* mParticipantList;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index f54b3672e5..bf0fc2f6c0 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -154,12 +154,6 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 	// Add a conversation list item in the left pane
 	addConversationListItem(floaterp->getTitle(), session_id, floaterp);
 	
-	LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
-
-	// we don't show the header when the floater is hosted,
-	// so reshape floater contents to occupy the header space
-	floater_contents->setShape(floaterp->getRect());
-
 	LLIconCtrl* icon = 0;
 
 	if(gAgent.isInGroup(session_id, TRUE))
@@ -185,19 +179,6 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 	mTabContainer->setTabImage(floaterp, icon);
 }
 
-// virtual
-void LLIMFloaterContainer::removeFloater(LLFloater* floaterp)
-{
-	LLMultiFloater::removeFloater(floaterp);
-
-	LLRect contents_rect = floaterp->getRect();
-
-	// reduce the floater contents height by header height
-	contents_rect.mTop -= floaterp->getHeaderHeight();
-
-	LLView* floater_contents = floaterp->getChild<LLView>("contents_view");
-	floater_contents->setShape(contents_rect);
-}
 
 void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
 {
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 0d988b5b73..b624b7558a 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -220,7 +220,6 @@ public:
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
-	/*virtual*/ void removeFloater(LLFloater* floaterp);
 
 	/*virtual*/ void tabClose();
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 32eb4ebdae..95f6708e96 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -9,6 +9,7 @@
  can_dock="false"
  can_minimize="true"
  can_close="true"
+ save_rect="true"
  visible="false"
  width="394"
  can_resize="true"
-- 
cgit v1.2.3


From af7de5dd9373a5a15c4d5ea107782e50eb3ce62c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 12 Jul 2012 19:06:29 +0300
Subject: CHUI-170 Workaround for the permanently showing of the nearbychat's
 name in a conversations list when that floater is torn-off

---
 indra/newview/llnearbychat.cpp | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 384762549a..1c81cdc4bc 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -363,6 +363,9 @@ void LLNearbyChat::addToHost()
 		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
 		if (im_box)
 		{
+			// Make sure the Nearby Chat is present in the conversations list
+			im_box->addConversationListItem(getTitle(), getKey(), this);
+
 			if (gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
 				im_box->addFloater(this, TRUE, LLTabContainer::END);
-- 
cgit v1.2.3


From 7f7a9b7cbae153b00b8a77d3d662257bf6152912 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 13 Jul 2012 20:06:35 +0300
Subject: CHUI-205 FIXED conversations selection in the conversations list.
 Each conversation item is added to the folder view which lists all
 conversations.

---
 indra/newview/llimfloatercontainer.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index bf0fc2f6c0..4f626cb5d2 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -438,6 +438,9 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 	LLFolderViewItem* widget = createConversationItemWidget(item);
 	mConversationsWidgets[floaterp] = widget;
 
+	// Add a new conversation widget to the root folder of a folder view.
+	mConversationsRoot->addItem(widget);
+
 	// Add it to the UI
 	widget->setVisible(TRUE);
 	mConversationsListPanel->addChild(widget);
@@ -460,7 +463,7 @@ void LLIMFloaterContainer::removeConversationListItem(LLFloater* floaterp, bool
 	if (widget_it != mConversationsWidgets.end())
 	{
 		LLFolderViewItem* widget = widget_it->second;
-		delete widget;
+		widget->destroyView();
 	}
 	
 	// Suppress the conversation items and widgets from their respective maps
-- 
cgit v1.2.3


From 56277fa43c6f6491d356c6fb8a0a0275d4cd00fc Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 13 Jul 2012 20:24:44 +0300
Subject: CHUI-206 FIXED Viewer crash when selecting to cut inventory item,
 then selecting to cut another inventory item

---
 indra/newview/llfolderviewmodelinventory.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index d23b4af8cb..dff1e1be90 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -158,22 +158,20 @@ bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite
 
 	if (item->getLastFilterGeneration() < filter_generation)
 	{
+		// recursive application of the filter for child items
+		item->filter( filter );
+
 		if (item->getLastFilterGeneration() >= must_pass_generation 
 			&& !item->passedFilter(must_pass_generation))
 		{
 			// failed to pass an earlier filter that was a subset of the current one
 			// go ahead and flag this item as done
-			item->filter(filter);
 			if (item->passedFilter())
 			{
 				llerrs << "Invalid shortcut in inventory filtering!" << llendl;
 			}
 			item->setPassedFilter(false, false, filter_generation);
 		}
-		else
-		{
-			item->filter( filter );
-		}
 	}
 
 	// track latest generation to pass any child items, for each folder up to root
-- 
cgit v1.2.3


From 8fd35a0a084303073bc40580d69c797c073fb4dc Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 13 Jul 2012 16:30:33 +0300
Subject: CHUI-207 FIXED cancellation of removal of the object that has already
 been removed

---
 indra/newview/llinventorypanel.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 0aa67cddca..ed370e9add 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -533,7 +533,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
 				// Remove the item's UI.
                 removeItemID(viewmodel_item->getUUID());
 				view_item->destroyView();
-                removeItemID(viewmodel_item->getUUID());
 			}
 		}
 	}
-- 
cgit v1.2.3


From b3ca0b09dcbe6189d6b1f6d0439b0d9d6f575007 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 17 Jul 2012 16:43:48 +0300
Subject: Fixed positioning of conversations into container

---
 indra/newview/llimconversation.cpp | 51 ++++++++++++++++++++++++--------------
 indra/newview/llimconversation.h   |  3 +++
 2 files changed, 36 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 4774cc2d5a..ec7e0ee6cb 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -43,6 +43,7 @@ const F32 REFRESH_INTERVAL = 0.2f;
 LLIMConversation::LLIMConversation(const LLUUID& session_id)
   : LLTransientDockableFloater(NULL, true, session_id)
   ,  mIsP2PChat(false)
+  ,  mWasHosted(false)
   ,  mExpandCollapseBtn(NULL)
   ,  mTearOffBtn(NULL)
   ,  mCloseBtn(NULL)
@@ -80,6 +81,8 @@ LLIMConversation::~LLIMConversation()
 
 BOOL LLIMConversation::postBuild()
 {
+	BOOL result;
+
 	mCloseBtn = getChild<LLButton>("close_btn");
 	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
 
@@ -103,6 +106,7 @@ BOOL LLIMConversation::postBuild()
 	}
 
 	buildParticipantList();
+
 	updateHeaderAndToolbar();
 
 	if (isChatMultiTab())
@@ -111,13 +115,14 @@ BOOL LLIMConversation::postBuild()
 		{
 			setCanClose(FALSE);
 		}
-		return LLFloater::postBuild();
+		result = LLFloater::postBuild();
 	}
 	else
 	{
-		return LLDockableFloater::postBuild();
+		result = LLDockableFloater::postBuild();
 	}
 
+	return result;
 }
 
 void LLIMConversation::draw()
@@ -215,7 +220,7 @@ bool LLIMConversation::onIMShowModesMenuItemEnable(const LLSD& userdata)
 	return (plain_text && (is_not_names || mIsP2PChat));
 }
 
-void LLIMConversation::updateHeaderAndToolbar()
+void LLIMConversation::hideOrShowTitle()
 {
 	bool is_hosted = getHost() != NULL;
 
@@ -227,23 +232,9 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 		if (is_hosted)
 		{
-			for (S32 i = 0; i < BUTTON_COUNT; i++)
-			{
-				if (mButtons[i])
-				{
-					// Hide the standard header buttons in a docked IM floater.
-					mButtons[i]->setVisible(false);
-				}
-			}
-
 			// we don't show the header when the floater is hosted, so reshape floater contents
 			// to occupy the header space.
-			LLRect floater_rect = getRect();
-			contents_rect.setOriginAndSize(
-					contents_rect.mLeft,
-					contents_rect.mBottom,
-					floater_rect.getWidth(),
-					floater_rect.getHeight());
+			contents_rect.mTop += getHeaderHeight();
 		}
 		else
 		{
@@ -253,6 +244,30 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 		floater_contents->setShape(contents_rect);
 	}
+}
+
+void LLIMConversation::hideAllStandardButtons()
+{
+	for (S32 i = 0; i < BUTTON_COUNT; i++)
+	{
+		if (mButtons[i])
+		{
+			// Hide the standard header buttons in a docked IM floater.
+			mButtons[i]->setVisible(false);
+		}
+	}
+}
+
+void LLIMConversation::updateHeaderAndToolbar()
+{
+	bool is_hosted = getHost() != NULL;
+
+	if (is_hosted)
+	{
+		hideAllStandardButtons();
+	}
+
+	hideOrShowTitle();
 
 	// Participant list should be visible only in torn off floaters.
 	bool is_participant_list_visible =
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 19d1e523f0..e6b4f534cc 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -89,6 +89,9 @@ protected:
 	void buildParticipantList();
 	void onSortMenuItemClicked(const LLSD& userdata);
 
+	void hideOrShowTitle();
+	void hideAllStandardButtons();
+
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
 	bool mWasHosted;
-- 
cgit v1.2.3


From ec4d1a2450807afcff5c0f0ebf651c9e67f1b310 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 17 Jul 2012 12:07:25 -0700
Subject: CHUI-234 : Fix crashers in landmarks panel

---
 indra/newview/llpanellandmarks.cpp       | 2 +-
 indra/newview/llplacesinventorypanel.cpp | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index faef923338..4bbab52e5a 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -651,7 +651,7 @@ void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesI
 	// Start background fetch, mostly for My Inventory and Library
 	if (expanded)
 	{
-		const LLUUID &cat_id = mCurrentSelectedList->getRootFolderID();
+		const LLUUID &cat_id = inventory_list->getRootFolderID();
 		// Just because the category itself has been fetched, doesn't mean its child folders have.
 		/*
 		  if (!gInventory.isCategoryComplete(cat_id))
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index d95d5eac19..65d9691902 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -93,6 +93,7 @@ void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& par
 	p.parent_panel = this;
 	p.allow_multiselect = mAllowMultiSelect;
 	p.use_ellipses = true;	// truncate inventory item text so remove horizontal scroller
+	p.view_model = &mInventoryViewModel;
 	mFolderRoot = LLUICtrlFactory::create<LLPlacesFolderView>(p);
 }
 
-- 
cgit v1.2.3


From 15f6f877f923ecc85489c0159ca62deb02de1201 Mon Sep 17 00:00:00 2001
From: merov_linden <none@none>
Date: Thu, 19 Jul 2012 03:57:24 +0100
Subject: CHUI-236 : WIP : Modify the handling of FT_ROOT_INVENTORY which was
 creating havoc in LLInventoryModel instantiation. Still, some of those hack
 will have to come back on.

---
 indra/newview/llinventorymodel.cpp       | 37 ++++++++++++++++----------------
 indra/newview/llplacesinventorypanel.cpp | 37 +-------------------------------
 2 files changed, 20 insertions(+), 54 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 9b0d12b353..3250d60179 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -210,7 +210,7 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons
 		if (!cat) break;
 		const LLFolderType::EType folder_type = cat->getPreferredType();
 		if (folder_type != LLFolderType::FT_NONE &&
-			folder_type != LLFolderType::FT_ROOT_INVENTORY &&
+//			folder_type != LLFolderType::FT_ROOT_INVENTORY &&
 			!LLFolderType::lookupIsEnsembleType(folder_type))
 		{
 			return cat;
@@ -380,11 +380,12 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
 	LLUUID rv = LLUUID::null;
 	
 	const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID();
-	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
-	{
-		rv = root_id;
-	}
-	else if (root_id.notNull())
+//	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
+//	{
+//		rv = root_id;
+//	}
+//	else if (root_id.notNull())
+	if (root_id.notNull())
 	{
 		cat_array_t* cats = NULL;
 		cats = get_ptr_in_map(mParentChildCategoryTree, root_id);
@@ -2026,11 +2027,11 @@ void LLInventoryModel::buildParentChildMap()
 			{
 				cat->setParent(findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND));
 			}
-			else if(LLFolderType::FT_ROOT_INVENTORY == pref)
-			{
+//			else if(LLFolderType::FT_ROOT_INVENTORY == pref)
+//			{
 				// it's the root
-				cat->setParent(LLUUID::null);
-			}
+//				cat->setParent(LLUUID::null);
+//			}
 			else
 			{
 				// it's a protected folder.
@@ -2160,14 +2161,14 @@ void LLInventoryModel::buildParentChildMap()
 
 					if(category && category->getPreferredType() != LLFolderType::FT_ROOT_INVENTORY)
 						continue;
-					if ( category && 0 == LLStringUtil::compareInsensitive(name, category->getName()) )
-					{
-						if(category->getUUID()!=mRootFolderID)
-						{
-							LLUUID& new_inv_root_folder_id = const_cast<LLUUID&>(mRootFolderID);
-							new_inv_root_folder_id = category->getUUID();
-						}
-					}
+//					if ( category && 0 == LLStringUtil::compareInsensitive(name, category->getName()) )
+//					{
+//						if(category->getUUID()!=mRootFolderID)
+//						{
+//							LLUUID& new_inv_root_folder_id = const_cast<LLUUID&>(mRootFolderID);
+//							new_inv_root_folder_id = category->getUUID();
+//						}
+//					}
 				}
 			}
 
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 65d9691902..c46681f556 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -60,44 +60,9 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()
 
 void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
 {
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);
-
-	LLUUID root_id;
-
-	if ("LIBRARY" == params.start_folder())
-	{
-		root_id = gInventory.getLibraryRootFolderID();
-	}
-	else
-	{
-		root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
-	}
-
-	LLRect folder_rect(0,
-		0,
-		getRect().getWidth(),
-		0);
-	LLPlacesFolderView::Params p;
-	p.name = getName();
-	p.title = getLabel();
-	p.rect = folder_rect;
-	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
-													LLAssetType::AT_CATEGORY,
-													LLInventoryType::IT_CATEGORY,
-													this,
-													&mInventoryViewModel,
-													NULL,
-													root_id);
-	p.parent_panel = this;
-	p.allow_multiselect = mAllowMultiSelect;
-	p.use_ellipses = true;	// truncate inventory item text so remove horizontal scroller
-	p.view_model = &mInventoryViewModel;
-	mFolderRoot = LLUICtrlFactory::create<LLPlacesFolderView>(p);
+	LLInventoryPanel::buildFolderView(params);
 }
 
-
 // save current folder open state
 void LLPlacesInventoryPanel::saveFolderState()
 {
-- 
cgit v1.2.3


From efa73d4975afda19ee5255d5cca33fa96fc21eb4 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 19 Jul 2012 20:38:07 -0700
Subject: CHUI-236 : WIP : Places panel works for My Inventory but still empty
 lists for Favorites Bar, My Landmarks and Library.

---
 indra/newview/llinventorymodel.cpp | 37 ++++++++++++++++++-------------------
 indra/newview/llinventorypanel.cpp | 25 +++++++++++--------------
 indra/newview/llinventorypanel.h   |  1 -
 3 files changed, 29 insertions(+), 34 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 3250d60179..9b0d12b353 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -210,7 +210,7 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons
 		if (!cat) break;
 		const LLFolderType::EType folder_type = cat->getPreferredType();
 		if (folder_type != LLFolderType::FT_NONE &&
-//			folder_type != LLFolderType::FT_ROOT_INVENTORY &&
+			folder_type != LLFolderType::FT_ROOT_INVENTORY &&
 			!LLFolderType::lookupIsEnsembleType(folder_type))
 		{
 			return cat;
@@ -380,12 +380,11 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
 	LLUUID rv = LLUUID::null;
 	
 	const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID();
-//	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
-//	{
-//		rv = root_id;
-//	}
-//	else if (root_id.notNull())
-	if (root_id.notNull())
+	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
+	{
+		rv = root_id;
+	}
+	else if (root_id.notNull())
 	{
 		cat_array_t* cats = NULL;
 		cats = get_ptr_in_map(mParentChildCategoryTree, root_id);
@@ -2027,11 +2026,11 @@ void LLInventoryModel::buildParentChildMap()
 			{
 				cat->setParent(findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND));
 			}
-//			else if(LLFolderType::FT_ROOT_INVENTORY == pref)
-//			{
+			else if(LLFolderType::FT_ROOT_INVENTORY == pref)
+			{
 				// it's the root
-//				cat->setParent(LLUUID::null);
-//			}
+				cat->setParent(LLUUID::null);
+			}
 			else
 			{
 				// it's a protected folder.
@@ -2161,14 +2160,14 @@ void LLInventoryModel::buildParentChildMap()
 
 					if(category && category->getPreferredType() != LLFolderType::FT_ROOT_INVENTORY)
 						continue;
-//					if ( category && 0 == LLStringUtil::compareInsensitive(name, category->getName()) )
-//					{
-//						if(category->getUUID()!=mRootFolderID)
-//						{
-//							LLUUID& new_inv_root_folder_id = const_cast<LLUUID&>(mRootFolderID);
-//							new_inv_root_folder_id = category->getUUID();
-//						}
-//					}
+					if ( category && 0 == LLStringUtil::compareInsensitive(name, category->getName()) )
+					{
+						if(category->getUUID()!=mRootFolderID)
+						{
+							LLUUID& new_inv_root_folder_id = const_cast<LLUUID&>(mRootFolderID);
+							new_inv_root_folder_id = category->getUUID();
+						}
+					}
 				}
 			}
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index ed370e9add..340f851ed8 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -193,6 +193,15 @@ void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
 
 void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 {
+	// Clear up the root view
+	// Note: This needs to be done *before* we build the new folder view 
+	LLFolderViewItem* root_view = getItemByID(gInventory.getRootFolderID());
+	if (root_view)
+	{
+		removeItemID(static_cast<LLFolderViewModelItemInventory*>(root_view->getViewModelItem())->getUUID());
+		root_view->destroyView();
+	}
+
 	LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
 
 	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
@@ -228,6 +237,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	{
 		initializeViews();
 	}
+	
 	gIdleCallbacks.addFunction(onIdle, (void*)this);
 
 	if (mSortOrderSetting != INHERIT_SORT_ORDER)
@@ -595,7 +605,7 @@ void LLInventoryPanel::initializeViews()
 {
 	if (!gInventory.isInventoryUsable()) return;
 
-	rebuildViewsFor(gInventory.getRootFolderID());
+	buildNewViews(gInventory.getRootFolderID());
 
 	gIdleCallbacks.addFunction(idle, this);
 
@@ -622,19 +632,6 @@ void LLInventoryPanel::initializeViews()
 	}
 }
 
-LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
-{
-	// Destroy the old view for this ID so we can rebuild it.
-	LLFolderViewItem* old_view = getItemByID(id);
-	if (old_view)
-	{
-		old_view->destroyView();
-		removeItemID(static_cast<LLFolderViewModelItemInventory*>(old_view->getViewModelItem())->getUUID());
-	}
-
-	return buildNewViews(id);
-}
-
 LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)
 {
 	LLRect folder_rect(0,
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 465ccdd582..4fcc93b0c4 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -237,7 +237,6 @@ public:
 protected:
 	// Builds the UI.  Call this once the inventory is usable.
 	void 				initializeViews();
-	LLFolderViewItem*	rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
 
 	virtual void		buildFolderView(const LLInventoryPanel::Params& params);
 	LLFolderViewItem*	buildNewViews(const LLUUID& id);
-- 
cgit v1.2.3


From 6227a5c273efbe732c8068400d7e4b5486981bba Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 19 Jul 2012 19:16:36 +0300
Subject: CHUI-231, CHUI-233 [FIXED] - Modified and simplified algorithm of
 reshaping floater's body (content)  and showing/hiding of the title for
 prevent of present and future issues with floater's repositioning

---
 indra/newview/llimconversation.cpp                 | 32 ++++++++--------------
 indra/newview/llimconversation.h                   |  3 +-
 .../skins/default/xui/en/floater_im_session.xml    |  2 +-
 3 files changed, 13 insertions(+), 24 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index ec7e0ee6cb..ec534b903d 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -43,7 +43,6 @@ const F32 REFRESH_INTERVAL = 0.2f;
 LLIMConversation::LLIMConversation(const LLUUID& session_id)
   : LLTransientDockableFloater(NULL, true, session_id)
   ,  mIsP2PChat(false)
-  ,  mWasHosted(false)
   ,  mExpandCollapseBtn(NULL)
   ,  mTearOffBtn(NULL)
   ,  mCloseBtn(NULL)
@@ -224,26 +223,17 @@ void LLIMConversation::hideOrShowTitle()
 {
 	bool is_hosted = getHost() != NULL;
 
-	if (mWasHosted != is_hosted)
-	{
-		mWasHosted = is_hosted;
-		LLView* floater_contents = getChild<LLView>("contents_view");
-		LLRect contents_rect = floater_contents->getRect();
-
-		if (is_hosted)
-		{
-			// we don't show the header when the floater is hosted, so reshape floater contents
-			// to occupy the header space.
-			contents_rect.mTop += getHeaderHeight();
-		}
-		else
-		{
-			// reduce the floater contents height by header height
-			contents_rect.mTop -= getHeaderHeight();
-		}
-
-		floater_contents->setShape(contents_rect);
-	}
+	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
+	S32 floater_header_size = default_params.header_height;
+	LLView* floater_contents = getChild<LLView>("contents_view");
+
+	LLRect floater_rect = getLocalRect();
+	S32 top_border_of_contents = floater_rect.mTop - (is_hosted? 0 : floater_header_size);
+	LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents);
+	LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom);
+	mDragHandle->setShape(handle_rect);
+	mDragHandle->setVisible(! is_hosted);
+	floater_contents->setShape(contents_rect);
 }
 
 void LLIMConversation::hideAllStandardButtons()
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index e6b4f534cc..c3dff96d5d 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -89,12 +89,11 @@ protected:
 	void buildParticipantList();
 	void onSortMenuItemClicked(const LLSD& userdata);
 
-	void hideOrShowTitle();
+	void hideOrShowTitle(); // toggle the floater's drag handle
 	void hideAllStandardButtons();
 
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
-	bool mWasHosted;
 
 	LLLayoutPanel* mParticipantListPanel;
 	LLParticipantList* mParticipantList;
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 95f6708e96..560e1be213 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -9,7 +9,7 @@
  can_dock="false"
  can_minimize="true"
  can_close="true"
- save_rect="true"
+ save_rect="false"
  visible="false"
  width="394"
  can_resize="true"
-- 
cgit v1.2.3


From 7c9be0e3de6821478c71e4646f07fb112e0e572c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 19 Jul 2012 15:11:56 +0300
Subject: CHUI-229 [FIXED] Nearby chat conversation does not appear initially
 in conversation list if no other conversations are present

---
 indra/newview/llimfloater.cpp          |  8 +++---
 indra/newview/llimfloatercontainer.cpp | 48 ++++++++++++++++++----------------
 indra/newview/llimfloatercontainer.h   |  1 +
 indra/newview/llnearbychat.cpp         |  8 +++---
 4 files changed, 34 insertions(+), 31 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 23c97c5345..22ce3cd42b 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -346,6 +346,10 @@ BOOL LLIMFloater::postBuild()
 
 	initIMFloater();
 
+	// Add a conversation list item in the left pane
+	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+	im_box->addConversationListItem(getTitle(), getKey(), this);
+
 	return TRUE;
 }
 
@@ -641,10 +645,6 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 			}
 		}
 		
-		// Add a conversation list item in the left pane: nothing will be done if already in there
-		// but relevant clean up will be done to ensure consistency of the conversation list
-		floater_container->addConversationListItem(floater->getTitle(), session_id, floater);
-
 		floater->openFloater(floater->getKey());
 	}
 	else
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4f626cb5d2..005794444b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -150,9 +150,6 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
 	LLUUID session_id = floaterp->getKey();
-
-	// Add a conversation list item in the left pane
-	addConversationListItem(floaterp->getTitle(), session_id, floaterp);
 	
 	LLIconCtrl* icon = 0;
 
@@ -280,6 +277,8 @@ void LLIMFloaterContainer::draw()
 		collapseMessagesPane(true);
 	}
 	LLFloater::draw();
+
+	repositioningWidgets();
 }
 
 void LLIMFloaterContainer::tabClose()
@@ -306,7 +305,7 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 			LLFloaterReg::toggleInstanceOrBringToFront(name);
 		}
 	}
-	
+
 	// We need to show/hide all the associated conversations that have been torn off
 	// (and therefore, are not longer managed by the multifloater),
 	// so that they show/hide with the conversations manager.
@@ -409,6 +408,23 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
     }
 }
 
+void LLIMFloaterContainer::repositioningWidgets()
+{
+	LLRect panel_rect = mConversationsListPanel->getRect();
+	S32 item_height = 16;
+	int index = 0;
+	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+		 widget_it != mConversationsWidgets.end();
+		 widget_it++, ++index)
+	{
+		LLFolderViewItem* widget = widget_it->second;
+		widget->setRect(LLRect(0,
+							   panel_rect.getHeight() - item_height*index,
+							   panel_rect.getWidth(),
+							   panel_rect.getHeight() - item_height*(index+1)));
+	}
+}
+
 // CHUI-137 : Temporary implementation of conversations list
 void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp)
 {
@@ -443,14 +459,11 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 
 	// Add it to the UI
 	widget->setVisible(TRUE);
+
+	repositioningWidgets();
+
 	mConversationsListPanel->addChild(widget);
-	LLRect panel_rect = mConversationsListPanel->getRect();
-	S32 item_height = 16;
-	S32 index = mConversationsWidgets.size() - 1;
-	widget->setRect(LLRect(0,
-						   panel_rect.getHeight() - item_height*index,
-						   panel_rect.getWidth(),
-						   panel_rect.getHeight() - item_height*(index+1)));
+
 	return;
 }
 
@@ -470,18 +483,7 @@ void LLIMFloaterContainer::removeConversationListItem(LLFloater* floaterp, bool
 	mConversationsItems.erase(floaterp);
 	mConversationsWidgets.erase(floaterp);
 
-	// Reposition the leftover conversation items
-	LLRect panel_rect = mConversationsListPanel->getRect();
-	S32 item_height = 16;
-	int index = 0;
-	for (widget_it = mConversationsWidgets.begin(); widget_it != mConversationsWidgets.end(); ++widget_it, ++index)
-	{
-		LLFolderViewItem* widget = widget_it->second;
-		widget->setRect(LLRect(0,
-							   panel_rect.getHeight() - item_height*index,
-							   panel_rect.getWidth(),
-							   panel_rect.getHeight() - item_height*(index+1)));
-	}
+	repositioningWidgets();
 	
 	// Don't let the focus fall IW, select and refocus on the first conversation in the list
 	if (change_focus)
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index b624b7558a..a25ea0ab46 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -254,6 +254,7 @@ private:
 	void collapseConversationsPane(bool collapse);
 
 	void updateState(bool collapse, S32 delta_width);
+	void repositioningWidgets();
 
 	void onAddButtonClicked();
 	void onAvatarPicked(const uuid_vec_t& ids);
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 1c81cdc4bc..a21690bed8 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -158,7 +158,7 @@ BOOL LLNearbyChat::postBuild()
 
 	enableResizeCtrls(true, true, false);
 
-	// title must be defined BEFORE call addToHost() because
+	// title must be defined BEFORE call addConversationListItem() because
 	// it is used for show the item's name in the conversations list
 	setTitle(getString("NearbyChatTitle"));
 
@@ -186,6 +186,9 @@ BOOL LLNearbyChat::postBuild()
 		loadHistory();
 	}
 
+	// added row in the conversations list when nearby chat is tear-off
+	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+	im_box->addConversationListItem(getTitle(), LLSD(), this);
 
 	return LLIMConversation::postBuild();
 }
@@ -363,9 +366,6 @@ void LLNearbyChat::addToHost()
 		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
 		if (im_box)
 		{
-			// Make sure the Nearby Chat is present in the conversations list
-			im_box->addConversationListItem(getTitle(), getKey(), this);
-
 			if (gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
 				im_box->addFloater(this, TRUE, LLTabContainer::END);
-- 
cgit v1.2.3


From 3ae21b429e67faf4ee32c9387c63a552b883a472 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 20 Jul 2012 17:16:22 +0300
Subject: CHUI-207 FIXED Emptying Lost and Found and Trash in inventory crashes
 viewer

---
 indra/newview/llinventorymodel.cpp | 23 +++++++++++++++++++++--
 indra/newview/llinventorypanel.cpp | 13 ++++++++++---
 2 files changed, 31 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 9b0d12b353..fe65b87afd 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1240,14 +1240,33 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
 							   items,
 							   INCLUDE_TRASH);
 			S32 count = items.count();
+
+			item_map_t::iterator item_map_end = mItemMap.end();
+			cat_map_t::iterator cat_map_end = mCategoryMap.end();
+			LLUUID uu_id;
+
 			for(S32 i = 0; i < count; ++i)
 			{
-				deleteObject(items.get(i)->getUUID());
+				uu_id = items.get(i)->getUUID();
+
+				// This check prevents the deletion of a previously deleted item.
+				// This is necessary because deletion is not done in a hierarchical
+				// order. The current item may have been already deleted as a child
+				// of its deleted parent.
+				if (mItemMap.find(uu_id) != item_map_end)
+				{
+					deleteObject(uu_id);
+				}
 			}
+
 			count = categories.count();
 			for(S32 i = 0; i < count; ++i)
 			{
-				deleteObject(categories.get(i)->getUUID());
+				uu_id = categories.get(i)->getUUID();
+				if (mCategoryMap.find(uu_id) != cat_map_end)
+				{
+					deleteObject(uu_id);
+				}
 			}
 		}
 	}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 340f851ed8..6a7ee3b6a0 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -421,7 +421,14 @@ void LLInventoryPanel::modelChanged(U32 mask)
 
 		// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
 		// to folder is the fast way to get a folder without searching through folders tree.
-		LLFolderViewFolder* view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
+		LLFolderViewFolder* view_folder = NULL;
+
+		// Check requires as this item might have already been deleted
+		// as a child of its deleted parent.
+		if (model_item && view_item)
+		{
+			view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
+		}
 
 		//////////////////////////////
 		// LABEL Operation
@@ -448,7 +455,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 		if (mask & LLInventoryObserver::REBUILD)
 		{
 			handled = true;
-			if (model_item && view_item)
+			if (model_item && view_item && viewmodel_item)
 			{
 				view_item->destroyView();
 				removeItemID(viewmodel_item->getUUID());
@@ -538,7 +545,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			//////////////////////////////
 			// REMOVE Operation
 			// This item has been removed from memory, but its associated UI element still exists.
-			else if (!model_item && view_item)
+			else if (!model_item && view_item && viewmodel_item)
 			{
 				// Remove the item's UI.
                 removeItemID(viewmodel_item->getUUID());
-- 
cgit v1.2.3


From 176b7d82be3b48344e2a54f81402352273719108 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 23 Jul 2012 19:33:39 -0700
Subject: CHUI-227 FIX Teleport offers sent are not received cleaned up
 serialization of LLSD to param block so that it can round-trip also,
 optimized LLXMLNode and fixed an assert

---
 indra/llui/llnotifications.cpp | 10 +----
 indra/llui/llsdparam.cpp       | 33 +++++-----------
 indra/llxml/llxmlnode.cpp      | 87 +++++++++---------------------------------
 indra/llxml/llxmlnode.h        |  5 +--
 indra/llxuixml/llinitparam.cpp |  5 ---
 indra/llxuixml/llinitparam.h   | 31 ++++++++++++---
 indra/llxuixml/llxuiparser.cpp | 12 +++++-
 7 files changed, 66 insertions(+), 117 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 48128e0b40..7e1e2c3c9b 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -223,14 +223,6 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
 	LLParamSDParser parser;
 	parser.writeSD(mFormData, p.form_elements);
 
-	if (!mFormData.isArray() && !mFormData.isUndefined())
-	{
-		// change existing contents to a one element array
-		LLSD new_llsd_array = LLSD::emptyArray();
-		new_llsd_array.append(mFormData);
-		mFormData = new_llsd_array;
-	}
-
 	for (LLSD::array_iterator it = mFormData.beginArray(), end_it = mFormData.endArray();
 		it != end_it;
 		++it)
@@ -516,7 +508,7 @@ LLSD LLNotification::asLLSD()
 	p.id = mId;
 	p.name = mTemplatep->mName;
 	p.form_elements = getForm()->asLLSD();
-
+	
 	p.substitutions = mSubstitutions;
 	p.payload = mPayload;
 	p.time_stamp = mTimestamp;
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 811e20e810..5a0d688f4f 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -223,10 +223,14 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:
 	{
 		bool new_traversal = it->second;
 
-		LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
-
-		if (child_sd->isArray())
+		LLSD* child_sd;
+		if (it->first.empty())
 		{
+			child_sd = sd_to_write;
+			if (child_sd->isUndefined())
+			{
+				*child_sd = LLSD::emptyArray();
+			}
 			if (new_traversal)
 			{
 				// write to new element at end
@@ -240,22 +244,7 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:
 		}
 		else
 		{
-			if (new_traversal 
-				&& child_sd->isDefined() 
-				&& !child_sd->isArray())
-			{
-				// copy child contents into first element of an array
-				LLSD new_array = LLSD::emptyArray();
-				new_array.append(*child_sd);
-				// assign array to slot that previously held the single value
-				*child_sd = new_array;
-				// return next element in that array
-				sd_to_write = &((*child_sd)[1]);
-			}
-			else
-			{
-				sd_to_write = child_sd;
-			}
+			sd_to_write = &(*sd_to_write)[it->first];
 		}
 		it->second = false;
 	}
@@ -283,11 +272,9 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI
 			it != sd.endArray();
 			++it)
 		{
-			if (!stack.empty())
-			{
-				stack.back().second = true;
-			}
+			stack.push_back(make_pair(std::string(), true));
 			readSDValues(cb, *it, stack);
+			stack.pop_back();
 		}
 	}
 	else if (sd.isUndefined())
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 2ffb0d8503..45839595a0 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -259,7 +259,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
 	return FALSE;
 }
 
-void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
+void LLXMLNode::addChild(LLXMLNodePtr& new_child)
 {
 	if (new_child->mParent != NULL)
 	{
@@ -273,6 +273,11 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
 	new_child->mParent = this;
 	if (new_child->mIsAttribute)
 	{
+		LLXMLAttribList::iterator found_it = mAttributes.find(new_child->mName);
+		if (found_it != mAttributes.end())
+		{
+			removeChild(found_it->second);
+		}
 		mAttributes.insert(std::make_pair(new_child->mName, new_child));
 	}
 	else
@@ -285,49 +290,11 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
 		}
 		mChildren->map.insert(std::make_pair(new_child->mName, new_child));
 
-		// if after_child is specified, it damn well better be in the list of children
-		// for this node. I'm not going to assert that, because it would be expensive,
-		// but don't specify that parameter if you didn't get the value for it from the
-		// list of children of this node!
-		if (after_child.isNull())
-		{
-			if (mChildren->tail != new_child)
-			{
-				mChildren->tail->mNext = new_child;
-				new_child->mPrev = mChildren->tail;
-				mChildren->tail = new_child;
-			}
-		}
-		// if after_child == parent, then put new_child at beginning
-		else if (after_child == this)
-		{
-			// add to front of list
-			new_child->mNext = mChildren->head;
-			if (mChildren->head)
-			{
-				mChildren->head->mPrev = new_child;
-				mChildren->head = new_child;
-			}
-			else // no children
-			{
-				mChildren->head = new_child;
-				mChildren->tail = new_child;
-			}
-		}
-		else
+		if (mChildren->tail != new_child)
 		{
-			if (after_child->mNext.notNull())
-			{
-				// if after_child was not the last item, fix up some pointers
-				after_child->mNext->mPrev = new_child;
-				new_child->mNext = after_child->mNext;
-			}
-			new_child->mPrev = after_child;
-			after_child->mNext = new_child;
-			if (mChildren->tail == after_child)
-			{
-				mChildren->tail = new_child;
-			}
+			mChildren->tail->mNext = new_child;
+			new_child->mPrev = mChildren->tail;
+			mChildren->tail = new_child;
 		}
 	}
 
@@ -343,8 +310,9 @@ LLXMLNodePtr LLXMLNode::createChild(const char* name, BOOL is_attribute)
 // virtual 
 LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, BOOL is_attribute)
 {
-	LLXMLNode* ret = new LLXMLNode(name, is_attribute);
+	LLXMLNodePtr ret(new LLXMLNode(name, is_attribute));
 	ret->mID.clear();
+	
 	addChild(ret);
 	return ret;
 }
@@ -358,11 +326,12 @@ BOOL LLXMLNode::deleteChild(LLXMLNode *child)
 	return FALSE;
 }
 
-void LLXMLNode::setParent(LLXMLNodePtr new_parent)
+void LLXMLNode::setParent(LLXMLNodePtr& new_parent)
 {
 	if (new_parent.notNull())
 	{
-		new_parent->addChild(this);
+		LLXMLNodePtr this_ptr(this);
+		new_parent->addChild(this_ptr);
 	}
 	else
 	{
@@ -681,27 +650,6 @@ bool LLXMLNode::updateNode(
 	return TRUE;
 }
 
-
-// static 
-LLXMLNodePtr LLXMLNode::replaceNode(LLXMLNodePtr node, LLXMLNodePtr update_node)
-{	
-	if (!node || !update_node)
-	{
-		llwarns << "Node invalid" << llendl;
-		return node;
-	}
-	
-	LLXMLNodePtr cloned_node = update_node->deepCopy();
-	node->mParent->addChild(cloned_node, node);	// add after node
-	LLXMLNodePtr parent = node->mParent;
-	parent->removeChild(node);
-	parent->updateDefault();
-	
-	return cloned_node;
-}
-
-
-
 // static
 bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree)
 {
@@ -1198,7 +1146,7 @@ void LLXMLNode::scrubToTree(LLXMLNode *tree)
 		std::vector<LLXMLNodePtr>::iterator itor3;
 		for (itor3=to_delete_list.begin(); itor3!=to_delete_list.end(); ++itor3)
 		{
-			(*itor3)->setParent(NULL);
+			(*itor3)->setParent(LLXMLNodePtr());
 		}
 	}
 }
@@ -2733,7 +2681,8 @@ void LLXMLNode::setName(LLStringTableEntry* name)
 	mName = name;
 	if (old_parent)
 	{
-		old_parent->addChild(this);
+		LLXMLNodePtr this_ptr(this);
+		old_parent->addChild(this_ptr);
 	}
 }
 
diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h
index e3da7169e7..ec486d7957 100644
--- a/indra/llxml/llxmlnode.h
+++ b/indra/llxml/llxmlnode.h
@@ -127,8 +127,8 @@ public:
 	BOOL isNull();
 
 	BOOL deleteChild(LLXMLNode* child);
-    void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL)); 
-    void setParent(LLXMLNodePtr new_parent); // reparent if necessary
+    void addChild(LLXMLNodePtr& new_child); 
+    void setParent(LLXMLNodePtr& new_parent); // reparent if necessary
 
     // Serialization
 	static bool parseFile(
@@ -147,7 +147,6 @@ public:
 	static bool updateNode(
 		LLXMLNodePtr& node,
 		LLXMLNodePtr& update_node);
-	static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
 	
 	static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths);
 	
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 3c0d0aaa7e..bb160b3c0b 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -227,12 +227,7 @@ namespace LLInitParam
 			if (serialize_func)
 			{
 				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
-				// each param descriptor remembers its serial number
-				// so we can inspect the same param under different names
-				// and see that it has the same number
-				name_stack.push_back(std::make_pair("", true));
 				serialize_func(*param, parser, name_stack, diff_param);
-				name_stack.pop_back();
 			}
 		}
 
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index d44ccac6e4..606676be2c 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -1317,10 +1317,18 @@ namespace LLInitParam
 
 		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
+			Parser::name_stack_range_t new_name_stack_range(name_stack_range);
 			self_t& typed_param = static_cast<self_t&>(param);
 			value_t value;
+
+			// pop first element if empty string
+			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
+			{
+				++new_name_stack_range.first;
+			}
+
 			// no further names in stack, attempt to parse value now
-			if (name_stack_range.first == name_stack_range.second)
+			if (new_name_stack_range.first == new_name_stack_range.second)
 			{
 				// attempt to read value directly
 				if (parser.readValue(value))
@@ -1353,14 +1361,14 @@ namespace LLInitParam
 		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
 		{
 			const self_t& typed_param = static_cast<const self_t&>(param);
-			if (!typed_param.isProvided() || name_stack.empty()) return;
+			if (!typed_param.isProvided()) return;
 
 			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
 				it != end_it;
 				++it)
 			{
 				std::string key = it->getValueName();
-				name_stack.back().second = true;
+				name_stack.push_back(std::make_pair(std::string(), true));
 
 				if(key.empty())
 				// not parsed via name values, write out value directly
@@ -1382,6 +1390,8 @@ namespace LLInitParam
 						break;
 					}
 				}
+
+				name_stack.pop_back();
 			}
 		}
 
@@ -1519,9 +1529,16 @@ namespace LLInitParam
 
 		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name) 
 		{ 
+			Parser::name_stack_range_t new_name_stack_range(name_stack_range);
 			self_t& typed_param = static_cast<self_t&>(param);
 			bool new_value = false;
 
+			// pop first element if empty string
+			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
+			{
+				new_value |= new_name_stack_range.first->second;
+				++new_name_stack_range.first;
+			}
 			if (new_name || typed_param.mValues.empty())
 			{
 				new_value = true;
@@ -1531,7 +1548,7 @@ namespace LLInitParam
 			param_value_t& value = typed_param.mValues.back();
 
 			// attempt to parse block...
-			if(value.deserializeBlock(parser, name_stack_range, new_name))
+			if(value.deserializeBlock(parser, new_name_stack_range, new_name))
 			{
 				typed_param.setProvided();
 				return true;
@@ -1564,13 +1581,13 @@ namespace LLInitParam
 		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
 		{
 			const self_t& typed_param = static_cast<const self_t&>(param);
-			if (!typed_param.isProvided() || name_stack.empty()) return;
+			if (!typed_param.isProvided()) return;
 
 			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
 				it != end_it;
 				++it)
 			{
-				name_stack.back().second = true;
+				name_stack.push_back(std::make_pair(std::string(), true));
 
 				std::string key = it->getValueName();
 				if (!key.empty())
@@ -1583,6 +1600,8 @@ namespace LLInitParam
 				{
 					it->serializeBlock(parser, name_stack, NULL);
 				}
+
+				name_stack.pop_back();
 			}
 		}
 
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 9cd88a1620..3ad5ad7d42 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -621,7 +621,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p
 			nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd");
 			
 			// add to front of schema
-			mSchemaNode->addChild(nodep, mSchemaNode);
+			mSchemaNode->addChild(nodep);
 		}
 
 		for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
@@ -877,16 +877,24 @@ LLXMLNodePtr LLXUIParser::getNode(name_stack_t& stack)
 		it = next_it)
 	{
 		++next_it;
+		bool force_new_node = false;
+
 		if (it->first.empty())
 		{
 			it->second = false;
 			continue;
 		}
 
+		if (next_it != stack.end() && next_it->first.empty() && next_it->second)
+		{
+			force_new_node = true;
+		}
+
+
 		out_nodes_t::iterator found_it = mOutNodes.find(it->first);
 
 		// node with this name not yet written
-		if (found_it == mOutNodes.end() || it->second)
+		if (found_it == mOutNodes.end() || it->second || force_new_node)
 		{
 			// make an attribute if we are the last element on the name stack
 			bool is_attribute = next_it == stack.end();
-- 
cgit v1.2.3


From 0a28a63ce05755d22b09badc41bdd23d5baab1bb Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 24 Jul 2012 12:03:00 -0700
Subject: fix for gcc builds

---
 indra/llxml/llxmlnode.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 45839595a0..afb0d87da9 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -147,13 +147,15 @@ LLXMLNodePtr LLXMLNode::deepCopy()
 		for (LLXMLChildList::iterator iter = mChildren->map.begin();
 			 iter != mChildren->map.end(); ++iter)	
 		{
-			newnode->addChild(iter->second->deepCopy());
+			LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy());
+			newnode->addChild(temp_ptr_for_gcc);
 		}
 	}
 	for (LLXMLAttribList::iterator iter = mAttributes.begin();
 		 iter != mAttributes.end(); ++iter)
 	{
-		newnode->addChild(iter->second->deepCopy());
+		LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy());
+		newnode->addChild(temp_ptr_for_gcc);
 	}
 
 	return newnode;
@@ -1146,7 +1148,8 @@ void LLXMLNode::scrubToTree(LLXMLNode *tree)
 		std::vector<LLXMLNodePtr>::iterator itor3;
 		for (itor3=to_delete_list.begin(); itor3!=to_delete_list.end(); ++itor3)
 		{
-			(*itor3)->setParent(LLXMLNodePtr());
+			LLXMLNodePtr ptr;
+			(*itor3)->setParent(ptr);
 		}
 	}
 }
-- 
cgit v1.2.3


From f303eeccf705f677e48c5738e5119352fd86b31d Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Tue, 24 Jul 2012 22:47:35 +0300
Subject: CHUI-209 FIX for properly updating folder names in folder view after
 they have been renamed. The old display name should be cleared before
 refreshing the views for both items and folders in folder view, otherwise the
 old name will be used upon renaming.

---
 indra/newview/llinventorybridge.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index b4a91ca0f7..9997d1720f 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -81,7 +81,7 @@ public:
 	// LLInvFVBridge functionality
 	//--------------------------------------------------------------------
 	virtual const LLUUID& getUUID() const { return mUUID; }
-	virtual void clearDisplayName() {}
+	virtual void clearDisplayName() { mDisplayName.clear(); }
 	virtual void restoreItem() {}
 	virtual void restoreToWorld() {}
 
@@ -229,8 +229,6 @@ public:
 	virtual bool hasChildren() const { return FALSE; }
 	virtual BOOL isUpToDate() const { return TRUE; }
 
-	/*virtual*/ void clearDisplayName() { mDisplayName.clear(); }
-
 	LLViewerInventoryItem* getItem() const;
 
 protected:
-- 
cgit v1.2.3


From decd8a435d8fb15bab52eec9e447b176e33eb5cf Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 24 Jul 2012 14:42:28 -0700
Subject: CHUI-211: Problem was due to a non-heap variable being deleted and
 then referenced later (which was found by ProductEngine). Also the crash
 occurred at a specifc location llpangelobjectinventory::reset() during a
 static_cast, so now using a dynamic_cast as a safeguard.

---
 indra/llui/llfolderview.cpp              | 3 ++-
 indra/newview/llpanelobjectinventory.cpp | 7 ++++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 8ade17b763..10729a3eae 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -266,7 +266,8 @@ LLFolderView::~LLFolderView( void )
 	mItems.clear();
 	mFolders.clear();
 
-	delete mViewModel;
+	//product engine bugfix, prevent deletion of non-heap data
+	//delete mViewModel;
 	mViewModel = NULL;
 }
 
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index ca20051a51..937d3bb8c5 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1565,7 +1565,12 @@ void LLPanelObjectInventory::reset()
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
 	//TODO RN: make this happen by manipulating filter object directly
-	static_cast<LLInventoryFilter*>(mFolders->getFolderViewModel()->getFilter())->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+  	LLInventoryFilter* inventoryFilter = dynamic_cast<LLInventoryFilter*>(mFolders->getFolderViewModel()->getFilter());
+  	if(inventoryFilter)
+	{
+    	inventoryFilter->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+  	}
+  
 	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
 	if (hasFocus())
-- 
cgit v1.2.3


From 1736c7b74e5291b1fee91ae72ff52391ae7d946f Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 24 Jul 2012 15:19:18 -0700
Subject: Backed out changeset: a20e437a726c

---
 indra/newview/llfolderviewmodelinventory.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index dff1e1be90..d23b4af8cb 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -158,20 +158,22 @@ bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite
 
 	if (item->getLastFilterGeneration() < filter_generation)
 	{
-		// recursive application of the filter for child items
-		item->filter( filter );
-
 		if (item->getLastFilterGeneration() >= must_pass_generation 
 			&& !item->passedFilter(must_pass_generation))
 		{
 			// failed to pass an earlier filter that was a subset of the current one
 			// go ahead and flag this item as done
+			item->filter(filter);
 			if (item->passedFilter())
 			{
 				llerrs << "Invalid shortcut in inventory filtering!" << llendl;
 			}
 			item->setPassedFilter(false, false, filter_generation);
 		}
+		else
+		{
+			item->filter( filter );
+		}
 	}
 
 	// track latest generation to pass any child items, for each folder up to root
-- 
cgit v1.2.3


From 891a09561d4dff23836c8618d481a6cd2dd001de Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Tue, 24 Jul 2012 20:29:20 -0700
Subject: CHUI-206 FIX Viewer crash when selecting to cut inventory item, then
 selecting to cut another inventory item Seems to work now, without filtering
 de-optimization

---
 indra/llui/llfolderview.cpp                  | 2 +-
 indra/newview/llfolderviewmodelinventory.cpp | 5 -----
 2 files changed, 1 insertion(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 8ade17b763..943e690948 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1123,7 +1123,7 @@ void LLFolderView::paste()
 			LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(item);
 			if (folder == NULL)
 			{
-				item = item->getParentFolder();
+				folder = item->getParentFolder();
 			}
 			folder_set.insert(folder);
 		}
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index d23b4af8cb..faf5b3e7ac 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -163,11 +163,6 @@ bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite
 		{
 			// failed to pass an earlier filter that was a subset of the current one
 			// go ahead and flag this item as done
-			item->filter(filter);
-			if (item->passedFilter())
-			{
-				llerrs << "Invalid shortcut in inventory filtering!" << llendl;
-			}
 			item->setPassedFilter(false, false, filter_generation);
 		}
 		else
-- 
cgit v1.2.3


From de8cd534b985450f6d9ff9d2ad947a2a110f76a8 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 25 Jul 2012 16:16:06 +0300
Subject: CHUI-230 [FIXED] Torn off conversation window size resizes when
 viewer window is resized

---
 indra/newview/llnearbychat.cpp                            | 10 ----------
 indra/newview/skins/default/xui/en/floater_im_session.xml |  2 +-
 2 files changed, 1 insertion(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a21690bed8..4e53082c05 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -391,17 +391,7 @@ void LLNearbyChat::onOpen(const LLSD& key)
 
 bool LLNearbyChat::applyRectControl()
 {
-	bool is_torn_off = getHost() == NULL;
-
-	// Resize is limited to torn off floaters.
-	// A hosted floater is not resizable.
-	if (is_torn_off)
-	{
-		enableResizeCtrls(true);
-	}
-	
 	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-
 	return LLFloater::applyRectControl();
 }
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 560e1be213..95f6708e96 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -9,7 +9,7 @@
  can_dock="false"
  can_minimize="true"
  can_close="true"
- save_rect="false"
+ save_rect="true"
  visible="false"
  width="394"
  can_resize="true"
-- 
cgit v1.2.3


From c4f59fd5882d8b019830292e9e5ed1d2480f73ef Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 25 Jul 2012 14:30:17 -0700
Subject: CHUI-239 FIX Viewer crash when opening object with contents

---
 indra/newview/llfloatertools.cpp             |  4 ++--
 indra/newview/llfolderviewmodelinventory.cpp | 10 +++++-----
 indra/newview/llfolderviewmodelinventory.h   | 10 +++-------
 indra/newview/llinventorybridge.cpp          |  5 ++---
 indra/newview/llinventorypanel.h             |  1 +
 indra/newview/llpanelobjectinventory.cpp     |  8 ++++++--
 indra/newview/llpanelobjectinventory.h       |  2 ++
 indra/newview/llplacesinventorybridge.cpp    |  2 --
 8 files changed, 21 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 6978e6a430..43465d4209 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -660,8 +660,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 
 	mBtnEdit	->setToggleState( edit_visible );
 	mRadioGroupEdit->setVisible( edit_visible );
-	bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
-	getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost);
+	//bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
+	//getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost);
 
 	mBtnLink->setVisible(edit_visible);
 	mBtnUnlink->setVisible(edit_visible);
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index dff1e1be90..e8135496d5 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -109,7 +109,7 @@ bool LLFolderViewModelInventory::contentsReady()
 void LLFolderViewModelItemInventory::requestSort()
 {
 	LLFolderViewModelItemCommon::requestSort();
-	if (mRootViewModel->getSorter().isByDate())
+	if (mRootViewModel.getSorter().isByDate())
 	{
 		// sort by date potentially affects parent folders which use a date
 		// derived from newest item in them
@@ -123,14 +123,14 @@ void LLFolderViewModelItemInventory::requestSort()
 bool LLFolderViewModelItemInventory::potentiallyVisible()
 {
 	return passedFilter() // we've passed the filter
-		|| getLastFilterGeneration() < mRootViewModel->getFilter()->getFirstSuccessGeneration() // or we don't know yet
+		|| getLastFilterGeneration() < mRootViewModel.getFilter()->getFirstSuccessGeneration() // or we don't know yet
 		|| descendantsPassedFilter();
 }
 
 bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation) 
 { 
-	if (filter_generation < 0 && mRootViewModel) 
-		filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
+	if (filter_generation < 0) 
+		filter_generation = mRootViewModel.getFilter()->getFirstSuccessGeneration();
 
 	return mPassedFolderFilter 
 		&& mLastFilterGeneration >= filter_generation
@@ -139,7 +139,7 @@ bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation)
 
 bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation)
 { 
-	if (filter_generation < 0) filter_generation = mRootViewModel->getFilter()->getFirstSuccessGeneration();
+	if (filter_generation < 0) filter_generation = mRootViewModel.getFilter()->getFirstSuccessGeneration();
 	return mMostFilteredDescendantGeneration >= filter_generation; 
 }
 
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index 12a977b28b..eb2a4bfdec 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -37,13 +37,9 @@ class LLFolderViewModelItemInventory
 	:	public LLFolderViewModelItemCommon
 {
 public:
-	LLFolderViewModelItemInventory()
-		:	mRootViewModel(NULL)
+	LLFolderViewModelItemInventory(class LLFolderViewModelInventory& root_view_model)
+	:	mRootViewModel(root_view_model)
 	{}
-	void setRootViewModel(class LLFolderViewModelInventory* root_view_model)
-	{
-		mRootViewModel = root_view_model;
-	}
 	virtual const LLUUID& getUUID() const = 0;
 	virtual time_t getCreationDate() const = 0;	// UTC seconds
 	virtual void setCreationDate(time_t creation_date_utc) = 0;
@@ -70,7 +66,7 @@ public:
 	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
 
 protected:
-	class LLFolderViewModelInventory* mRootViewModel;
+	class LLFolderViewModelInventory& mRootViewModel;
 };
 
 class LLInventorySort
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d17c25d9f3..9f1d4bdec9 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -190,7 +190,8 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory,
 	mUUID(uuid), 
 	mRoot(root),
 	mInvType(LLInventoryType::IT_NONE),
-	mIsLink(FALSE)
+	mIsLink(FALSE),
+	LLFolderViewModelItemInventory(inventory->getRootViewModel())
 {
 	mInventoryPanel = inventory->getInventoryPanelHandle();
 	const LLInventoryObject* obj = getInventoryObject();
@@ -1158,7 +1159,6 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 	if (new_listener)
 	{
 		new_listener->mInvType = inv_type;
-		new_listener->setRootViewModel(view_model);
 	}
 
 	return new_listener;
@@ -6484,7 +6484,6 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(
 		&& actual_asset_type != LLAssetType::AT_LINK_FOLDER)
 	{
 		new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid);
-		new_listener->setRootViewModel(view_model);
 	}
 	else
 	{
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 4fcc93b0c4..910325cdbc 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -104,6 +104,7 @@ public:
 
 public:
 	LLInventoryModel* getModel() { return mInventory; }
+	LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
 
 	// LLView methods
 	void draw();
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 937d3bb8c5..9bd716e900 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -155,7 +155,8 @@ LLTaskInvFVBridge::LLTaskInvFVBridge(
 	LLPanelObjectInventory* panel,
 	const LLUUID& uuid,
 	const std::string& name,
-	U32 flags):
+	U32 flags)
+:	LLFolderViewModelItemInventory(panel->getRootViewModel()),
 	mUUID(uuid),
 	mName(name),
 	mPanel(panel),
@@ -1915,7 +1916,10 @@ void LLPanelObjectInventory::idle(void* user_data)
 {
 	LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data;
 
-
+	if (self->mFolders)
+	{
+		self->mFolders->update();
+	}
 	if (self->mInventoryNeedsUpdate)
 	{
 		self->updateInventory();
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 7e857f8b31..593fb43b6d 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -56,6 +56,8 @@ public:
 	
 	virtual BOOL postBuild();
 
+	LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
+
 	void doToSelected(const LLSD& userdata);
 	
 	void refresh();
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index af29ab7ea9..1a5f64e295 100644
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -165,7 +165,6 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 			llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl;
 		}
 		new_listener = new LLPlacesLandmarkBridge(inv_type, inventory, root, uuid, flags);
-		new_listener->setRootViewModel(view_model);
 		break;
 	case LLAssetType::AT_CATEGORY:
 		if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
@@ -183,7 +182,6 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 			break;
 		}
 		new_listener = new LLPlacesFolderBridge(inv_type, inventory, root, uuid);
-		new_listener->setRootViewModel(view_model);
 		break;
 	default:
 		new_listener = LLInventoryFVBridgeBuilder::createBridge(
-- 
cgit v1.2.3


From f6dfd6bf0f3ea0e9b5f56a939867353c393539d6 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 25 Jul 2012 18:20:54 -0700
Subject: CHUI-222 FIX Selecting None in inventory filters does not update
 until inventory selected

---
 indra/llui/llfolderview.cpp                  |  2 -
 indra/llui/llfolderviewitem.cpp              | 11 +++--
 indra/llui/llfolderviewmodel.h               |  4 +-
 indra/newview/llfolderviewmodelinventory.cpp | 74 +++++++++++++---------------
 indra/newview/llfolderviewmodelinventory.h   |  4 +-
 indra/newview/llimfloatercontainer.h         |  2 +-
 indra/newview/llpanelobjectinventory.cpp     |  2 +-
 7 files changed, 49 insertions(+), 50 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 10729a3eae..147af04f30 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -266,8 +266,6 @@ LLFolderView::~LLFolderView( void )
 	mItems.clear();
 	mFolders.clear();
 
-	//product engine bugfix, prevent deletion of non-heap data
-	//delete mViewModel;
 	mViewModel = NULL;
 }
 
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 741fc9c324..a356d587f9 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1543,11 +1543,14 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 
 void LLFolderViewFolder::requestArrange()
 { 
-	mLastArrangeGeneration = -1; 
-	// flag all items up to root
-	if (mParentFolder)
+	//if ( mLastArrangeGeneration != -1)
 	{
-		mParentFolder->requestArrange();
+		mLastArrangeGeneration = -1; 
+		// flag all items up to root
+		if (mParentFolder)
+		{
+			mParentFolder->requestArrange();
+		}
 	}
 }
 
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 268ae8eea8..acdec53602 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -152,7 +152,7 @@ public:
 	
 	virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
 
-	virtual bool filter( LLFolderViewFilter& filter) = 0;
+	virtual void filter( LLFolderViewFilter& filter) = 0;
 	virtual bool passedFilter(S32 filter_generation = -1) = 0;
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
 	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) = 0;
@@ -192,6 +192,7 @@ public:
 	:	mSortVersion(-1),
 		mPassedFilter(true),
 		mPassedFolderFilter(true),
+		mPrevPassedAllFilters(false),
 		mFolderViewItem(NULL),
 		mLastFilterGeneration(-1),
 		mMostFilteredDescendantGeneration(-1),
@@ -232,6 +233,7 @@ protected:
 	S32						mSortVersion;
 	bool					mPassedFilter;
 	bool					mPassedFolderFilter;
+	bool					mPrevPassedAllFilters;
 
 	S32						mLastFilterGeneration;
 	S32						mMostFilteredDescendantGeneration;
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index e8135496d5..13ca73917b 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -133,8 +133,9 @@ bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation)
 		filter_generation = mRootViewModel.getFilter()->getFirstSuccessGeneration();
 
 	return mPassedFolderFilter 
-		&& mLastFilterGeneration >= filter_generation
-		&& (mPassedFilter || descendantsPassedFilter(filter_generation));
+		&& (descendantsPassedFilter(filter_generation)
+			|| (mLastFilterGeneration >= filter_generation 
+				&& mPassedFilter));
 }
 
 bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation)
@@ -148,30 +149,29 @@ void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_fo
 	mPassedFilter = passed;
 	mPassedFolderFilter = passed_folder;
 	mLastFilterGeneration = filter_generation;
+
+	bool passed_filter_before = mPrevPassedAllFilters;
+	mPrevPassedAllFilters = passedFilter(filter_generation);
+
+	if (passed_filter_before != mPrevPassedAllFilters)
+	{
+		//TODO RN: ensure this still happens, but without dependency on folderview
+		LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
+		if (parent_folder)
+		{
+			parent_folder->requestArrange();
+		}
+	}
 }
 
-bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
+void LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
 {
-	bool passed_filter_before = item->passedFilter();
 	S32 filter_generation = filter.getCurrentGeneration();
-	S32 must_pass_generation = filter.getFirstRequiredGeneration();
 
 	if (item->getLastFilterGeneration() < filter_generation)
 	{
 		// recursive application of the filter for child items
 		item->filter( filter );
-
-		if (item->getLastFilterGeneration() >= must_pass_generation 
-			&& !item->passedFilter(must_pass_generation))
-		{
-			// failed to pass an earlier filter that was a subset of the current one
-			// go ahead and flag this item as done
-			if (item->passedFilter())
-			{
-				llerrs << "Invalid shortcut in inventory filtering!" << llendl;
-			}
-			item->setPassedFilter(false, false, filter_generation);
-		}
 	}
 
 	// track latest generation to pass any child items, for each folder up to root
@@ -184,39 +184,36 @@ bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite
 			view_model->mMostFilteredDescendantGeneration = filter_generation;
 			view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent);
 		}
-		
-		return !passed_filter_before;
-	}
-	else // !item->passedfilter()
-	{
-		return passed_filter_before;
 	}
 }
 
-bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
+void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 {
-	bool changed = false;
+	const S32 filter_generation = filter.getCurrentGeneration();
+	const S32 must_pass_generation = filter.getFirstRequiredGeneration();
+
+	if (getLastFilterGeneration() >= must_pass_generation 
+		&& !passedFilter(must_pass_generation))
+	{
+		// failed to pass an earlier filter that was a subset of the current one
+		// go ahead and flag this item as done
+		setPassedFilter(false, false, filter_generation);
+		return;
+	}
 
 	if(!mChildren.empty()
-		&& (getLastFilterGeneration() < filter.getFirstRequiredGeneration() // haven't checked descendants against minimum required generation to pass
-			|| descendantsPassedFilter(filter.getFirstRequiredGeneration()))) // or at least one descendant has passed the minimum requirement
+		&& (getLastFilterGeneration() < must_pass_generation // haven't checked descendants against minimum required generation to pass
+			|| descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement
 	{
 		// now query children
-		for (child_list_t::iterator iter = mChildren.begin();
-			iter != mChildren.end() && filter.getFilterCount() > 0;
+		for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end();
+			iter != end_iter && filter.getFilterCount() > 0;
 			++iter)
 		{
-			changed |= filterChildItem((*iter), filter);
+			filterChildItem((*iter), filter);
 		}
 	}
 
-	if (changed)
-	{
-		//TODO RN: ensure this still happens, but without dependency on folderview
-		LLFolderViewFolder* folder = static_cast<LLFolderViewFolder*>(mFolderViewItem);
-		folder->requestArrange();
-	}
-
 	// if we didn't use all filter iterations
 	// that means we filtered all of our descendants
 	// so filter ourselves now
@@ -229,11 +226,10 @@ bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 								? filter.checkFolder(this)
 								: true;
 
-		setPassedFilter(passed_filter, passed_filter_folder, filter.getCurrentGeneration());
+		setPassedFilter(passed_filter, passed_filter_folder, filter_generation);
 		//TODO RN: create interface for string highlighting
 		//mStringMatchOffset = filter.getStringMatchOffset(this);
 	}
-	return changed;
 }
 
 LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index eb2a4bfdec..ab67c93897 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -59,8 +59,8 @@ public:
 	virtual bool passedFilter(S32 filter_generation = -1);
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1);
 	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
-	virtual bool filter( LLFolderViewFilter& filter);
-	virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+	virtual void filter( LLFolderViewFilter& filter);
+	virtual void filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
 
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
 	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index a25ea0ab46..7005ab7b6a 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -89,7 +89,7 @@ public:
 	virtual bool hasChildren() const { return FALSE; }
 
 	virtual bool potentiallyVisible() { return true; }
-	virtual bool filter( LLFolderViewFilter& filter) { return true; }
+	virtual void filter( LLFolderViewFilter& filter) { }
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
 	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) { }
 	virtual bool passedFilter(S32 filter_generation = -1) { return true; }
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 9bd716e900..4719191231 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1616,7 +1616,7 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
 			 iter != inventory->end(); )
 		{
 			LLInventoryObject* item = *iter++;
-			LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID());
+			LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properties", item->getUUID());
 			if(floater)
 			{
 				floater->refresh();
-- 
cgit v1.2.3


From 69b57d4ac075db855d88c2ff0e8c580e9e41ebf7 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 25 Jul 2012 19:54:39 -0700
Subject: CHUI-252 FIX Deleting an item from object contents in build tools
 crashes viewer also improved selection behavior for object contents when
 deleting/adding items

---
 indra/llui/llhandle.h                    | 13 +++----
 indra/newview/llpanelobjectinventory.cpp | 64 ++++++++++++++++++++++++++------
 indra/newview/llpanelobjectinventory.h   |  7 ++++
 3 files changed, 66 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
index 37c657dd92..680a1a7f1d 100644
--- a/indra/llui/llhandle.h
+++ b/indra/llui/llhandle.h
@@ -158,13 +158,6 @@ public:
 		return mHandle; 
 	}
 
-protected:
-	typedef LLHandle<T> handle_type_t;
-	LLHandleProvider() 
-	{
-		// provided here to enforce T deriving from LLHandleProvider<T>
-	} 
-
 	template <typename U>
 	LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
 	{
@@ -173,6 +166,12 @@ protected:
 		return downcast_handle;
 	}
 
+protected:
+	typedef LLHandle<T> handle_type_t;
+	LLHandleProvider() 
+	{
+		// provided here to enforce T deriving from LLHandleProvider<T>
+	} 
 
 private:
 	mutable LLRootHandle<T> mHandle;
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 4719191231..473b5d9479 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1535,6 +1535,8 @@ void LLPanelObjectInventory::clearContents()
 		LLToolDragAndDrop::getInstance()->endDrag();
 	}
 
+	clearItemIDs();
+
 	if( mScroller )
 	{
 		// removes mFolders
@@ -1550,8 +1552,6 @@ void LLPanelObjectInventory::reset()
 {
 	clearContents();
 
-	//setBorderVisible(FALSE);
-	
 	mCommitCallbackRegistrar.pushScope(); // push local callbacks
 	
 	LLRect dummy_rect(0, 1, 1, 0);
@@ -1631,15 +1631,20 @@ void LLPanelObjectInventory::updateInventory()
 	//		<< " panel UUID: " << panel->mTaskUUID << "\n"
 	//		<< " task  UUID: " << object->mID << llendl;
 	// We're still interested in this task's inventory.
+	std::vector<LLUUID> selected_item_ids;
 	std::set<LLFolderViewItem*> selected_items;
 	BOOL inventory_has_focus = FALSE;
-	if (mHaveInventory)
+	if (mHaveInventory && mFolders)
 	{
 		selected_items = mFolders->getSelectionList();
 		inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
 	}
-
-	reset();
+	for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
+		it != end_it;
+		++it)
+	{
+		selected_item_ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+	}
 
 	LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
 	if (objectp)
@@ -1647,10 +1652,11 @@ void LLPanelObjectInventory::updateInventory()
 		LLInventoryObject* inventory_root = objectp->getInventoryRoot();
 		LLInventoryObject::object_list_t contents;
 		objectp->getInventoryContents(contents);
-		mHaveInventory = TRUE;
 
 		if (inventory_root && !contents.empty())
 		{
+			reset();
+
 			createFolderViews(inventory_root, contents);
 			mIsInventoryEmpty = FALSE;
 			mFolders->setEnabled(TRUE);
@@ -1660,6 +1666,8 @@ void LLPanelObjectInventory::updateInventory()
 			// TODO: create an empty inventory
 			mIsInventoryEmpty = TRUE;
 		}
+
+		mHaveInventory = TRUE;
 	}
 	else
 	{
@@ -1669,11 +1677,12 @@ void LLPanelObjectInventory::updateInventory()
 	}
 
 	// restore previous selection
-	std::set<LLFolderViewItem*>::iterator selection_it;
-	BOOL first_item = TRUE;
-	for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
+	std::vector<LLUUID>::iterator selection_it;
+	bool first_item = true;
+	for (selection_it = selected_item_ids.begin(); selection_it != selected_item_ids.end(); ++selection_it)
 	{
-		LLFolderViewItem* selected_item = (*selection_it);
+		LLFolderViewItem* selected_item = getItemByID(*selection_it);
+		
 		if (selected_item)
 		{
 			//HACK: "set" first item then "change" each other one to get keyboard focus right
@@ -1689,7 +1698,10 @@ void LLPanelObjectInventory::updateInventory()
 		}
 	}
 
-	mFolders->requestArrange();
+	if (mFolders)
+	{
+		mFolders->requestArrange();
+	}
 	mInventoryNeedsUpdate = FALSE;
 	// Edit menu handler is set in onFocusReceived
 }
@@ -1761,6 +1773,7 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 			}
 			view->addToFolder(folder);
+			addItemID(obj->getUUID(), view);
 		}
 	}
 
@@ -1944,3 +1957,32 @@ void LLPanelObjectInventory::onFocusReceived()
 	
 	LLPanel::onFocusReceived();
 }
+
+
+LLFolderViewItem* LLPanelObjectInventory::getItemByID( const LLUUID& id )
+{
+	std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
+	map_it = mItemMap.find(id);
+	if (map_it != mItemMap.end())
+	{
+		return map_it->second;
+	}
+
+	return NULL;
+}
+
+void LLPanelObjectInventory::removeItemID( const LLUUID& id )
+{
+	mItemMap.erase(id);
+}
+
+void LLPanelObjectInventory::addItemID( const LLUUID& id, LLFolderViewItem* itemp )
+{
+	mItemMap[id] = itemp;
+}
+
+void LLPanelObjectInventory::clearItemIDs()
+{
+	mItemMap.clear();
+}
+
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 593fb43b6d..f497c695b3 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -88,8 +88,15 @@ protected:
 								LLInventoryObject* parent,
 								LLFolderViewFolder* folder);
 	void clearContents();
+	LLFolderViewItem* getItemByID(const LLUUID& id);
+
+	void addItemID( const LLUUID& id, LLFolderViewItem*   itemp );
+	void removeItemID(const LLUUID& id);
+	void clearItemIDs();
 
 private:
+	std::map<LLUUID, LLFolderViewItem*> mItemMap;
+
 	LLScrollContainer* mScroller;
 	LLFolderView* mFolders;
 	
-- 
cgit v1.2.3


From 88f259f7c1aefea197ae8b6c49a79de09feebf5b Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 25 Jul 2012 20:08:17 -0700
Subject: optimization of LLSD param parsing

---
 indra/llui/llsdparam.cpp | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 5a0d688f4f..54c8389772 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -305,6 +305,12 @@ namespace LLInitParam
 	// block param interface
 	bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
 	{
+		if (name_stack.first == name_stack.second
+			&& p.readValue<LLSD>(mValue))
+		{
+			return true;
+		}
+
 		LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
 
 		LLSD::String string;
@@ -325,7 +331,11 @@ namespace LLInitParam
 
 	void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
 	{
-		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
-		LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
+		// attempt to write LLSD out directly
+		if (!p.writeValue<LLSD>(mValue, name_stack))
+		{
+			// otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
+			LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
+		}
 	}
 }
-- 
cgit v1.2.3


From 779d982717098e608285b171ac06f5b9f43a94a0 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 26 Jul 2012 16:30:27 -0700
Subject: made Deprecated params write-only

---
 indra/llxuixml/llinitparam.h        | 36 ++++++++++++++++++++++++++++++++----
 indra/newview/llinventoryfilter.cpp |  2 +-
 2 files changed, 33 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 606676be2c..71cd550693 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -2015,10 +2015,12 @@ namespace LLInitParam
 			}
 		};
 
-		class Deprecated : public Param
+		// can appear in data files, but will ignored during parsing
+		// cannot read or write in code
+		class Ignored : public Param
 		{
 		public:
-			explicit Deprecated(const char* name)
+			explicit Ignored(const char* name)
 			:	Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)
 			{
 				BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();
@@ -2049,8 +2051,34 @@ namespace LLInitParam
 			}
 		};
 
-		// different semantics for documentation purposes, but functionally identical
-		typedef Deprecated Ignored;
+		// can appear in data files, or be written to in code, but data will be ignored
+		// cannot be read in code
+		class Deprecated : public Ignored
+		{
+		public:
+			explicit Deprecated(const char* name) : Ignored(name) {}
+
+			// dummy writer interfaces
+			template<typename T>
+			Deprecated& operator =(const T& val)
+			{
+				// do nothing
+				return *this;
+			}
+
+			template<typename T>
+			DERIVED_BLOCK& operator()(const T& val)
+			{
+				// do nothing
+				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+			}
+
+			template<typename T>
+			void set(const T& val, bool flag_as_provided = true)
+			{
+				// do nothing
+			}
+		};
 
 	public:
 		static BlockDescriptor& getBlockDescriptor()
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 3f38d80a39..3e14faa55e 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -89,7 +89,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
 	const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
 
 	// If it's a folder and we're showing all folders, return automatically.
-	const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;;
+	const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;
 	if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
 	{
 		return passed_clipboard;
-- 
cgit v1.2.3


From 5221e48ef64d3965f6d4d3dbf0f937982230d11c Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Thu, 26 Jul 2012 17:26:27 -0700
Subject: CHUI-251: Resetting the object inventory panel after deleting the
 last object.

---
 indra/newview/llpanelobjectinventory.cpp | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 473b5d9479..fe1ff01bc2 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1653,13 +1653,16 @@ void LLPanelObjectInventory::updateInventory()
 		LLInventoryObject::object_list_t contents;
 		objectp->getInventoryContents(contents);
 
-		if (inventory_root && !contents.empty())
+		if (inventory_root)
 		{
 			reset();
+			mIsInventoryEmpty = contents.empty();
+			if (!mIsInventoryEmpty)
+			{
 
-			createFolderViews(inventory_root, contents);
-			mIsInventoryEmpty = FALSE;
-			mFolders->setEnabled(TRUE);
+				createFolderViews(inventory_root, contents);
+				mFolders->setEnabled(TRUE);
+			}
 		}
 		else
 		{
-- 
cgit v1.2.3


From 1e65ba1f909604b027cb7dee5631f698a9f550a8 Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Thu, 26 Jul 2012 18:57:54 -0700
Subject: CHUI-251: Adding back in the root 'Contents' folder under the Build
 floater Content tab.

---
 indra/newview/llpanelobjectinventory.cpp       | 25 +++++++++++++++++--------
 indra/newview/skins/default/xui/en/strings.xml |  3 ---
 2 files changed, 17 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index fe1ff01bc2..5887f4d244 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1656,13 +1656,9 @@ void LLPanelObjectInventory::updateInventory()
 		if (inventory_root)
 		{
 			reset();
-			mIsInventoryEmpty = contents.empty();
-			if (!mIsInventoryEmpty)
-			{
-
-				createFolderViews(inventory_root, contents);
-				mFolders->setEnabled(TRUE);
-			}
+			mIsInventoryEmpty = FALSE;
+			createFolderViews(inventory_root, contents);
+			mFolders->setEnabled(TRUE);
 		}
 		else
 		{
@@ -1725,7 +1721,20 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
 	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
 	if(bridge)
 	{
-		createViewsForCategory(&contents, inventory_root, mFolders);
+		LLFolderViewFolder::Params p;
+		p.name = inventory_root->getName();
+		p.tool_tip = p.name;
+		p.root = mFolders;
+		p.listener = bridge;
+
+		LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
+		new_folder->addToFolder(mFolders);
+		new_folder->toggleOpen();
+
+		if (!contents.empty())
+		{
+			createViewsForCategory(&contents, inventory_root, new_folder);
+		}
 	}
 }
 
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 7790a382d9..fff892af68 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2447,9 +2447,6 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="GroupMoneyDebits">Debits</string>
 	<string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string>
 
-	<!-- viewer object -->
-	<string name="ViewerObjectContents">Contents</string>
-
 	<!-- Viewer menu -->
 	<string name="AcquiredItems">Acquired Items</string>
 	<string name="Cancel">Cancel</string>
-- 
cgit v1.2.3


From e9f640a26fd6c9219ba28336231621e2ad2558fc Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 27 Jul 2012 17:36:41 +0300
Subject: CHUI-198 FIXED (Hitting minimize option on conversations floater
 closes floater, not minimize)

- Removed code which was hiding floater on minimizing floater.
---
 indra/newview/llimfloatercontainer.cpp | 2 --
 1 file changed, 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 005794444b..c19683b1c2 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -257,8 +257,6 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 	if (isMinimized() == b) return;
 	
 	LLMultiFloater::setMinimized(b);
-	// Hide minimized floater (see EXT-5315)
-	setVisible(!b);
 
 	if (isMinimized()) return;
 
-- 
cgit v1.2.3


From f82d0b171964a0b24ab0eca64febc0c1e3821138 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 27 Jul 2012 17:51:40 +0300
Subject: CHUI-204 FIXED (Conversations panel can be re-sized too small with
 all conversations torn off)

- Increased min width of conversations panel by 10 pixels
---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 8e434b5848..e5ef80e352 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -33,7 +33,7 @@
          auto_resize="true"
          height="430"
          name="conversations_layout_panel"
-         min_dim="41"
+         min_dim="51"
          width="268">
             <layout_stack
              animate="false" 
-- 
cgit v1.2.3


From 0ee0a5eff41a3763b1fc3fc45a36f87fc6eedac5 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 27 Jul 2012 22:25:17 +0300
Subject: CHUI-151 FIXED (Implement conversation log)

A brief explanation of what have been implemented. More information can be found in comments.

1. Created conversation history viewer (llfloaterconversationpreview)
2. Created LLConversation and LLConversationLog classes which represent and hold data of conversations (llconversationlog)
3. Created LLConversationLogList and LLConversationLogListItem which are the visual representation of LLConversationLog and LLConversation respectively
4. Created LLFloaterConversationLog - which holds and displays LLConversationLogList
---
 indra/newview/CMakeLists.txt                       |  10 +
 indra/newview/app_settings/settings.xml            |  22 ++
 indra/newview/llappviewer.cpp                      |   4 +
 indra/newview/llconversationlog.cpp                | 336 ++++++++++++++++
 indra/newview/llconversationlog.h                  | 164 ++++++++
 indra/newview/llconversationloglist.cpp            | 422 +++++++++++++++++++++
 indra/newview/llconversationloglist.h              | 143 +++++++
 indra/newview/llconversationloglistitem.cpp        | 157 ++++++++
 indra/newview/llconversationloglistitem.h          |  77 ++++
 indra/newview/llfloaterconversationlog.cpp         | 127 +++++++
 indra/newview/llfloaterconversationlog.h           |  61 +++
 indra/newview/llfloaterconversationpreview.cpp     | 112 ++++++
 indra/newview/llfloaterconversationpreview.h       |  51 +++
 indra/newview/llimfloater.cpp                      |  12 +
 indra/newview/llimfloater.h                        |   6 +
 indra/newview/llimview.cpp                         |  17 +-
 indra/newview/llimview.h                           |  10 +-
 indra/newview/llstartup.cpp                        |   3 +
 indra/newview/llviewerfloaterreg.cpp               |   4 +
 indra/newview/llviewermessage.cpp                  |   5 +-
 indra/newview/llvoicevivox.cpp                     |   1 +
 .../default/xui/en/floater_conversation_log.xml    |  84 ++++
 .../xui/en/floater_conversation_preview.xml        |  53 +++
 .../skins/default/xui/en/floater_im_container.xml  |   1 +
 .../default/xui/en/menu_conversation_log_gear.xml  | 134 +++++++
 .../default/xui/en/menu_conversation_log_view.xml  |  37 ++
 .../skins/default/xui/en/menu_participant_view.xml |  16 +
 .../xui/en/panel_conversation_log_list_item.xml    | 108 ++++++
 28 files changed, 2167 insertions(+), 10 deletions(-)
 create mode 100644 indra/newview/llconversationlog.cpp
 create mode 100644 indra/newview/llconversationlog.h
 create mode 100644 indra/newview/llconversationloglist.cpp
 create mode 100644 indra/newview/llconversationloglist.h
 create mode 100644 indra/newview/llconversationloglistitem.cpp
 create mode 100644 indra/newview/llconversationloglistitem.h
 create mode 100644 indra/newview/llfloaterconversationlog.cpp
 create mode 100644 indra/newview/llfloaterconversationlog.h
 create mode 100644 indra/newview/llfloaterconversationpreview.cpp
 create mode 100644 indra/newview/llfloaterconversationpreview.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_conversation_log.xml
 create mode 100644 indra/newview/skins/default/xui/en/floater_conversation_preview.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_participant_view.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b31b99f47c..3fe1aec5ff 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -130,6 +130,9 @@ set(viewer_SOURCE_FILES
     llcommandlineparser.cpp
     llcompilequeue.cpp
     llconfirmationmanager.cpp
+    llconversationlog.cpp
+    llconversationloglist.cpp
+    llconversationloglistitem.cpp
     llcurrencyuimanager.cpp
     llcylinder.cpp
     lldateutil.cpp
@@ -185,6 +188,8 @@ set(viewer_SOURCE_FILES
     llfloaterbuyland.cpp
     llfloatercamera.cpp
     llfloatercolorpicker.cpp
+    llfloaterconversationlog.cpp
+    llfloaterconversationpreview.cpp
     llfloaterdeleteenvpreset.cpp
     llfloaterdestinations.cpp
     llfloaterdisplayname.cpp
@@ -687,6 +692,9 @@ set(viewer_HEADER_FILES
     llcommandlineparser.h
     llcompilequeue.h
     llconfirmationmanager.h
+    llconversationlog.h
+    llconversationloglist.h
+    llconversationloglistitem.h
     llcurrencyuimanager.h
     llcylinder.h
     lldateutil.h
@@ -742,6 +750,8 @@ set(viewer_HEADER_FILES
     llfloaterbuyland.h
     llfloatercamera.h
     llfloatercolorpicker.h
+    llfloaterconversationlog.h
+    llfloaterconversationpreview.h
     llfloaterdeleteenvpreset.h
     llfloaterdestinations.h
     llfloaterdisplayname.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index da3ff2d1ee..7a5abba971 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10004,6 +10004,28 @@
       <key>Value</key>
       <integer>2</integer>
     </map>
+    <key>CallLogSortOrder</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies sort order for Call Log (0 = by name, 1 = by date)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>2</integer>
+    </map>
+    <key>SortFriendsFirst</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies whether friends will be sorted first in Call Log</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>ShowPGSearchAll</key>    
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 1174d108d2..fe3a1ebf65 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -59,6 +59,7 @@
 #include "llares.h" 
 #include "llcurl.h"
 #include "llcalc.h"
+#include "llconversationlog.h"
 #include "lltexturestats.h"
 #include "lltexturestats.h"
 #include "llviewerwindow.h"
@@ -1757,6 +1758,9 @@ bool LLAppViewer::cleanup()
 	// save mute list. gMuteList used to also be deleted here too.
 	LLMuteList::getInstance()->cache(gAgent.getID());
 
+	//save call log list
+	LLConversationLog::instance().cache();
+
 	if (mPurgeOnExit)
 	{
 		llinfos << "Purging all cache files on exit" << llendflush;
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
new file mode 100644
index 0000000000..df9350407d
--- /dev/null
+++ b/indra/newview/llconversationlog.cpp
@@ -0,0 +1,336 @@
+/**
+ * @file llconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llconversationlog.h"
+#include "lltrans.h"
+
+struct Conversation_params
+{
+	Conversation_params(time_t time)
+	:	mTime(time),
+		mTimestamp(LLConversation::createTimestamp(time))
+	{}
+
+	time_t		mTime;
+	std::string	mTimestamp;
+	SessionType	mConversationType;
+	std::string	mConversationName;
+	std::string	mHistoryFileName;
+	LLUUID		mSessionID;
+	LLUUID		mParticipantID;
+	bool		mIsVoice;
+	bool		mHasOfflineIMs;
+};
+
+/************************************************************************/
+/*             LLConversation implementation                            */
+/************************************************************************/
+
+LLConversation::LLConversation(const Conversation_params& params)
+:	mTime(params.mTime),
+	mTimestamp(params.mTimestamp),
+	mConversationType(params.mConversationType),
+	mConversationName(params.mConversationName),
+	mHistoryFileName(params.mHistoryFileName),
+	mSessionID(params.mSessionID),
+	mParticipantID(params.mParticipantID),
+	mIsVoice(params.mIsVoice),
+	mHasOfflineIMs(params.mHasOfflineIMs)
+{
+	setListenIMFloaterOpened();
+}
+
+LLConversation::LLConversation(const LLIMModel::LLIMSession& session)
+:	mTime(time_corrected()),
+	mTimestamp(createTimestamp(mTime)),
+	mConversationType(session.mSessionType),
+	mConversationName(session.mName),
+	mHistoryFileName(session.mHistoryFileName),
+	mSessionID(session.mSessionID),
+	mParticipantID(session.mOtherParticipantID),
+	mIsVoice(session.mStartedAsIMCall),
+	mHasOfflineIMs(session.mHasOfflineMessage)
+{
+	setListenIMFloaterOpened();
+}
+
+LLConversation::LLConversation(const LLConversation& conversation)
+{
+	mTime				= conversation.getTime();
+	mTimestamp			= conversation.getTimestamp();
+	mConversationType	= conversation.getConversationType();
+	mConversationName	= conversation.getConversationName();
+	mHistoryFileName	= conversation.getHistoryFileName();
+	mSessionID			= conversation.getSessionID();
+	mParticipantID		= conversation.getParticipantID();
+	mIsVoice			= conversation.isVoice();
+	mHasOfflineIMs		= conversation.hasOfflineMessages();
+
+	setListenIMFloaterOpened();
+}
+
+LLConversation::~LLConversation()
+{
+	mIMFloaterShowedConnection.disconnect();
+}
+
+void LLConversation::onIMFloaterShown(const LLUUID& session_id)
+{
+	if (mSessionID == session_id)
+	{
+		mHasOfflineIMs = false;
+	}
+}
+
+// static
+const std::string LLConversation::createTimestamp(const time_t& utc_time)
+{
+	std::string timeStr;
+	LLSD substitution;
+	substitution["datetime"] = (S32) utc_time;
+
+	timeStr = "["+LLTrans::getString ("TimeMonth")+"]/["
+				 +LLTrans::getString ("TimeDay")+"]/["
+				 +LLTrans::getString ("TimeYear")+"] ["
+				 +LLTrans::getString ("TimeHour")+"]:["
+				 +LLTrans::getString ("TimeMin")+"]";
+
+
+	LLStringUtil::format (timeStr, substitution);
+	return timeStr;
+}
+
+void LLConversation::setListenIMFloaterOpened()
+{
+	LLIMFloater* floater = LLIMFloater::findInstance(mSessionID);
+
+	bool has_offline_ims = !mIsVoice && mHasOfflineIMs;
+	bool ims_are_read = 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)
+	{
+		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
+	}
+}
+/************************************************************************/
+/*             LLConversationLog implementation                         */
+/************************************************************************/
+
+LLConversationLog::LLConversationLog()
+{
+	loadFromFile(getFileName());
+
+	LLIMMgr::instance().addSessionObserver(this);
+	LLAvatarTracker::instance().addObserver(this);
+}
+void LLConversationLog::logConversation(const LLConversation& conversation)
+{
+	mConversations.push_back(conversation);
+	notifyObservers();
+}
+
+void LLConversationLog::removeConversation(const LLConversation& conversation)
+{
+	conversations_vec_t::iterator conv_it = mConversations.begin();
+	for(; conv_it != mConversations.end(); ++conv_it)
+	{
+		if (conv_it->getSessionID() == conversation.getSessionID() && conv_it->getTime() == conversation.getTime())
+		{
+			mConversations.erase(conv_it);
+			notifyObservers();
+			return;
+		}
+	}
+}
+
+const LLConversation* LLConversationLog::getConversation(const LLUUID& session_id)
+{
+	conversations_vec_t::const_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::addObserver(LLConversationLogObserver* observer)
+{
+	mObservers.insert(observer);
+}
+
+void LLConversationLog::removeObserver(LLConversationLogObserver* observer)
+{
+	mObservers.erase(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)
+	{
+		LLConversation conversation(*session);
+		LLConversationLog::instance().logConversation(conversation);
+	}
+}
+
+// LLFriendObserver
+void LLConversationLog::changed(U32 mask)
+{
+	if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
+	{
+		notifyObservers();
+	}
+}
+
+void LLConversationLog::cache()
+{
+	saveToFile(getFileName());
+}
+
+std::string LLConversationLog::getFileName()
+{
+	std::string agent_id_string;
+	gAgent.getID().toString(agent_id_string);
+
+	return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, agent_id_string) + ".call_log";
+}
+
+bool LLConversationLog::saveToFile(const std::string& filename)
+{
+	if(!filename.size())
+	{
+		llwarns << "Call log list filename is empty!" << llendl;
+		return false;
+	}
+
+	LLFILE* fp = LLFile::fopen(filename, "wb");
+	if (!fp)
+	{
+		llwarns << "Couldn't open call log list" << filename << llendl;
+		return false;
+	}
+
+	std::string participant_id;
+	std::string conversation_id;
+
+	conversations_vec_t::const_iterator conv_it = mConversations.begin();
+	for (; conv_it != mConversations.end(); ++conv_it)
+	{
+		conv_it->getSessionID().toString(conversation_id);
+		conv_it->getParticipantID().toString(participant_id);
+
+		// examples of two file entries
+		// [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe|
+		// [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
+
+		fprintf(fp, "[%d] %d %d %d %s| %s %s %s|\n",
+				(S32)conv_it->getTime(),
+				(S32)conv_it->getConversationType(),
+				(S32)conv_it->isVoice(),
+				(S32)conv_it->hasOfflineMessages(),
+				     conv_it->getConversationName().c_str(),
+				participant_id.c_str(),
+				conversation_id.c_str(),
+				conv_it->getHistoryFileName().c_str());
+	}
+	fclose(fp);
+	return true;
+}
+bool LLConversationLog::loadFromFile(const std::string& filename)
+{
+	if(!filename.size())
+	{
+		llwarns << "Call log list filename is empty!" << llendl;
+		return false;
+	}
+
+	LLFILE* fp = LLFile::fopen(filename, "rb");
+	if (!fp)
+	{
+		llwarns << "Couldn't open call log list" << filename << llendl;
+		return false;
+	}
+
+	char buffer[MAX_STRING];
+	char conv_name_buffer[MAX_STRING];
+	char part_id_buffer[MAX_STRING];
+	char conv_id_buffer[MAX_STRING];
+	char history_file_name[MAX_STRING];
+	int is_voice;
+	int has_offline_ims;
+	int stype;
+	S32 time;
+
+	while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
+	{
+		conv_name_buffer[0] = '\0';
+		part_id_buffer[0]	= '\0';
+		conv_id_buffer[0]	= '\0';
+
+		sscanf(buffer, "[%d] %d %d %d %[^|]| %s %s %[^|]|",
+				&time,
+				&stype,
+				&is_voice,
+				&has_offline_ims,
+				conv_name_buffer,
+				part_id_buffer,
+				conv_id_buffer,
+				history_file_name);
+
+		Conversation_params params(time);
+		params.mConversationType = (SessionType)stype;
+		params.mIsVoice = is_voice;
+		params.mHasOfflineIMs = has_offline_ims;
+		params.mConversationName = std::string(conv_name_buffer);
+		params.mParticipantID = LLUUID(part_id_buffer);
+		params.mSessionID = LLUUID(conv_id_buffer);
+		params.mHistoryFileName = std::string(history_file_name);
+
+		LLConversation conversation(params);
+		mConversations.push_back(conversation);
+	}
+	fclose(fp);
+
+	notifyObservers();
+	return true;
+}
+
+void LLConversationLog::notifyObservers()
+{
+	std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
+	for (; iter != mObservers.end(); ++iter)
+	{
+		(*iter)->changed();
+	}
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
new file mode 100644
index 0000000000..700472ca8b
--- /dev/null
+++ b/indra/newview/llconversationlog.h
@@ -0,0 +1,164 @@
+/**
+ * @file llconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLCONVERSATIONLOG_H_
+#define LLCONVERSATIONLOG_H_
+
+#include "llcallingcard.h"
+#include "llimfloater.h"
+#include "llimview.h"
+
+class LLConversationLogObserver;
+class Conversation_params;
+
+typedef LLIMModel::LLIMSession::SType SessionType;
+
+/*
+ * This class represents a particular session(conversation) of any type(im/voice/p2p/group/...) by storing some of session's data.
+ * Each LLConversation object has a corresponding visual representation in a form of LLConversationLogListItem.
+ */
+class LLConversation
+{
+public:
+
+	LLConversation(const Conversation_params& params);
+	LLConversation(const LLIMModel::LLIMSession& session);
+	LLConversation(const LLConversation& conversation);
+
+	~LLConversation();
+
+	const SessionType&	getConversationType()	const	{ return mConversationType; }
+	const std::string&	getConversationName()	const	{ return mConversationName; }
+	const std::string&	getHistoryFileName()	const	{ return mHistoryFileName; }
+	const LLUUID&		getSessionID()			const	{ return mSessionID; }
+	const LLUUID&		getParticipantID()		const	{ return mParticipantID; }
+	const std::string&	getTimestamp()			const	{ return mTimestamp; }
+	const time_t&		getTime()				const	{ return mTime; }
+	bool				isVoice()				const	{ return mIsVoice; }
+	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }
+
+	/*
+	 * Resets flag of unread offline message to false when im floater with this conversation is opened.
+	 */
+	void onIMFloaterShown(const LLUUID& session_id);
+
+	/*
+	 * returns string representation(in form of: mm/dd/yyyy hh:mm) of time when conversation was started
+	 */
+	static const std::string createTimestamp(const time_t& utc_time);
+
+private:
+
+	/*
+	 * If conversation has unread offline messages sets callback for opening LLIMFloater
+	 * with this conversation.
+	 */
+	void setListenIMFloaterOpened();
+
+	boost::signals2::connection mIMFloaterShowedConnection;
+
+	time_t			mTime; // start time of conversation
+	SessionType		mConversationType;
+	std::string		mConversationName;
+	std::string		mHistoryFileName;
+	LLUUID			mSessionID;
+	LLUUID			mParticipantID;
+	bool			mIsVoice;
+	bool			mHasOfflineIMs;
+	std::string		mTimestamp; // conversation start time in form of: mm/dd/yyyy hh:mm
+};
+
+/**
+ * LLConversationLog stores all agent's conversations.
+ * This class is responsible for creating and storing LLConversation objects when im or voice session starts.
+ * Also this class saves/retrieves conversations to/from file.
+ *
+ * Also please note that it may be several conversations with the same sessionID stored in the conversation log.
+ * To distinguish two conversations with the same sessionID it's also needed to compare their creation date.
+ */
+
+class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver, LLFriendObserver
+{
+	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);
+
+	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 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
+
+	// LLFriendObserver trigger
+	virtual void changed(U32 mask);
+
+	/**
+	 * public method which is called on viewer exit to save conversation log
+	 */
+	void cache();
+
+private:
+
+	LLConversationLog();
+	void notifyObservers();
+
+	/**
+	 * 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
+	 */
+	std::string getFileName();
+
+	bool saveToFile(const std::string& filename);
+	bool loadFromFile(const std::string& filename);
+
+	typedef std::vector<LLConversation> conversations_vec_t;
+	std::vector<LLConversation>				mConversations;
+	std::set<LLConversationLogObserver*>	mObservers;
+};
+
+class LLConversationLogObserver
+{
+public:
+	virtual ~LLConversationLogObserver(){}
+	virtual void changed() = 0;
+};
+
+#endif /* LLCONVERSATIONLOG_H_ */
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
new file mode 100644
index 0000000000..0433719a89
--- /dev/null
+++ b/indra/newview/llconversationloglist.cpp
@@ -0,0 +1,422 @@
+/**
+ * @file llconversationloglist.cpp
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llavataractions.h"
+#include "llagent.h"
+#include "llfloaterreg.h"
+#include "llfloaterconversationpreview.h"
+#include "llgroupactions.h"
+#include "llconversationloglist.h"
+#include "llconversationloglistitem.h"
+#include "llviewermenu.h"
+
+static LLDefaultChildRegistry::Register<LLConversationLogList> r("conversation_log_list");
+
+static LLConversationLogListNameComparator NAME_COMPARATOR;
+static LLConversationLogListDateComparator DATE_COMPARATOR;
+
+LLConversationLogList::LLConversationLogList(const Params& p)
+:	LLFlatListViewEx(p),
+	mIsDirty(true)
+{
+	LLConversationLog::instance().addObserver(this);
+
+	// Set up context menu.
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar check_registrar;
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+	registrar.add		("Calllog.Action",	boost::bind(&LLConversationLogList::onCustomAction,	this, _2));
+	check_registrar.add ("Calllog.Check",	boost::bind(&LLConversationLogList::isActionChecked,this, _2));
+	enable_registrar.add("Calllog.Enable",	boost::bind(&LLConversationLogList::isActionEnabled,this, _2));
+
+	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
+									"menu_conversation_log_gear.xml",
+									gMenuHolder,
+									LLViewerMenuHolderGL::child_registry_t::instance());
+	if(context_menu)
+	{
+		mContextMenu = context_menu->getHandle();
+	}
+
+	mIsFriendsOnTop = gSavedSettings.getBOOL("SortFriendsFirst");
+}
+
+LLConversationLogList::~LLConversationLogList()
+{
+	if (mContextMenu.get())
+	{
+		mContextMenu.get()->die();
+	}
+
+	LLConversationLog::instance().removeObserver(this);
+}
+
+void LLConversationLogList::draw()
+{
+	if (mIsDirty)
+	{
+		refresh();
+	}
+	LLFlatListViewEx::draw();
+}
+
+BOOL LLConversationLogList::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
+
+	LLToggleableMenu* context_menu = mContextMenu.get();
+	{
+		context_menu->buildDrawLabels();
+	if (context_menu && size())
+		context_menu->updateParent(LLMenuGL::sMenuContainer);
+		LLMenuGL::showPopup(this, context_menu, x, y);
+	}
+
+	return handled;
+}
+
+void LLConversationLogList::setNameFilter(const std::string& filter)
+{
+	std::string filter_upper = filter;
+	LLStringUtil::toUpper(filter_upper);
+	if (mNameFilter != filter_upper)
+	{
+		mNameFilter = filter_upper;
+		setDirty();
+	}
+}
+
+bool LLConversationLogList::findInsensitive(std::string haystack, const std::string& needle_upper)
+{
+    LLStringUtil::toUpper(haystack);
+    return haystack.find(needle_upper) != std::string::npos;
+}
+
+void LLConversationLogList::sortByName()
+{
+	setComparator(&NAME_COMPARATOR);
+	sort();
+}
+
+void LLConversationLogList::sortByDate()
+{
+	setComparator(&DATE_COMPARATOR);
+	sort();
+}
+
+void LLConversationLogList::toggleSortFriendsOnTop()
+{
+	mIsFriendsOnTop = !mIsFriendsOnTop;
+	gSavedSettings.setBOOL("SortFriendsFirst", mIsFriendsOnTop);
+	sort();
+}
+
+void LLConversationLogList::changed()
+{
+	refresh();
+}
+
+void LLConversationLogList::addNewItem(const LLConversation* conversation)
+{
+	LLConversationLogListItem* item = new LLConversationLogListItem(&*conversation);
+	if (!mNameFilter.empty())
+	{
+		item->highlightNameDate(mNameFilter);
+	}
+	addItem(item, conversation->getSessionID(), ADD_TOP);
+}
+
+void LLConversationLogList::refresh()
+{
+	rebuildList();
+	sort();
+
+	mIsDirty = false;
+}
+
+void LLConversationLogList::rebuildList()
+{
+	clear();
+
+	bool have_filter = !mNameFilter.empty();
+
+	const std::vector<LLConversation>& conversations = LLConversationLog::instance().getConversations();
+	std::vector<LLConversation>::const_iterator iter = conversations.begin();
+
+	for (; iter != conversations.end(); ++iter)
+	{
+		bool not_found = have_filter && !findInsensitive(iter->getConversationName(), mNameFilter) && !findInsensitive(iter->getTimestamp(), mNameFilter);
+		if (not_found)
+			continue;
+
+		addNewItem(&*iter);
+	}
+}
+
+void LLConversationLogList::onCustomAction(const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+	const LLUUID& selected_id = getSelectedConversation()->getParticipantID();
+	LLIMModel::LLIMSession::SType stype = getSelectedSessionType();
+
+	if ("im" == command_name)
+	{
+		switch (stype)
+		{
+		case LLIMModel::LLIMSession::P2P_SESSION:
+			LLAvatarActions::startIM(selected_id);
+			break;
+
+		case LLIMModel::LLIMSession::GROUP_SESSION:
+			LLGroupActions::startIM(selected_id);
+			break;
+
+		default:
+			break;
+		}
+	}
+	else if ("call" == command_name)
+	{
+		switch (stype)
+		{
+		case LLIMModel::LLIMSession::P2P_SESSION:
+			LLAvatarActions::startCall(selected_id);
+			break;
+
+		case LLIMModel::LLIMSession::GROUP_SESSION:
+			LLGroupActions::startCall(selected_id);
+			break;
+
+		default:
+			break;
+		}
+	}
+	else if ("view_profile" == command_name)
+	{
+		switch (stype)
+		{
+		case LLIMModel::LLIMSession::P2P_SESSION:
+			LLAvatarActions::showProfile(selected_id);
+			break;
+
+		case LLIMModel::LLIMSession::GROUP_SESSION:
+			LLGroupActions::show(selected_id);
+			break;
+
+		default:
+			break;
+		}
+	}
+	else if ("chat_history" == command_name)
+	{
+		const LLUUID& session_id = getSelectedConversation()->getSessionID();
+		LLFloaterReg::showInstance("preview_conversation", session_id, true);
+	}
+	else if ("offer_teleport" == command_name)
+	{
+		LLAvatarActions::offerTeleport(selected_id);
+	}
+	else if("add_rem_friend" == command_name)
+	{
+		if (LLAvatarActions::isFriend(selected_id))
+		{
+			LLAvatarActions::removeFriendDialog(selected_id);
+		}
+		else
+		{
+			LLAvatarActions::requestFriendshipDialog(selected_id);
+		}
+	}
+	else if ("invite_to_group" == command_name)
+	{
+		LLAvatarActions::inviteToGroup(selected_id);
+	}
+	else if ("show_on_map" == command_name)
+	{
+		LLAvatarActions::showOnMap(selected_id);
+	}
+	else if ("share" == command_name)
+	{
+		LLAvatarActions::share(selected_id);
+	}
+	else if ("pay" == command_name)
+	{
+		LLAvatarActions::pay(selected_id);
+	}
+	else if ("block" == command_name)
+	{
+		LLAvatarActions::toggleBlock(selected_id);
+	}
+}
+
+bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
+{
+	if (numSelected() != 1)
+	{
+		return false;
+	}
+
+	const std::string command_name = userdata.asString();
+
+	LLIMModel::LLIMSession::SType stype = getSelectedSessionType();
+	const LLUUID& selected_id = getSelectedConversation()->getParticipantID();
+
+	bool is_p2p   = LLIMModel::LLIMSession::P2P_SESSION == stype;
+	bool is_group = LLIMModel::LLIMSession::GROUP_SESSION == stype;
+
+	if ("can_im" == command_name || "can_view_profile" == command_name)
+	{
+		return is_p2p || is_group;
+	}
+	else if ("can_view_chat_history" == command_name)
+	{
+		return true;
+	}
+	else if ("can_call"	== command_name)
+	{
+		return (is_p2p || is_group) && LLAvatarActions::canCall();
+	}
+	else if ("add_rem_friend"		== command_name ||
+			 "can_invite_to_group"	== command_name ||
+			 "can_share"			== command_name ||
+			 "can_block"			== command_name ||
+			 "can_pay"				== command_name)
+	{
+		return is_p2p;
+	}
+	else if("can_offer_teleport" == command_name)
+	{
+		return is_p2p && LLAvatarActions::canOfferTeleport(selected_id);
+	}
+	else if ("can_show_on_map")
+	{
+		return is_p2p && ((LLAvatarTracker::instance().isBuddyOnline(selected_id) && is_agent_mappable(selected_id)) || gAgent.isGodlike());
+	}
+
+	return false;
+}
+
+bool LLConversationLogList::isActionChecked(const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+
+	const LLUUID& selected_id = getSelectedConversation()->getParticipantID();
+	bool is_p2p = LLIMModel::LLIMSession::P2P_SESSION == getSelectedSessionType();
+
+	if ("is_blocked" == command_name)
+	{
+		return is_p2p && LLAvatarActions::isBlocked(selected_id);
+	}
+	else if ("is_friend" == command_name)
+	{
+		return is_p2p && LLAvatarActions::isFriend(selected_id);
+	}
+
+	return false;
+}
+
+LLIMModel::LLIMSession::SType LLConversationLogList::getSelectedSessionType()
+{
+	const LLConversationLogListItem* item = getSelectedConversationPanel();
+
+	if (item)
+	{
+		return item->getConversation()->getConversationType();
+	}
+
+	return LLIMModel::LLIMSession::NONE_SESSION;
+}
+
+const LLConversationLogListItem* LLConversationLogList::getSelectedConversationPanel()
+{
+	LLPanel* panel = LLFlatListViewEx::getSelectedItem();
+	LLConversationLogListItem* conv_panel = dynamic_cast<LLConversationLogListItem*>(panel);
+
+	return conv_panel;
+}
+
+const LLConversation* LLConversationLogList::getSelectedConversation()
+{
+	const LLConversationLogListItem* panel = getSelectedConversationPanel();
+
+	if (panel)
+	{
+		return panel->getConversation();
+	}
+
+	return NULL;
+}
+
+bool LLConversationLogListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
+{
+	const LLConversationLogListItem* conversation_item1 = dynamic_cast<const LLConversationLogListItem*>(item1);
+	const LLConversationLogListItem* conversation_item2 = dynamic_cast<const LLConversationLogListItem*>(item2);
+
+	if (!conversation_item1 || !conversation_item2)
+	{
+		llerror("conversation_item1 and conversation_item2 cannot be null", 0);
+		return true;
+	}
+
+	return doCompare(conversation_item1, conversation_item2);
+}
+
+bool LLConversationLogListNameComparator::doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const
+{
+	std::string name1 = conversation1->getConversation()->getConversationName();
+	std::string name2 = conversation2->getConversation()->getConversationName();
+	const LLUUID& id1 = conversation1->getConversation()->getParticipantID();
+	const LLUUID& id2 = conversation2->getConversation()->getParticipantID();
+
+	LLStringUtil::toUpper(name1);
+	LLStringUtil::toUpper(name2);
+
+	bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst");
+	if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
+	{
+		return LLAvatarActions::isFriend(id1);
+	}
+
+	return name1 < name2;
+}
+
+bool LLConversationLogListDateComparator::doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const
+{
+	time_t date1 = conversation1->getConversation()->getTime();
+	time_t date2 = conversation2->getConversation()->getTime();
+	const LLUUID& id1 = conversation1->getConversation()->getParticipantID();
+	const LLUUID& id2 = conversation2->getConversation()->getParticipantID();
+
+	bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst");
+	if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
+	{
+		return LLAvatarActions::isFriend(id1);
+	}
+
+	return date1 > date2;
+}
diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h
new file mode 100644
index 0000000000..dff34a74c6
--- /dev/null
+++ b/indra/newview/llconversationloglist.h
@@ -0,0 +1,143 @@
+/**
+ * @file llconversationloglist.h
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLCONVERSATIONLOGLIST_H_
+#define LLCONVERSATIONLOGLIST_H_
+
+#include "llconversationlog.h"
+#include "llflatlistview.h"
+#include "lltoggleablemenu.h"
+
+class LLConversationLogListItem;
+
+/**
+ * List of all agent's conversations. I.e. history of conversations.
+ * This list represents contents of the LLConversationLog.
+ * Each change in LLConversationLog leads to rebuilding this list, so
+ * it's always in actual state.
+ */
+
+class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogObserver
+{
+	LOG_CLASS(LLConversationLogList);
+public:
+	struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+	{
+		Params(){};
+	};
+
+	LLConversationLogList(const Params& p);
+	virtual ~LLConversationLogList();
+
+	virtual void draw();
+
+	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+	LLToggleableMenu*	getContextMenu() const { return mContextMenu.get(); }
+
+	void addNewItem(const LLConversation* conversation);
+	void setNameFilter(const std::string& filter);
+	void sortByName();
+	void sortByDate();
+	void toggleSortFriendsOnTop();
+	bool getSortFriendsOnTop() const { return mIsFriendsOnTop; }
+
+	/**
+	 * Changes from LLConversationLogObserver
+	 */
+	virtual void changed();
+
+private:
+
+	void setDirty(bool dirty = true) { mIsDirty = dirty; }
+	void refresh();
+
+	/**
+	 * Clears list and re-adds items from LLConverstationLog
+	 * If filter is not empty re-adds items which match the filter
+	 */
+	void rebuildList();
+
+	bool findInsensitive(std::string haystack, const std::string& needle_upper);
+
+	void onCustomAction (const LLSD& userdata);
+	bool isActionEnabled(const LLSD& userdata);
+	bool isActionChecked(const LLSD& userdata);
+
+	LLIMModel::LLIMSession::SType getSelectedSessionType();
+	const LLConversationLogListItem* getSelectedConversationPanel();
+	const LLConversation* getSelectedConversation();
+
+	LLHandle<LLToggleableMenu>	mContextMenu;
+	bool mIsDirty;
+	bool mIsFriendsOnTop;
+	std::string mNameFilter;
+};
+
+/**
+ * Abstract comparator for ConversationLogList items
+ */
+class LLConversationLogListItemComparator : public LLFlatListView::ItemComparator
+{
+	LOG_CLASS(LLConversationLogListItemComparator);
+
+public:
+	LLConversationLogListItemComparator() {};
+	virtual ~LLConversationLogListItemComparator() {};
+
+	virtual bool compare(const LLPanel* item1, const LLPanel* item2) const;
+
+protected:
+
+	virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const = 0;
+};
+
+class LLConversationLogListNameComparator : public LLConversationLogListItemComparator
+{
+	LOG_CLASS(LLConversationLogListNameComparator);
+
+public:
+	LLConversationLogListNameComparator() {};
+	virtual ~LLConversationLogListNameComparator() {};
+
+protected:
+
+	virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const;
+};
+
+class LLConversationLogListDateComparator : public LLConversationLogListItemComparator
+{
+	LOG_CLASS(LLConversationLogListDateComparator);
+
+public:
+	LLConversationLogListDateComparator() {};
+	virtual ~LLConversationLogListDateComparator() {};
+
+protected:
+
+	virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const;
+};
+
+#endif /* LLCONVERSATIONLOGLIST_H_ */
diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
new file mode 100644
index 0000000000..fc2e757864
--- /dev/null
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -0,0 +1,157 @@
+/**
+ * @file llconversationloglistitem.cpp
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+// llui
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "lltextutil.h"
+
+// newview
+#include "llavatariconctrl.h"
+#include "llconversationlog.h"
+#include "llconversationloglistitem.h"
+#include "llgroupiconctrl.h"
+#include "llinventoryicon.h"
+
+LLConversationLogListItem::LLConversationLogListItem(const LLConversation* conversation)
+:	LLPanel(),
+	mConversation(conversation),
+	mConversationName(NULL),
+	mConversationDate(NULL)
+{
+	buildFromFile("panel_conversation_log_list_item.xml");
+
+	LLIMFloater* floater = LLIMFloater::findInstance(mConversation->getSessionID());
+
+	bool has_offline_ims = !mConversation->isVoice() && mConversation->hasOfflineMessages();
+	bool ims_are_read = LLIMFloater::isVisible(floater) && floater->hasFocus();
+
+	if (has_offline_ims && !ims_are_read)
+	{
+		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
+	}
+}
+
+LLConversationLogListItem::~LLConversationLogListItem()
+{
+	mIMFloaterShowedConnection.disconnect();
+}
+
+BOOL LLConversationLogListItem::postBuild()
+{
+	initIcons();
+
+	// set conversation name
+	mConversationName = getChild<LLTextBox>("conversation_name");
+	mConversationName->setValue(mConversation->getConversationName());
+
+	// set conversation date and time
+	mConversationDate = getChild<LLTextBox>("date_time");
+	mConversationDate->setValue(mConversation->getTimestamp());
+
+	getChild<LLButton>("delete_btn")->setClickedCallback(boost::bind(&LLConversationLogListItem::onRemoveBtnClicked, this));
+
+	return TRUE;
+}
+
+void LLConversationLogListItem::initIcons()
+{
+	switch (mConversation->getConversationType())
+	{
+		case LLIMModel::LLIMSession::P2P_SESSION:
+		case LLIMModel::LLIMSession::ADHOC_SESSION:
+		{
+			LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+			avatar_icon->setVisible(TRUE);
+			avatar_icon->setValue(mConversation->getParticipantID());
+			break;
+		}
+		case LLIMModel::LLIMSession::GROUP_SESSION:
+		{
+			LLGroupIconCtrl* group_icon = getChild<LLGroupIconCtrl>("group_icon");
+			group_icon->setVisible(TRUE);
+			group_icon->setValue(mConversation->getSessionID());
+			break;
+		}
+		default:
+			break;
+	}
+
+	if (mConversation->isVoice())
+	{
+		getChild<LLIconCtrl>("voice_session_icon")->setVisible(TRUE);
+	}
+	else
+	{
+		if (mConversation->hasOfflineMessages())
+		{
+			getChild<LLIconCtrl>("unread_ims_icon")->setVisible(TRUE);
+		}
+	}
+}
+
+void LLConversationLogListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+	getChildView("hovered_icon")->setVisible(true);
+	LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLConversationLogListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	getChildView("hovered_icon")->setVisible(false);
+	LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLConversationLogListItem::setValue(const LLSD& value)
+{
+	if (!value.isMap() || !value.has("selected"))
+	{
+		return;
+	}
+
+	getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
+void LLConversationLogListItem::onIMFloaterShown(const LLUUID& session_id)
+{
+	if (mConversation->getSessionID() == session_id)
+	{
+		getChild<LLIconCtrl>("unread_ims_icon")->setVisible(FALSE);
+	}
+}
+
+void LLConversationLogListItem::onRemoveBtnClicked()
+{
+	LLConversationLog::instance().removeConversation(*mConversation);
+}
+
+void LLConversationLogListItem::highlightNameDate(const std::string& highlited_text)
+{
+	LLStyle::Params params;
+	LLTextUtil::textboxSetHighlightedVal(mConversationName, params, mConversation->getConversationName(), highlited_text);
+	LLTextUtil::textboxSetHighlightedVal(mConversationDate, params, mConversation->getTimestamp(), highlited_text);
+}
diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h
new file mode 100644
index 0000000000..deba7d4563
--- /dev/null
+++ b/indra/newview/llconversationloglistitem.h
@@ -0,0 +1,77 @@
+/**
+ * @file llconversationloglistitem.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLCONVERSATIONLOGLISTITEM_H_
+#define LLCONVERSATIONLOGLISTITEM_H_
+
+#include "llimfloater.h"
+#include "llpanel.h"
+
+class LLTextBox;
+class LLConversation;
+
+/**
+ * This class is a visual representation of LLConversation, each of which is LLConversationLog entry.
+ * LLConversationLogList consists of these LLConversationLogListItems.
+ * LLConversationLogListItem consists of:
+ *		conversaion_type_icon
+ *		conversaion_name
+ *		conversaion_date
+ * Also LLConversationLogListItem holds pointer to its LLConversationLog.
+ */
+
+class LLConversationLogListItem : public LLPanel
+{
+public:
+	LLConversationLogListItem(const LLConversation* conversation);
+	virtual ~LLConversationLogListItem();
+
+	void onMouseEnter(S32 x, S32 y, MASK mask);
+	void onMouseLeave(S32 x, S32 y, MASK mask);
+
+	virtual void setValue(const LLSD& value);
+
+	virtual BOOL postBuild();
+
+	void onIMFloaterShown(const LLUUID& session_id);
+	void onRemoveBtnClicked();
+
+	const LLConversation* getConversation() const { return mConversation; }
+
+	void highlightNameDate(const std::string& highlited_text);
+
+private:
+
+	void initIcons();
+
+	const LLConversation* mConversation;
+
+	LLTextBox*		mConversationName;
+	LLTextBox*		mConversationDate;
+
+	boost::signals2::connection mIMFloaterShowedConnection;
+};
+
+#endif /* LLCONVERSATIONLOGITEM_H_ */
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
new file mode 100644
index 0000000000..569ba12ed6
--- /dev/null
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -0,0 +1,127 @@
+/**
+ * @file llfloaterconversationlog.cpp
+ * @brief Functionality of the "conversation log" floater
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llconversationloglist.h"
+#include "llfiltereditor.h"
+#include "llfloaterconversationlog.h"
+#include "llmenubutton.h"
+
+LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key)
+:	LLFloater(key),
+	mConversationLogList(NULL)
+{
+	mCommitCallbackRegistrar.add("CallLog.Action",	boost::bind(&LLFloaterConversationLog::onCustomAction,  this, _2));
+	mEnableCallbackRegistrar.add("CallLog.Check",	boost::bind(&LLFloaterConversationLog::isActionChecked, this, _2));
+}
+
+BOOL LLFloaterConversationLog::postBuild()
+{
+	mConversationLogList = getChild<LLConversationLogList>("conversation_log_list");
+
+	switch (gSavedSettings.getU32("CallLogSortOrder"))
+	{
+	case E_SORT_BY_NAME:
+		mConversationLogList->sortByName();
+		break;
+
+	case E_SORT_BY_DATE:
+		mConversationLogList->sortByDate();
+		break;
+	}
+
+	// Use the context menu of the Conversation list for the Conversation tab gear menu.
+	LLToggleableMenu* conversations_gear_menu = mConversationLogList->getContextMenu();
+	if (conversations_gear_menu)
+	{
+		getChild<LLMenuButton>("conversations_gear_btn")->setMenu(conversations_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+	}
+
+	getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
+
+	return LLFloater::postBuild();
+}
+
+void LLFloaterConversationLog::draw()
+{
+	LLFloater::draw();
+}
+
+void LLFloaterConversationLog::onFilterEdit(const std::string& search_string)
+{
+	std::string filter = search_string;
+	LLStringUtil::trimHead(filter);
+
+	mConversationLogList->setNameFilter(filter);
+}
+
+
+void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+
+	if ("sort_by_name" == command_name)
+	{
+		mConversationLogList->sortByName();
+		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_NAME);
+	}
+	else if ("sort_by_date" == command_name)
+	{
+		mConversationLogList->sortByDate();
+		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_DATE);
+	}
+	else if ("sort_friends_on_top" == command_name)
+	{
+		mConversationLogList->toggleSortFriendsOnTop();
+	}
+}
+
+bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata)
+{
+	return true;
+}
+
+bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+
+	U32 sort_order = gSavedSettings.getU32("CallLogSortOrder");
+
+	if ("sort_by_name" == command_name)
+	{
+		return sort_order == E_SORT_BY_NAME;
+	}
+	else if ("sort_by_date" == command_name)
+	{
+		return sort_order == E_SORT_BY_DATE;
+	}
+	else if ("sort_friends_on_top" == command_name)
+	{
+		return gSavedSettings.getBOOL("SortFriendsFirst");
+	}
+
+	return false;
+}
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
new file mode 100644
index 0000000000..40dd266663
--- /dev/null
+++ b/indra/newview/llfloaterconversationlog.h
@@ -0,0 +1,61 @@
+/**
+ * @file llfloaterconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERCONVERSATIONLOG_H_
+#define LL_LLFLOATERCONVERSATIONLOG_H_
+
+#include "llfloater.h"
+
+class LLConversationLogList;
+
+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(){};
+
+	virtual BOOL postBuild();
+
+	virtual void draw();
+
+	void onFilterEdit(const std::string& search_string);
+
+private:
+
+	void onCustomAction (const LLSD& userdata);
+	bool isActionEnabled(const LLSD& userdata);
+	bool isActionChecked(const LLSD& userdata);
+
+	LLConversationLogList* mConversationLogList;
+};
+
+
+#endif /* LLFLOATERCONVERSATIONLOG_H_ */
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
new file mode 100644
index 0000000000..e8554bb066
--- /dev/null
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -0,0 +1,112 @@
+/**
+ * @file llfloaterconversationpreview.cpp
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llconversationlog.h"
+#include "llfloaterconversationpreview.h"
+#include "llimview.h"
+#include "lllineeditor.h"
+
+LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
+:	LLFloater(session_id),
+	mChatHistory(NULL),
+	mSessionID(session_id.asUUID())
+{}
+
+BOOL LLFloaterConversationPreview::postBuild()
+{
+	mChatHistory = getChild<LLChatHistory>("chat_history");
+
+	const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID);
+	if (conv)
+	{
+		std::string name = conv->getConversationName();
+		LLStringUtil::format_map_t args;
+		args["[NAME]"] = name;
+		std::string title = getString("Title", args);
+		setTitle(title);
+
+		getChild<LLLineEditor>("description")->setValue(name);
+	}
+
+	return LLFloater::postBuild();
+}
+
+void LLFloaterConversationPreview::draw()
+{
+	LLFloater::draw();
+}
+
+void LLFloaterConversationPreview::onOpen(const LLSD& session_id)
+{
+	const LLConversation* conv = LLConversationLog::instance().getConversation(session_id);
+	if (!conv)
+	{
+		return;
+	}
+	std::list<LLSD> messages;
+	std::string file = conv->getHistoryFileName();
+	LLLogChat::loadAllHistory(file, messages);
+
+	if (messages.size())
+	{
+		std::ostringstream message;
+		std::list<LLSD>::const_iterator iter = messages.begin();
+		for (; iter != messages.end(); ++iter)
+		{
+			LLSD msg = *iter;
+
+			std::string time	= msg["time"].asString();
+			LLUUID from_id		= msg["from_id"].asUUID();
+			std::string from	= msg["from"].asString();
+			std::string message	= msg["message"].asString();
+			bool is_history	= msg["is_history"].asBoolean();
+
+			LLChat chat;
+			chat.mFromID = from_id;
+			chat.mSessionID = session_id;
+			chat.mFromName = from;
+			chat.mTimeStr = time;
+			chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
+			chat.mText = message;
+
+			appendMessage(chat);
+		}
+	}
+}
+
+void LLFloaterConversationPreview::appendMessage(const LLChat& chat)
+{
+	if (!chat.mMuted)
+	{
+		LLSD args;
+		args["use_plain_text_chat_history"] = true;
+		args["show_time"] = true;
+		args["show_names_for_p2p_conv"] = true;
+
+		mChatHistory->appendMessage(chat);
+	}
+}
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
new file mode 100644
index 0000000000..cfc7c34485
--- /dev/null
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -0,0 +1,51 @@
+/**
+ * @file llfloaterconversationpreview.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLFLOATERCONVERSATIONPREVIEW_H_
+#define LLFLOATERCONVERSATIONPREVIEW_H_
+
+#include "llchathistory.h"
+#include "llfloater.h"
+
+class LLFloaterConversationPreview : public LLFloater
+{
+public:
+
+	LLFloaterConversationPreview(const LLSD& session_id);
+	virtual ~LLFloaterConversationPreview(){};
+
+	virtual BOOL postBuild();
+
+	virtual void draw();
+	virtual void onOpen(const LLSD& session_id);
+
+private:
+	void appendMessage(const LLChat& chat);
+
+	LLChatHistory*	mChatHistory;
+	LLUUID			mSessionID;
+};
+
+#endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 22ce3cd42b..f1d7d1c04f 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -59,6 +59,8 @@
 #include "llviewerchat.h"
 #include "llnotificationmanager.h"
 
+floater_showed_signal_t LLIMFloater::sIMFloaterShowedSignal;
+
 LLIMFloater::LLIMFloater(const LLUUID& session_id)
   : LLIMConversation(session_id),
 	mLastMessageIndex(-1),
@@ -765,6 +767,11 @@ void LLIMFloater::setVisible(BOOL visible)
 			chiclet->setToggleState(false);
 		}
 	}
+
+	if (visible)
+	{
+		sIMFloaterShowedSignal(mSessionID);
+	}
 }
 
 BOOL LLIMFloater::getVisible()
@@ -1334,3 +1341,8 @@ void LLIMFloater::addToHost(const LLUUID& session_id)
 		}
 	}
 }
+
+boost::signals2::connection LLIMFloater::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb)
+{
+	return LLIMFloater::sIMFloaterShowedSignal.connect(cb);
+}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 2ac11ded20..7e45cf42c2 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -44,6 +44,8 @@ class LLChatHistory;
 class LLInventoryItem;
 class LLInventoryCategory;
 
+typedef boost::signals2::signal<void(const LLUUID& session_id)> floater_showed_signal_t;
+
 /**
  * Individual IM window that appears at the bottom of the screen,
  * optionally "docked" to the bottom tray.
@@ -125,7 +127,11 @@ public:
 
 	bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
 
+	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
+	static floater_showed_signal_t sIMFloaterShowedSignal;
+
 private:
+
 	// process focus events to set a currently active session
 	/* virtual */ void onFocusLost();
 	/* virtual */ void onFocusReceived();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cdbb7c7cca..c66c0cd865 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -175,10 +175,11 @@ LLIMModel::LLIMModel()
 	addNewMsgCallback(boost::bind(&toast_callback, _1));
 }
 
-LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice)
+LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
 :	mSessionID(session_id),
 	mName(name),
 	mType(type),
+	mHasOfflineMessage(has_offline_msg),
 	mParticipantUnreadMessageCount(0),
 	mNumUnread(0),
 	mOtherParticipantID(other_participant_id),
@@ -375,6 +376,8 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 				break;
 			}
 		}
+	default:
+		break;
 	}
 	// Update speakers list when connected
 	if (LLVoiceChannel::STATE_CONNECTED == new_state)
@@ -676,7 +679,7 @@ void LLIMModel::testMessages()
 
 //session name should not be empty
 bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, 
-						   const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice)
+						   const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
 {
 	if (name.empty())
 	{
@@ -690,7 +693,7 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co
 		return false;
 	}
 
-	LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice);
+	LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg);
 	mId2SessionMap[session_id] = session;
 
 	// When notifying observer, name of session is used instead of "name", because they may not be the
@@ -702,10 +705,10 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co
 
 }
 
-bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice)
+bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice, bool has_offline_msg)
 {
 	uuid_vec_t no_ids;
-	return newSession(session_id, name, type, other_participant_id, no_ids, voice);
+	return newSession(session_id, name, type, other_participant_id, no_ids, voice, has_offline_msg);
 }
 
 bool LLIMModel::clearSession(const LLUUID& session_id)
@@ -2398,6 +2401,7 @@ void LLIMMgr::addMessage(
 	const LLUUID& target_id,
 	const std::string& from,
 	const std::string& msg,
+	bool  is_offline_msg,
 	const std::string& session_name,
 	EInstantMessage dialog,
 	U32 parent_estate_id,
@@ -2423,7 +2427,7 @@ void LLIMMgr::addMessage(
 	bool new_session = !hasSession(new_session_id);
 	if (new_session)
 	{
-		LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id);
+		LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg);
 
 		// When we get a new IM, and if you are a god, display a bit
 		// of information about the source. This is to help liaisons
@@ -3315,6 +3319,7 @@ public:
 				from_id,
 				name,
 				buffer,
+				IM_OFFLINE == offline,
 				std::string((char*)&bin_bucket[0]),
 				IM_SESSION_INVITE,
 				message_params["parent_estate_id"].asInteger(),
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 80bf315aa8..fa9d20ca53 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -70,10 +70,11 @@ public:
 			GROUP_SESSION,
 			ADHOC_SESSION,
 			AVALINE_SESSION,
+			NONE_SESSION,
 		} SType;
 
 		LLIMSession(const LLUUID& session_id, const std::string& name, 
-			const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice);
+			const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg);
 		virtual ~LLIMSession();
 
 		void sessionInitReplyReceived(const LLUUID& new_session_id);
@@ -133,6 +134,8 @@ public:
 		//if IM session is created for a voice call
 		bool mStartedAsIMCall;
 
+		bool mHasOfflineMessage;
+
 	private:
 		void onAdHocNameCache(const LLAvatarName& av_name);
 
@@ -181,10 +184,10 @@ public:
 	 * @param name session name should not be empty, will return false if empty
 	 */
 	bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, 
-		const uuid_vec_t& ids, bool voice = false);
+		const uuid_vec_t& ids, bool voice = false, bool has_offline_msg = false);
 
 	bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
-		const LLUUID& other_participant_id, bool voice = false);
+		const LLUUID& other_participant_id, bool voice = false, bool has_offline_msg = false);
 
 	/**
 	 * Remove all session data associated with a session specified by session_id
@@ -325,6 +328,7 @@ public:
 					const LLUUID& target_id,
 					const std::string& from,
 					const std::string& msg,
+					bool  is_offline_msg = false,
 					const std::string& session_name = LLStringUtil::null,
 					EInstantMessage dialog = IM_NOTHING_SPECIAL,
 					U32 parent_estate_id = 0,
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 65fd6d7019..4cf6ff55a4 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -94,6 +94,7 @@
 #include "llcallingcard.h"
 #include "llconsole.h"
 #include "llcontainerview.h"
+#include "llconversationlog.h"
 #include "lldebugview.h"
 #include "lldrawable.h"
 #include "lleventnotifier.h"
@@ -1266,6 +1267,8 @@ bool idle_startup()
 		display_startup();
 		LLStartUp::setStartupState( STATE_MULTIMEDIA_INIT );
 		
+		LLConversationLog::getInstance();
+
 		return FALSE;
 	}
 
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index bf12b08321..5c662af875 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -50,6 +50,8 @@
 #include "llfloaterbump.h"
 #include "llfloaterbvhpreview.h"
 #include "llfloatercamera.h"
+#include "llfloaterconversationlog.h"
+#include "llfloaterconversationpreview.h"
 #include "llfloaterdeleteenvpreset.h"
 #include "llfloaterdisplayname.h"
 #include "llfloatereditdaycycle.h"
@@ -188,6 +190,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
 	LLFloaterReg::add("chat_bar", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
+	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
 
 	LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
 
@@ -253,6 +256,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
 	LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
 	LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
+	LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>);
 	LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewGesture>, "preview");
 	LLFloaterReg::add("preview_notecard", "floater_preview_notecard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewNotecard>, "preview");
 	LLFloaterReg::add("preview_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewLSL>, "preview");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 03c113ecb3..20887f7832 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2396,6 +2396,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				from_id,
 				name,
 				buffer,
+				IM_OFFLINE == offline,
 				LLStringUtil::null,
 				dialog,
 				parent_estate_id,
@@ -2435,7 +2436,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				if (!gIMMgr->isNonFriendSessionNotified(session_id))
 				{
 					std::string message = LLTrans::getString("IM_unblock_only_groups_friends");
-					gIMMgr->addMessage(session_id, from_id, name, message);
+					gIMMgr->addMessage(session_id, from_id, name, message, IM_OFFLINE == offline);
 					gIMMgr->addNotifiedNonFriendSessionID(session_id);
 				}
 
@@ -2448,6 +2449,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 					from_id,
 					name,
 					buffer,
+					IM_OFFLINE == offline,
 					LLStringUtil::null,
 					dialog,
 					parent_estate_id,
@@ -2788,6 +2790,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			from_id,
 			name,
 			buffer,
+			IM_OFFLINE == offline,
 			ll_safe_string((char*)binary_bucket),
 			IM_SESSION_INVITE,
 			parent_estate_id,
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index df1d3f2955..f4c88403a5 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -4072,6 +4072,7 @@ void LLVivoxVoiceClient::messageEvent(
 						session->mCallerID,
 						session->mName.c_str(),
 						message.c_str(),
+						false,
 						LLStringUtil::null,		// default arg
 						IM_NOTHING_SPECIAL,		// default arg
 						0,						// default arg
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
new file mode 100644
index 0000000000..1c5800e25f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+
+<floater
+  can_resize="true"
+  positioning="cascading"
+  height="400"
+  min_height="100"
+  min_width="390"
+  layout="topleft"
+  name="floater_conversation_log"
+  save_rect="true"
+  single_instance="true"
+  reuse_instance="true"
+  title="CONVERSATION LOG"
+  width="450">
+	<panel
+      follows="left|top|right"
+      height="27"
+      layout="topleft"
+      left="0"
+      name="buttons_panel"
+      top="0">
+        <filter_editor
+          follows="left|top|right"
+          height="23"
+          layout="topleft"
+          left="8"
+          label="Filter People"
+          max_length_chars="300"
+          name="people_filter_input"
+          text_color="Black"
+          text_pad_left="10"
+          top="4"
+          width="364" />
+        <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="Conv_toolbar_sort"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="5"
+          menu_filename="menu_conversation_log_view.xml"
+          menu_position="bottomleft"
+          name="conversation_view_btn"
+          top="3"
+          width="31" />
+        <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="OptionsMenu_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="2"
+          name="conversations_gear_btn"
+          top="3"
+          width="31" />
+    </panel>
+    <panel
+      follows="all"
+      height="370"
+      layout="topleft"
+      left="5"
+      name="buttons_panel"
+      right="-5"
+      top_pad="5">
+    <conversation_log_list
+      opaque="true"
+      allow_select="true"
+      follows="all"
+      height="360"
+      layout="topleft"
+      left="3"
+      keep_selection_visible_on_reshape="true"
+      item_pad="2"
+      multi_select="false"
+      name="conversation_log_list"
+      right="-3"
+      top="5" />
+    </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
new file mode 100644
index 0000000000..27b744aefb
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ default_tab_group="1"
+ height="361"
+ layout="topleft"
+ min_height="243"
+ min_width="234"
+ name="preview_conversation"
+ title="CONVERSATION:"
+ width="400">
+    <floater.string
+     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"
+     name="chat_history"
+     parse_highlights="true"
+     parse_urls="true"
+     left="5"
+     width="390">
+    </chat_history>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index e5ef80e352..e8ef3c1df9 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -56,6 +56,7 @@
                      image_overlay="Conv_toolbar_sort"
                      image_selected="Toolbar_Middle_Selected"
                      image_unselected="Toolbar_Middle_Off"
+                     menu_filename="menu_participant_view.xml"
                      layout="topleft"
                      left="10"
                      name="sort_btn"
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000..b8d0eef956
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Conversation Context Menu">
+    <menu_item_call
+     label="IM..."
+     layout="topleft"
+     name="IM">
+        <on_click
+         function="Calllog.Action"
+         parameter="im" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_im" />
+    </menu_item_call>
+    <menu_item_call
+     label="Voice call..."
+     layout="topleft"
+     name="Call">
+        <on_click
+         function="Calllog.Action"
+         parameter="call" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_call" />
+    </menu_item_call>
+    <menu_item_call
+     label="Open chat history..."
+     layout="topleft"
+     name="Chat history">
+        <on_click
+         function="Calllog.Action"
+         parameter="chat_history" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_view_chat_history" />
+    </menu_item_call>
+    <menu_item_call
+     label="View Profile"
+     layout="topleft"
+     name="View Profile">
+        <on_click
+         function="Calllog.Action"
+         parameter="view_profile" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_view_profile" />
+    </menu_item_call>
+    <menu_item_call
+    label="Offer Teleport"
+    name="teleport">
+      <on_click
+       function="Calllog.Action"
+       parameter="offer_teleport"/>
+      <on_enable
+      function="Calllog.Enable"
+      parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_separator />
+    <menu_item_check
+     label="Add friend/Remove friend"
+     layout="topleft"
+     name="Friend_add_remove">
+        <menu_item_check.on_click
+         function="Calllog.Action"
+         parameter="add_rem_friend" />
+        <menu_item_check.on_check
+         function="Calllog.Check"
+         parameter="is_friend" />
+        <menu_item_check.on_enable
+         function="Calllog.Enable"
+         parameter="add_rem_friend" />
+    </menu_item_check>
+    <menu_item_call
+     label="Invite to group..."
+     layout="topleft"
+     name="Invite">
+        <on_click
+         function="Calllog.Action"
+         parameter="invite_to_group"/>
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_invite_to_group" />
+    </menu_item_call>
+    <menu_item_separator />
+    <menu_item_call
+     label="Map"
+     layout="topleft"
+     name="Map">
+        <on_click
+         function="Calllog.Action"
+         parameter="show_on_map" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_show_on_map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Share"
+     layout="topleft"
+     name="Share">
+        <on_click
+         function="Calllog.Action"
+         parameter="share" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_share" />
+    </menu_item_call>
+    <menu_item_call
+     label="Pay"
+     layout="topleft"
+     name="Pay">
+        <on_click
+         function="Calllog.Action"
+         parameter="pay" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_pay" />
+    </menu_item_call>
+    <menu_item_check
+     label="Block/Unblock"
+     layout="topleft"
+     name="Block/Unblock">
+        <menu_item_check.on_click
+         function="Calllog.Action"
+         parameter="block"/>
+        <menu_item_check.on_check
+         function="Calllog.Check"
+         parameter="is_blocked" />
+        <menu_item_check.on_enable
+         function="Calllog.Enable"
+         parameter="can_block" />
+    </menu_item_check>
+
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
new file mode 100644
index 0000000000..4ab8cb4f7d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+     name="menu_conversation_view"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check
+   label="Sort by name"
+   name="sort_by_name">
+      <on_click
+       function="CallLog.Action"
+       parameter="sort_by_name"/>
+      <on_check
+       function="CallLog.Check"
+       parameter="sort_by_name"/>
+  </menu_item_check>
+  <menu_item_check
+   label="Sort by date"
+   name="sort_by_date">
+      <on_click
+       function="CallLog.Action"
+       parameter="sort_by_date" />
+      <on_check
+       function="CallLog.Check"
+       parameter="sort_by_date" />
+  </menu_item_check>
+  <menu_item_separator />
+  <menu_item_check
+   label="Sort friends on top"
+   name="sort_by_friends">
+      <on_click
+       function="CallLog.Action"
+       parameter="sort_friends_on_top" />
+      <on_check
+       function="CallLog.Check"
+       parameter="sort_friends_on_top" />
+  </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
new file mode 100644
index 0000000000..6401b0e3b7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="participant_manu_view">
+    <menu_item_check
+         label="Open conversation log"
+         name="Conversation"
+         visible="true">
+        <menu_item_check.on_check
+         function="Floater.Visible"
+         parameter="conversation" />
+        <menu_item_check.on_click
+         function="Floater.Toggle"
+         parameter="conversation" />
+      </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000..3c98e32e7d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="conversation_log_list_item"
+ top="0"
+ width="380">
+    <icon
+     height="24"
+     follows="top|right|left"
+     image_name="ListItem_Select"
+     layout="topleft"
+     left="0"
+     name="selected_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     follows="top|right|left"
+     height="24"
+     image_name="ListItem_Over"
+     layout="topleft"
+     left="0"
+     name="hovered_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     default_icon_name="voice_session_icon"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left="5"
+     image_name="Audio_Press"
+     mouse_opaque="true"
+     name="voice_session_icon"
+     top="2"
+     visible="false"
+     width="20" />
+    <icon
+     default_icon_name="incoming_unread_im_icon"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left="5"
+     image_name="Movement_Backward_Off"
+     mouse_opaque="false"
+     name="unread_ims_icon"
+     top="2"
+     visible="false"
+     width="20" />
+    <avatar_icon
+     default_icon_name="Generic_Person"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="true"
+     top="2"
+     visible="false"
+     width="20" />
+    <group_icon
+     default_icon_name="Generic_Group"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     mouse_opaque="true"
+     top="2"
+     visible="false"
+     width="20" />
+    <text
+     follows="left|right"
+     font="SansSerifSmall"
+     font.color="DkGray"
+     height="15"
+     layout="topleft"
+     left_pad="5"
+     name="conversation_name"
+     parse_urls="false"
+     top="6"
+     use_ellipses="true"
+     width="180" />
+    <text
+     follows="right"
+     font="SansSerifSmall"
+     font.color="DkGray"
+     height="15"
+     layout="topleft"
+     left_pad="5"
+     name="date_time"
+     parse_urls="false"
+     top="6"
+     use_ellipses="true"
+     width="110"/>
+    <button
+     name="delete_btn"
+     layout="topleft"
+     follows="top|right"
+     image_unselected="Toast_CloseBtn"
+     image_selected="Toast_CloseBtn"
+     top="5"
+     left_pad="0"
+     height="14"
+     width="14"
+     tab_stop="false"/>
+</panel>
\ No newline at end of file
-- 
cgit v1.2.3


From 1da3e890a6a426113c79513d74e94783c5762409 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 27 Jul 2012 13:38:10 -0700
Subject: CHUI-253 FIX Not able to view the contents of a Buy Contents object
 for sale

---
 indra/llui/llsdparam.cpp       |  2 +-
 indra/llxuixml/llinitparam.cpp |  5 +++--
 indra/llxuixml/llinitparam.h   | 45 +++++++++++++++++++++++++-----------------
 3 files changed, 31 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 54c8389772..9f4460a988 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -303,7 +303,7 @@ namespace LLInitParam
 {
 	// LLSD specialization
 	// block param interface
-	bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
+	bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack, bool new_name)
 	{
 		if (name_stack.first == name_stack.second
 			&& p.readValue<LLSD>(mValue))
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index bb160b3c0b..451b638a3f 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -181,7 +181,8 @@ namespace LLInitParam
 
 	bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)
 	{
-		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true))
+		Parser::name_stack_range_t range = std::make_pair(name_stack.begin(), name_stack.end());
+		if (!deserializeBlock(p, range, true))
 		{
 			if (!silent)
 			{
@@ -321,7 +322,7 @@ namespace LLInitParam
 		return true;
 	}
 
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored)
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool ignored)
 	{
 		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
 		bool names_left = name_stack_range.first != name_stack_range.second;
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 606676be2c..a07818dfce 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -571,7 +571,7 @@ namespace LLInitParam
 		};
 
 		typedef bool(*merge_func_t)(Param&, const Param&, bool);
-		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool);
+		typedef bool(*deserialize_func_t)(Param&, Parser&, Parser::name_stack_range_t&, bool);
 		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
 		typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
 		typedef bool(*validation_func_t)(const Param*);
@@ -837,7 +837,7 @@ namespace LLInitParam
 		// Blocks can override this to do custom tracking of changes
 		virtual void paramChanged(const Param& changed_param, bool user_provided) {}
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
 
@@ -969,7 +969,7 @@ namespace LLInitParam
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 			// no further names in stack, attempt to parse value now
@@ -1127,7 +1127,7 @@ namespace LLInitParam
 			}
 		}
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 			// attempt to parse block...
@@ -1286,7 +1286,7 @@ namespace LLInitParam
 		}
 	};
 
-	// container of non-block parameters
+	// list of non-block parameters
 	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
 	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> 
 	:	public Param
@@ -1315,7 +1315,7 @@ namespace LLInitParam
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
 			Parser::name_stack_range_t new_name_stack_range(name_stack_range);
 			self_t& typed_param = static_cast<self_t&>(param);
@@ -1498,7 +1498,7 @@ namespace LLInitParam
 		}
 	};
 
-	// container of block parameters
+	// list of block parameters
 	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
 	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> 
 	:	public Param
@@ -1527,30 +1527,35 @@ namespace LLInitParam
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name) 
+		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name) 
 		{ 
 			Parser::name_stack_range_t new_name_stack_range(name_stack_range);
 			self_t& typed_param = static_cast<self_t&>(param);
 			bool new_value = false;
+			bool new_array_value = false;
 
 			// pop first element if empty string
 			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
 			{
-				new_value |= new_name_stack_range.first->second;
+				new_array_value = new_name_stack_range.first->second;
 				++new_name_stack_range.first;
 			}
-			if (new_name || typed_param.mValues.empty())
+
+			if (new_name || new_array_value || typed_param.mValues.empty())
 			{
 				new_value = true;
 				typed_param.mValues.push_back(value_t());
 			}
-
 			param_value_t& value = typed_param.mValues.back();
 
 			// attempt to parse block...
 			if(value.deserializeBlock(parser, new_name_stack_range, new_name))
 			{
 				typed_param.setProvided();
+				if (new_array_value)
+				{
+					name_stack_range.first->second = false;
+				}
 				return true;
 			}
 			else if(named_value_t::valueNamesExist())
@@ -1564,6 +1569,10 @@ namespace LLInitParam
 					{
 						typed_param.mValues.back().setValueName(name);
 						typed_param.setProvided();
+						if (new_array_value)
+						{
+							name_stack_range.first->second = false;
+						}
 						return true;
 					}
 
@@ -2036,7 +2045,7 @@ namespace LLInitParam
 				}
 			}
 			
-			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+			static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 			{
 				if (name_stack_range.first == name_stack_range.second)
 				{
@@ -2149,14 +2158,14 @@ namespace LLInitParam
 			return mValue.getValue();
 		}
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{
 			if (new_name)
 			{
 				resetToDefault();
 			}
 			return mValue.deserializeBlock(p, name_stack_range, new_name);
-			}
+		}
 
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
 		{
@@ -2242,7 +2251,7 @@ namespace LLInitParam
 			return mValue.getValue();
 		}
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{
 			if (new_name)
 			{
@@ -2372,7 +2381,7 @@ namespace LLInitParam
 			return mValue.get().getValue();
 		}
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{
 			return mValue.get().deserializeBlock(p, name_stack_range, new_name);
 		}
@@ -2481,7 +2490,7 @@ namespace LLInitParam
 		LLSD& getValue() { return mValue; }
 
 		// block param interface
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
 		{
@@ -2524,7 +2533,7 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)
+		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{
 			derived_t& typed_param = static_cast<derived_t&>(*this);
 			// try to parse direct value T
-- 
cgit v1.2.3


From e9c436e00e36710228a7d8856d18e116c0b17503 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 27 Jul 2012 13:43:38 -0700
Subject: fixed line endings

---
 .../default/xui/en/floater_conversation_log.xml    | 168 ++++++++++-----------
 1 file changed, 84 insertions(+), 84 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index 1c5800e25f..9cdeb0d788 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -1,84 +1,84 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
-
-<floater
-  can_resize="true"
-  positioning="cascading"
-  height="400"
-  min_height="100"
-  min_width="390"
-  layout="topleft"
-  name="floater_conversation_log"
-  save_rect="true"
-  single_instance="true"
-  reuse_instance="true"
-  title="CONVERSATION LOG"
-  width="450">
-	<panel
-      follows="left|top|right"
-      height="27"
-      layout="topleft"
-      left="0"
-      name="buttons_panel"
-      top="0">
-        <filter_editor
-          follows="left|top|right"
-          height="23"
-          layout="topleft"
-          left="8"
-          label="Filter People"
-          max_length_chars="300"
-          name="people_filter_input"
-          text_color="Black"
-          text_pad_left="10"
-          top="4"
-          width="364" />
-        <menu_button
-          follows="right"
-          height="25"
-          image_hover_unselected="Toolbar_Middle_Over"
-          image_overlay="Conv_toolbar_sort"
-          image_selected="Toolbar_Middle_Selected"
-          image_unselected="Toolbar_Middle_Off"
-          layout="topleft"
-          left_pad="5"
-          menu_filename="menu_conversation_log_view.xml"
-          menu_position="bottomleft"
-          name="conversation_view_btn"
-          top="3"
-          width="31" />
-        <menu_button
-          follows="right"
-          height="25"
-          image_hover_unselected="Toolbar_Middle_Over"
-          image_overlay="OptionsMenu_Off"
-          image_selected="Toolbar_Middle_Selected"
-          image_unselected="Toolbar_Middle_Off"
-          layout="topleft"
-          left_pad="2"
-          name="conversations_gear_btn"
-          top="3"
-          width="31" />
-    </panel>
-    <panel
-      follows="all"
-      height="370"
-      layout="topleft"
-      left="5"
-      name="buttons_panel"
-      right="-5"
-      top_pad="5">
-    <conversation_log_list
-      opaque="true"
-      allow_select="true"
-      follows="all"
-      height="360"
-      layout="topleft"
-      left="3"
-      keep_selection_visible_on_reshape="true"
-      item_pad="2"
-      multi_select="false"
-      name="conversation_log_list"
-      right="-3"
-      top="5" />
-    </panel>
-</floater>
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+
+<floater
+  can_resize="true"
+  positioning="cascading"
+  height="400"
+  min_height="100"
+  min_width="390"
+  layout="topleft"
+  name="floater_conversation_log"
+  save_rect="true"
+  single_instance="true"
+  reuse_instance="true"
+  title="CONVERSATION LOG"
+  width="450">
+	<panel
+      follows="left|top|right"
+      height="27"
+      layout="topleft"
+      left="0"
+      name="buttons_panel"
+      top="0">
+        <filter_editor
+          follows="left|top|right"
+          height="23"
+          layout="topleft"
+          left="8"
+          label="Filter People"
+          max_length_chars="300"
+          name="people_filter_input"
+          text_color="Black"
+          text_pad_left="10"
+          top="4"
+          width="364" />
+        <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="Conv_toolbar_sort"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="5"
+          menu_filename="menu_conversation_log_view.xml"
+          menu_position="bottomleft"
+          name="conversation_view_btn"
+          top="3"
+          width="31" />
+        <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="OptionsMenu_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="2"
+          name="conversations_gear_btn"
+          top="3"
+          width="31" />
+    </panel>
+    <panel
+      follows="all"
+      height="370"
+      layout="topleft"
+      left="5"
+      name="buttons_panel"
+      right="-5"
+      top_pad="5">
+    <conversation_log_list
+      opaque="true"
+      allow_select="true"
+      follows="all"
+      height="360"
+      layout="topleft"
+      left="3"
+      keep_selection_visible_on_reshape="true"
+      item_pad="2"
+      multi_select="false"
+      name="conversation_log_list"
+      right="-3"
+      top="5" />
+    </panel>
+</floater>
-- 
cgit v1.2.3


From f9ccd6bc9d9a1da849ac21913ff870e2db8ad6a1 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 27 Jul 2012 23:46:25 +0300
Subject: Fixed line endings in files added in CHUI-151.

---
 indra/newview/llfloaterconversationlog.cpp | 254 ++++++++++++++---------------
 indra/newview/llfloaterconversationlog.h   | 122 +++++++-------
 2 files changed, 188 insertions(+), 188 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index 569ba12ed6..c77a9e74bb 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -1,127 +1,127 @@
-/**
- * @file llfloaterconversationlog.cpp
- * @brief Functionality of the "conversation log" floater
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-#include "llviewerprecompiledheaders.h"
-
-#include "llconversationloglist.h"
-#include "llfiltereditor.h"
-#include "llfloaterconversationlog.h"
-#include "llmenubutton.h"
-
-LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key)
-:	LLFloater(key),
-	mConversationLogList(NULL)
-{
-	mCommitCallbackRegistrar.add("CallLog.Action",	boost::bind(&LLFloaterConversationLog::onCustomAction,  this, _2));
-	mEnableCallbackRegistrar.add("CallLog.Check",	boost::bind(&LLFloaterConversationLog::isActionChecked, this, _2));
-}
-
-BOOL LLFloaterConversationLog::postBuild()
-{
-	mConversationLogList = getChild<LLConversationLogList>("conversation_log_list");
-
-	switch (gSavedSettings.getU32("CallLogSortOrder"))
-	{
-	case E_SORT_BY_NAME:
-		mConversationLogList->sortByName();
-		break;
-
-	case E_SORT_BY_DATE:
-		mConversationLogList->sortByDate();
-		break;
-	}
-
-	// Use the context menu of the Conversation list for the Conversation tab gear menu.
-	LLToggleableMenu* conversations_gear_menu = mConversationLogList->getContextMenu();
-	if (conversations_gear_menu)
-	{
-		getChild<LLMenuButton>("conversations_gear_btn")->setMenu(conversations_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
-	}
-
-	getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
-
-	return LLFloater::postBuild();
-}
-
-void LLFloaterConversationLog::draw()
-{
-	LLFloater::draw();
-}
-
-void LLFloaterConversationLog::onFilterEdit(const std::string& search_string)
-{
-	std::string filter = search_string;
-	LLStringUtil::trimHead(filter);
-
-	mConversationLogList->setNameFilter(filter);
-}
-
-
-void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
-{
-	const std::string command_name = userdata.asString();
-
-	if ("sort_by_name" == command_name)
-	{
-		mConversationLogList->sortByName();
-		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_NAME);
-	}
-	else if ("sort_by_date" == command_name)
-	{
-		mConversationLogList->sortByDate();
-		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_DATE);
-	}
-	else if ("sort_friends_on_top" == command_name)
-	{
-		mConversationLogList->toggleSortFriendsOnTop();
-	}
-}
-
-bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata)
-{
-	return true;
-}
-
-bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
-{
-	const std::string command_name = userdata.asString();
-
-	U32 sort_order = gSavedSettings.getU32("CallLogSortOrder");
-
-	if ("sort_by_name" == command_name)
-	{
-		return sort_order == E_SORT_BY_NAME;
-	}
-	else if ("sort_by_date" == command_name)
-	{
-		return sort_order == E_SORT_BY_DATE;
-	}
-	else if ("sort_friends_on_top" == command_name)
-	{
-		return gSavedSettings.getBOOL("SortFriendsFirst");
-	}
-
-	return false;
-}
+/**
+ * @file llfloaterconversationlog.cpp
+ * @brief Functionality of the "conversation log" floater
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llconversationloglist.h"
+#include "llfiltereditor.h"
+#include "llfloaterconversationlog.h"
+#include "llmenubutton.h"
+
+LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key)
+:	LLFloater(key),
+	mConversationLogList(NULL)
+{
+	mCommitCallbackRegistrar.add("CallLog.Action",	boost::bind(&LLFloaterConversationLog::onCustomAction,  this, _2));
+	mEnableCallbackRegistrar.add("CallLog.Check",	boost::bind(&LLFloaterConversationLog::isActionChecked, this, _2));
+}
+
+BOOL LLFloaterConversationLog::postBuild()
+{
+	mConversationLogList = getChild<LLConversationLogList>("conversation_log_list");
+
+	switch (gSavedSettings.getU32("CallLogSortOrder"))
+	{
+	case E_SORT_BY_NAME:
+		mConversationLogList->sortByName();
+		break;
+
+	case E_SORT_BY_DATE:
+		mConversationLogList->sortByDate();
+		break;
+	}
+
+	// Use the context menu of the Conversation list for the Conversation tab gear menu.
+	LLToggleableMenu* conversations_gear_menu = mConversationLogList->getContextMenu();
+	if (conversations_gear_menu)
+	{
+		getChild<LLMenuButton>("conversations_gear_btn")->setMenu(conversations_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+	}
+
+	getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
+
+	return LLFloater::postBuild();
+}
+
+void LLFloaterConversationLog::draw()
+{
+	LLFloater::draw();
+}
+
+void LLFloaterConversationLog::onFilterEdit(const std::string& search_string)
+{
+	std::string filter = search_string;
+	LLStringUtil::trimHead(filter);
+
+	mConversationLogList->setNameFilter(filter);
+}
+
+
+void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+
+	if ("sort_by_name" == command_name)
+	{
+		mConversationLogList->sortByName();
+		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_NAME);
+	}
+	else if ("sort_by_date" == command_name)
+	{
+		mConversationLogList->sortByDate();
+		gSavedSettings.setU32("CallLogSortOrder", E_SORT_BY_DATE);
+	}
+	else if ("sort_friends_on_top" == command_name)
+	{
+		mConversationLogList->toggleSortFriendsOnTop();
+	}
+}
+
+bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata)
+{
+	return true;
+}
+
+bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+
+	U32 sort_order = gSavedSettings.getU32("CallLogSortOrder");
+
+	if ("sort_by_name" == command_name)
+	{
+		return sort_order == E_SORT_BY_NAME;
+	}
+	else if ("sort_by_date" == command_name)
+	{
+		return sort_order == E_SORT_BY_DATE;
+	}
+	else if ("sort_friends_on_top" == command_name)
+	{
+		return gSavedSettings.getBOOL("SortFriendsFirst");
+	}
+
+	return false;
+}
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
index 40dd266663..7d788c0290 100644
--- a/indra/newview/llfloaterconversationlog.h
+++ b/indra/newview/llfloaterconversationlog.h
@@ -1,61 +1,61 @@
-/**
- * @file llfloaterconversationlog.h
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFLOATERCONVERSATIONLOG_H_
-#define LL_LLFLOATERCONVERSATIONLOG_H_
-
-#include "llfloater.h"
-
-class LLConversationLogList;
-
-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(){};
-
-	virtual BOOL postBuild();
-
-	virtual void draw();
-
-	void onFilterEdit(const std::string& search_string);
-
-private:
-
-	void onCustomAction (const LLSD& userdata);
-	bool isActionEnabled(const LLSD& userdata);
-	bool isActionChecked(const LLSD& userdata);
-
-	LLConversationLogList* mConversationLogList;
-};
-
-
-#endif /* LLFLOATERCONVERSATIONLOG_H_ */
+/**
+ * @file llfloaterconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERCONVERSATIONLOG_H_
+#define LL_LLFLOATERCONVERSATIONLOG_H_
+
+#include "llfloater.h"
+
+class LLConversationLogList;
+
+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(){};
+
+	virtual BOOL postBuild();
+
+	virtual void draw();
+
+	void onFilterEdit(const std::string& search_string);
+
+private:
+
+	void onCustomAction (const LLSD& userdata);
+	bool isActionEnabled(const LLSD& userdata);
+	bool isActionChecked(const LLSD& userdata);
+
+	LLConversationLogList* mConversationLogList;
+};
+
+
+#endif /* LLFLOATERCONVERSATIONLOG_H_ */
-- 
cgit v1.2.3


From 3ba619053de562fc623263704af2bc2f415e8389 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 27 Jul 2012 14:10:29 -0700
Subject: CHUI-256 FIX Invalid param warnings in llfolderview when adding and
 deleting items from object inventory

---
 indra/newview/llconversationlog.h        | 2 +-
 indra/newview/llimfloatercontainer.cpp   | 1 +
 indra/newview/llinventorypanel.cpp       | 1 +
 indra/newview/llpanelobjectinventory.cpp | 1 +
 4 files changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 700472ca8b..18865bb80e 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -31,7 +31,7 @@
 #include "llimview.h"
 
 class LLConversationLogObserver;
-class Conversation_params;
+struct Conversation_params;
 
 typedef LLIMModel::LLIMSession::SType SessionType;
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c19683b1c2..74f089811e 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -107,6 +107,7 @@ BOOL LLIMFloaterContainer::postBuild()
 	p.rect = mConversationsListPanel->getLocalRect();
 	p.follows.flags = FOLLOWS_ALL;
 	p.listener = base_item;
+	p.root = NULL;
 
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
 	mConversationsListPanel->addChild(mConversationsRoot);
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 6a7ee3b6a0..be1cd2510d 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -659,6 +659,7 @@ LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool u
 	p.allow_multiselect = mAllowMultiSelect;
 	p.show_empty_message = mShowEmptyMessage;
 	p.show_item_link_overlays = mShowItemLinkOverlays;
+	p.root = NULL;
 
 	return LLUICtrlFactory::create<LLFolderView>(p);
 }
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 5887f4d244..4f2c515bde 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1563,6 +1563,7 @@ void LLPanelObjectInventory::reset()
 	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
 	p.folder_indentation = -14; // subtract space normally reserved for folder expanders
 	p.view_model = &mInventoryViewModel;
+	p.root = NULL;
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
 	//TODO RN: make this happen by manipulating filter object directly
-- 
cgit v1.2.3


From 0479e8d4ad1212b0028805cd4e39b6fe593b86c7 Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Fri, 27 Jul 2012 14:28:31 -0700
Subject: Updating comments for merge conflicts after reviewing with Richard.

---
 indra/llui/llfolderviewitem.cpp | 4 ++--
 indra/newview/llimfloater.cpp   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index cd8d8bafbc..777e778bc0 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1495,7 +1495,7 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	
 	item->getViewModelItem()->dirtyFilter();
 
-	// XXX stinson TODO : handle the creation date
+	// TODO RN - port creation date management to new code location
 #if 0
 	// Update the folder creation date if the child is newer than our current date
 	setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
@@ -1506,7 +1506,7 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	requestSort();
 
 	getViewModelItem()->addChild(item->getViewModelItem());
-	// XXX stinson TODO : handle the creation date
+	// TODO RN - port creation date management to new code location
 #if 0
 	// Traverse parent folders and update creation date and resort, if necessary
 	LLFolderViewFolder* parentp = getParentFolder();
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 5e0e0973fc..260957011e 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -316,7 +316,7 @@ BOOL LLIMFloater::postBuild()
 	mInputEditor = getChild<LLChatEntry>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
 	// enable line history support for instant message bar
-	// XXX stinson TODO : resolve merge conflict
+	// XXX stinson TODO : resolve merge by adding autoreplace to text editors
 #if 0
 	// *TODO Establish LineEditor with autoreplace callback
 	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
-- 
cgit v1.2.3


From ca7b9a944b164602cd8b11bf6512f790743964f3 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 27 Jul 2012 14:36:23 -0700
Subject: build fix

---
 indra/llui/tests/llurlentry_stub.cpp | 2 +-
 indra/llui/tests/llurlmatch_test.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index 61e30d89d0..20e98adf2b 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -123,7 +123,7 @@ namespace LLInitParam
 	{
 		descriptor.mCurrentBlockPtr = this;
 	}
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack, bool new_name){ return true; }
 	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const {}
 	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; }
 	bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 97fe5b2eea..f37d270844 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -93,7 +93,7 @@ namespace LLInitParam
 		mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;
 	}
 
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack, bool new_name){ return true; }
 	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const {}
 	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; }
 	bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
-- 
cgit v1.2.3


From 0b5abcfa8e2adbeb9c9f12644f36ee2c4daee560 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 27 Jul 2012 16:14:31 +0300
Subject: Micro fix for string.xml

---
 indra/newview/skins/default/xui/en/strings.xml | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 9ccd6b5cbe..752710373c 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2140,8 +2140,10 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="InvFolder Gestures">Gestures</string>
 	<string name="InvFolder Favorite">My Favorites</string>
   <!-- historically default name of the Favorites folder can start from either "f" or "F" letter.
-  We should localize both of them with the same value -->
+      Also, it can be written as "Favorite" or "Favorites".
+  We should localize all variants of them with the same value -->
 	<string name="InvFolder favorite">My Favorites</string>
+	<string name="InvFolder Favorites">My Favorites</string>
 	<string name="InvFolder Current Outfit">Current Outfit</string>
 	<string name="InvFolder Initial Outfits">Initial Outfits</string>
 	<string name="InvFolder My Outfits">My Outfits</string>
@@ -2150,6 +2152,7 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 
   <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
 	<string name="InvFolder Friends">Friends</string>
+	<string name="InvFolder Received Items">Received Items</string>
 	<string name="InvFolder All">All</string>
 
 	<string name="no_attachments">No attachments worn</string>
-- 
cgit v1.2.3


From 209fd15176647a4b8defbb6e66daea6eb12d4b42 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Mon, 30 Jul 2012 19:38:27 +0300
Subject: CHUI-244 FIX for propagating the dirty filter flag to the folder view
 item's parent. The filter dirty flag is set after a new child item is added
 to ensure that this item already has a parent and the dirty flag can be
 bubbled up.

---
 indra/llui/llfolderviewitem.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 777e778bc0..b9b6ea7444 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1492,8 +1492,6 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	item->setVisible(FALSE);
 	
 	addChild(item);
-	
-	item->getViewModelItem()->dirtyFilter();
 
 	// TODO RN - port creation date management to new code location
 #if 0
@@ -1531,6 +1529,8 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	//	parentp = parentp->getParentFolder();
 	//}
 
+	item->getViewModelItem()->dirtyFilter();
+
 	return TRUE;
 }
 
@@ -1547,13 +1547,14 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 	folder->reshape(getRect().getWidth(), 0);
 	folder->setVisible(FALSE);
 	addChild( folder );
-	folder->getViewModelItem()->dirtyFilter();
 	// rearrange all descendants too, as our indentation level might have changed
 	folder->requestArrange();
 	requestSort();
 
 	getViewModelItem()->addChild(folder->getViewModelItem());
 
+	folder->getViewModelItem()->dirtyFilter();
+
 	return TRUE;
 }
 
-- 
cgit v1.2.3


From 9fa3407c9c18e0e9592bd659a515ec0b77ba13bd Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 30 Jul 2012 11:35:01 -0700
Subject: CHUI-213: When a new folder is added to inventory, its parent is
 assigned before calling dirtyFilter(). This allows dirtyFilter() to propogate
 the dirty flag up.

---
 indra/llui/llfolderviewitem.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index b9b6ea7444..2f17fa7c35 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1552,8 +1552,8 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 	requestSort();
 
 	getViewModelItem()->addChild(folder->getViewModelItem());
-
-	folder->getViewModelItem()->dirtyFilter();
+  //After addChild since addChild assigns parent to bubble up to when calling dirtyFilter
+  folder->getViewModelItem()->dirtyFilter();
 
 	return TRUE;
 }
-- 
cgit v1.2.3


From 4285cc271eacaca31a1d5d76c8e88debf00235c2 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 30 Jul 2012 15:15:42 -0700
Subject: CHUI-217 FIX Items are not visible in Merchant Outbox cleaned up a
 lot custom code for folder view item creation in inbox and outbox proper
 initialization of views from inventory panel starting folder

---
 indra/llui/llfolderviewitem.cpp                    |  13 +-
 indra/llui/llfolderviewitem.h                      |  10 +-
 indra/llui/lluictrlfactory.cpp                     |   5 -
 indra/llui/lluictrlfactory.h                       |   5 +-
 indra/newview/CMakeLists.txt                       |   2 -
 indra/newview/llagentwearablesfetch.cpp            |   2 +-
 indra/newview/llappearancemgr.cpp                  |   2 +-
 indra/newview/llfloateroutbox.cpp                  |   3 +-
 indra/newview/llinventorybridge.cpp                |  16 +-
 indra/newview/llinventorybridge.h                  |  12 +-
 indra/newview/llinventorymodel.cpp                 |  46 ++++-
 indra/newview/llinventorymodel.h                   |   9 +-
 indra/newview/llinventorypanel.cpp                 | 198 ++++++++++++---------
 indra/newview/llinventorypanel.h                   |  59 ++++--
 indra/newview/llpanellandmarks.cpp                 |  12 +-
 indra/newview/llpanelmarketplaceinboxinventory.cpp |  70 +-------
 indra/newview/llpanelmarketplaceinboxinventory.h   |  13 +-
 .../newview/llpanelmarketplaceoutboxinventory.cpp  | 141 ---------------
 indra/newview/llpanelmarketplaceoutboxinventory.h  |  78 --------
 indra/newview/llplacesinventorybridge.cpp          |   4 +-
 indra/newview/llplacesinventorybridge.h            |   2 +-
 indra/newview/llplacesinventorypanel.cpp           |   5 -
 indra/newview/llplacesinventorypanel.h             |   6 +-
 indra/newview/llsidepanelinventory.cpp             |   3 +-
 indra/newview/lltooldraganddrop.cpp                |   2 +-
 indra/newview/pipeline.cpp                         |   2 +-
 .../skins/default/xui/en/panel_inbox_inventory.xml |   2 +-
 .../skins/default/xui/en/panel_landmarks.xml       |   8 +-
 .../default/xui/en/panel_outbox_inventory.xml      |  18 +-
 .../xui/en/widgets/inbox_inventory_panel.xml       |   3 +-
 .../xui/en/widgets/outbox_folder_view_folder.xml   |   9 -
 .../xui/en/widgets/outbox_inventory_panel.xml      |   2 -
 32 files changed, 282 insertions(+), 480 deletions(-)
 delete mode 100644 indra/newview/llpanelmarketplaceoutboxinventory.cpp
 delete mode 100644 indra/newview/llpanelmarketplaceoutboxinventory.h
 delete mode 100644 indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
 delete mode 100644 indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index b9b6ea7444..1d8dfbbafa 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -89,7 +89,8 @@ LLFolderViewItem::Params::Params()
 	selection_image("selection_image"),
 	item_height("item_height"),
 	item_top_pad("item_top_pad"),
-	creation_date()
+	creation_date(),
+	allow_open("allow_open", true)
 {}
 
 // Default constructor
@@ -112,7 +113,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mLabel(p.name),
 	mRoot(p.root),
 	mViewModelItem(p.listener),
-	mIsMouseOverTitle(false)
+	mIsMouseOverTitle(false),
+	mAllowOpen(p.allow_open)
 {
 	if (mViewModelItem)
 	{
@@ -404,7 +406,10 @@ void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
 
 void LLFolderViewItem::openItem( void )
 {
-	getViewModelItem()->openItem();
+	if (mAllowOpen)
+	{
+		getViewModelItem()->openItem();
+	}
 }
 
 void LLFolderViewItem::rename(const std::string& new_name)
@@ -517,7 +522,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 
 BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
 {
-	getViewModelItem()->openItem();
+	openItem();
 	return TRUE;
 }
 
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 50d3e0580e..df007dd15d 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -61,6 +61,7 @@ public:
 													item_top_pad;
 
 		Optional<time_t>							creation_date;
+		Optional<bool>								allow_open;
 
 		Params();
 	};
@@ -92,14 +93,11 @@ protected:
 	bool						mLabelWidthDirty;
 	LLFolderViewFolder*			mParentFolder;
 	LLFolderViewModelItem*		mViewModelItem;
-	BOOL						mIsCurSelection;
-	BOOL						mSelectPending;
 	LLFontGL::StyleFlags		mLabelStyle;
 	std::string					mLabelSuffix;
 	LLUIImagePtr				mIcon;
 	LLUIImagePtr				mIconOpen;
 	LLUIImagePtr				mIconOverlay;
-	BOOL						mHasVisibleChildren;
 	S32							mIndentation;
 	S32							mItemHeight;
 	S32							mDragStartX,
@@ -109,8 +107,12 @@ protected:
 	//std::string::size_type		mStringMatchOffset;
 	F32							mControlLabelRotation;
 	LLFolderView*				mRoot;
-	BOOL						mDragAndDropTarget;
+	bool						mHasVisibleChildren;
+	bool						mIsCurSelection;
+	bool						mDragAndDropTarget;
 	bool						mIsMouseOverTitle;
+	bool						mAllowOpen;
+	bool						mSelectPending;
 
 	// this is an internal method used for adding items to folders. A
 	// no-op at this level, but reimplemented in derived classes.
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index f64f33bc5e..91a6b3259c 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -304,9 +304,4 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st
 	//LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block<T>);
 }
 
-//static 
-const std::string* LLUICtrlFactory::getWidgetName(const std::type_info* widget_type)
-{
-	return LLWidgetNameRegistry::instance().getValue(widget_type);
-}
 
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index b441cb0c9d..9f18be2371 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -105,7 +105,7 @@ private:
 		ParamDefaults()
 		{
 			// look up template file for this param block...
-			const std::string* param_block_tag = getWidgetName(&typeid(PARAM_BLOCK));
+			const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
 			if (param_block_tag)
 			{	// ...and if it exists, back fill values using the most specific template first
 				PARAM_BLOCK params;
@@ -139,7 +139,6 @@ public:
 	template<typename T>
 	static const typename T::Params& getDefaultParams()
 	{
-		//#pragma message("Generating ParamDefaults")
 		return ParamDefaults<typename T::Params, 0>::instance().get();
 	}
 
@@ -303,8 +302,6 @@ private:
 	}
 
 
-	static const std::string* getWidgetName(const std::type_info* widget_type);
-
 	// this exists to get around dependency on llview
 	static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b71f13a450..626fb8caa5 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -383,7 +383,6 @@ set(viewer_SOURCE_FILES
     llpanelmaininventory.cpp
     llpanelmarketplaceinbox.cpp
     llpanelmarketplaceinboxinventory.cpp
-    llpanelmarketplaceoutboxinventory.cpp
     llpanelmediasettingsgeneral.cpp
     llpanelmediasettingspermissions.cpp
     llpanelmediasettingssecurity.cpp
@@ -942,7 +941,6 @@ set(viewer_HEADER_FILES
     llpanelmaininventory.h
     llpanelmarketplaceinbox.h
     llpanelmarketplaceinboxinventory.h
-    llpanelmarketplaceoutboxinventory.h
     llpanelmediasettingsgeneral.h
     llpanelmediasettingspermissions.h
     llpanelmediasettingssecurity.h
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index e2417cdddb..e31e39dca2 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -342,7 +342,7 @@ void LLLibraryOutfitsFetch::folderDone()
 	}
 
 	mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
-	mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true);
+	mLibraryClothingID = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_CLOTHING, false);
 
 	// If Library->Clothing->Initial Outfits exists, use that.
 	LLNameCategoryCollector matchFolderFunctor("Initial Outfits");
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 6d67e098a6..510abf198a 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2330,7 +2330,7 @@ void LLAppearanceMgr::copyLibraryGestures()
 
 	// Copy gestures
 	LLUUID lib_gesture_cat_id =
-		gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE,false,true);
+		gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_GESTURE,false);
 	if (lib_gesture_cat_id.isNull())
 	{
 		llwarns << "Unable to copy gestures, source category not found" << llendl;
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 04a55b261c..e4ed97892e 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -174,9 +174,8 @@ void LLFloaterOutbox::onOpen(const LLSD& key)
 	if (mOutboxId.isNull())
 	{
 		const bool do_not_create_folder = false;
-		const bool do_not_find_in_library = false;
 		
-		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library);
+		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder);
 		
 		if (outbox_id.isNull())
 		{
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 9f1d4bdec9..14616ca7ab 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -955,7 +955,7 @@ BOOL LLInvFVBridge::isCOFFolder() const
 
 BOOL LLInvFVBridge::isInboxFolder() const
 {
-	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
+	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false);
 	
 	if (inbox_id.isNull())
 	{
@@ -995,7 +995,7 @@ BOOL LLInvFVBridge::isOutboxFolderDirectParent() const
 
 const LLUUID LLInvFVBridge::getOutboxFolder() const
 {
-	const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+	const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 
 	return outbox_id;
 }
@@ -1330,7 +1330,7 @@ LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const
 // +=================================================+
 // |        InventoryFVBridgeBuilder                 |
 // +=================================================+
-LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset_type,
+LLInvFVBridge* LLInventoryFolderViewModelBuilder::createBridge(LLAssetType::EType asset_type,
 														LLAssetType::EType actual_asset_type,
 														LLInventoryType::EType inv_type,
 														LLInventoryPanel* inventory,
@@ -1438,7 +1438,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryItem* itemp = model->getItem(mUUID);
 		if (!itemp) return;
 
-		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 		copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId());
 	}
 }
@@ -2469,7 +2469,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 			}
 			else
 			{
-				if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
+				if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
 				{
 					set_dad_inbox_object(cat_id);
 				}
@@ -2909,7 +2909,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryCategory * cat = gInventory.getCategory(mUUID);
 		if (!cat) return;
 
-		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 		copy_folder_to_outbox(cat, outbox_id, cat->getUUID(), LLToolDragAndDrop::getOperationId());
 	}
 #if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
@@ -4068,7 +4068,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			else
 			{
 				// set up observer to select item once drag and drop from inbox is complete 
-				if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
+				if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
 				{
 					set_dad_inbox_object(inv_item->getUUID());
 				}
@@ -6487,7 +6487,7 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(
 	}
 	else
 	{
-		new_listener = LLInventoryFVBridgeBuilder::createBridge(asset_type,
+		new_listener = LLInventoryFolderViewModelBuilder::createBridge(asset_type,
 																actual_asset_type,
 																inv_type,
 																inventory,
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 9997d1720f..fc0b15acad 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -185,15 +185,15 @@ protected:
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInvFVBridgeBuilder
+// Class LLInventoryFolderViewModelBuilder
 //
-// This class intended to build Folder View Bridge via LLInvFVBridge::createBridge.
-// It can be overridden with another way of creation necessary Inventory-Folder-View-Bridge.
+// This class intended to build Folder View Model via LLInvFVBridge::createBridge.
+// It can be overridden with another way of creation necessary Inventory Folder View Models.
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryFVBridgeBuilder
+class LLInventoryFolderViewModelBuilder
 {
 public:
- 	virtual ~LLInventoryFVBridgeBuilder() {}
+ 	virtual ~LLInventoryFolderViewModelBuilder() {}
 	virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
 										LLAssetType::EType actual_asset_type,
 										LLInventoryType::EType inv_type,
@@ -637,7 +637,7 @@ public:
 };
 
 // Bridge builder to create Inventory-Folder-View-Bridge for Recent Inventory Panel
-class LLRecentInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
+class LLRecentInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder
 {
 public:
 	// Overrides FolderBridge for Recent Inventory Panel.
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 5cb7f53bfa..0673970d89 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -373,13 +373,12 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
 // specifies 'type' as what it defaults to containing. The category is
 // not necessarily only for that type. *NOTE: This will create a new
 // inventory category on the fly if one does not exist.
-const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, 
-													   bool create_folder, 
-													   bool find_in_library)
+const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*, 
+					  bool find_in_library*/)
 {
 	LLUUID rv = LLUUID::null;
 	
-	const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID();
+	const LLUUID &root_id = /*(find_in_library) ? gInventory.getLibraryRootFolderID() :*/ gInventory.getRootFolderID();
 	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
 	{
 		rv = root_id;
@@ -402,7 +401,44 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
 		}
 	}
 	
-	if(rv.isNull() && isInventoryUsable() && (create_folder && !find_in_library))
+	if(rv.isNull() && isInventoryUsable() && (create_folder && true/*!find_in_library*/))
+	{
+		if(root_id.notNull())
+		{
+			return createNewCategory(root_id, preferred_type, LLStringUtil::null);
+		}
+	}
+	return rv;
+}
+
+const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder)
+{
+	LLUUID rv = LLUUID::null;
+
+	const LLUUID &root_id = gInventory.getLibraryRootFolderID();
+	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
+	{
+		rv = root_id;
+	}
+	else if (root_id.notNull())
+	{
+		cat_array_t* cats = NULL;
+		cats = get_ptr_in_map(mParentChildCategoryTree, root_id);
+		if(cats)
+		{
+			S32 count = cats->count();
+			for(S32 i = 0; i < count; ++i)
+			{
+				if(cats->get(i)->getPreferredType() == preferred_type)
+				{
+					rv = cats->get(i)->getUUID();
+					break;
+				}
+			}
+		}
+	}
+
+	if(rv.isNull() && isInventoryUsable() && (create_folder && true/*!find_in_library*/))
 	{
 		if(root_id.notNull())
 		{
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 3613bc4917..503de627a0 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -231,11 +231,12 @@ public:
 	// Returns the uuid of the category that specifies 'type' as what it 
 	// defaults to containing. The category is not necessarily only for that type. 
 	//    NOTE: If create_folder is true, this will create a new inventory category 
-	//    on the fly if one does not exist. *NOTE: if find_in_library is true it 
-	//    will search in the user's library folder instead of "My Inventory"
+	//    on the fly if one does not exist. 
 	const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, 
-										 bool create_folder = true, 
-										 bool find_in_library = false);
+										 bool create_folder = true);
+	//    will search in the user's library folder instead of "My Inventory"
+	const LLUUID findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type, 
+												bool create_folder = true);
 	
 	// Get whatever special folder this object is a child of, if any.
 	const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index be1cd2510d..e9b128e836 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -55,7 +55,7 @@ static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel");
 const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
 const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
 const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
-static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
+static const LLInventoryFolderViewModelBuilder INVENTORY_BRIDGE_BUILDER;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInventoryPanelObserver
@@ -140,7 +140,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 {
 	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
 
-	// contex menu callbacks
+	// context menu callbacks
 	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
 	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
 	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
@@ -151,71 +151,60 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 
 }
 
-void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	
-	std::string start_folder_name(params.start_folder());
-	
-	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(start_folder_name);
-
-	LLUUID root_id;
-
-	if ("LIBRARY" == params.start_folder())
-	{
-		root_id = gInventory.getLibraryRootFolderID();
-	}
-	else
-	{
-		root_id = (preferred_type != LLFolderType::FT_NONE)
-				? gInventory.findCategoryUUIDForType(preferred_type, false, false) 
-				: LLUUID::null;
-	}
-	
-	if ((root_id == LLUUID::null) && !start_folder_name.empty())
-	{
-		llwarns << "No category found that matches start_folder: " << start_folder_name << llendl;
-		root_id = LLUUID::generateNewID();
-	}
-	
-	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
-																	LLAssetType::AT_CATEGORY,
-																	LLInventoryType::IT_CATEGORY,
-																	this,
-																	&mInventoryViewModel,
-																	NULL,
-																	root_id);
-	
-	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
-	addItemID(root_id, mFolderRoot);
-}
 
 void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 {
+	// save off copy of params
+	mParams = params;
 	// Clear up the root view
 	// Note: This needs to be done *before* we build the new folder view 
-	LLFolderViewItem* root_view = getItemByID(gInventory.getRootFolderID());
-	if (root_view)
+	LLUUID root_id = getRootFolderID();
+	if (mFolderRoot)
 	{
-		removeItemID(static_cast<LLFolderViewModelItemInventory*>(root_view->getViewModelItem())->getUUID());
-		root_view->destroyView();
+		removeItemID(root_id);
+		mFolderRoot->destroyView();
+		mFolderRoot = NULL;
 	}
 
 	LLMemType mt(LLMemType::MTYPE_INVENTORY_POST_BUILD);
-
-	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
 	
-	buildFolderView(params);
-
+	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
+	{
+		// Determine the root folder in case specified, and
+		// build the views starting with that folder.
+
+
+		LLFolderView::Params p(mParams.folder_view);
+		p.name = getName();
+		p.title = getLabel();
+		p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+		p.parent_panel = this;
+		p.tool_tip = p.name;
+		p.listener = mInvFVBridgeBuilder->createBridge(	LLAssetType::AT_CATEGORY,
+														LLAssetType::AT_CATEGORY,
+														LLInventoryType::IT_CATEGORY,
+														this,
+														&mInventoryViewModel,
+														NULL,
+														root_id);
+		p.view_model = &mInventoryViewModel;
+		p.use_label_suffix = mParams.use_label_suffix;
+		p.allow_multiselect = mAllowMultiSelect;
+		p.show_empty_message = mShowEmptyMessage;
+		p.show_item_link_overlays = mShowItemLinkOverlays;
+		p.root = NULL;
+
+		mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
+		
+		addItemID(root_id, mFolderRoot);
+	} 	
 	mCommitCallbackRegistrar.popScope();
-	
 	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 	
 	// Scroller
 	LLRect scroller_view_rect = getRect();
 	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
-	LLScrollContainer::Params scroller_params(params.scroll());
+	LLScrollContainer::Params scroller_params(mParams.scroll());
 	scroller_params.rect(scroller_view_rect);
 	mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
 	addChild(mScroller);
@@ -263,7 +252,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	mClipboardState = LLClipboard::instance().getGeneration();
 	
 	// Initialize base class params.
-	LLPanel::initFromParams(params);
+	LLPanel::initFromParams(mParams);
 }
 
 LLInventoryPanel::~LLInventoryPanel()
@@ -562,7 +551,40 @@ LLFolderView* LLInventoryPanel::getRootFolder()
 
 LLUUID LLInventoryPanel::getRootFolderID()
 {
-	return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
+	if (mFolderRoot && mFolderRoot->getViewModelItem())
+	{
+		return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
+
+	}
+	else
+	{
+		LLUUID root_id;
+		if (mParams.start_folder.id.isChosen())
+		{
+			root_id = mParams.start_folder.id;
+		}
+		else
+		{
+			const LLFolderType::EType preferred_type = mParams.start_folder.type.isChosen() 
+				? mParams.start_folder.type
+				: LLViewerFolderType::lookupTypeFromNewCategoryName(mParams.start_folder.name);
+
+			if ("LIBRARY" == mParams.start_folder.name())
+			{
+				root_id = gInventory.getLibraryRootFolderID();
+			}
+			else if (preferred_type != LLFolderType::FT_NONE)
+			{
+				root_id = gInventory.findCategoryUUIDForType(preferred_type, false);
+				if (root_id.isNull())
+				{
+					llwarns << "Could not find folder of type " << preferred_type << llendl;
+					root_id.generateNewID();
+				}
+			}
+		}
+		return root_id;
+	}
 }
 
 
@@ -612,7 +634,16 @@ void LLInventoryPanel::initializeViews()
 {
 	if (!gInventory.isInventoryUsable()) return;
 
-	buildNewViews(gInventory.getRootFolderID());
+	LLUUID root_id = getRootFolderID();
+	if (root_id.notNull())
+	{
+		buildNewViews(getRootFolderID());
+	}
+	else
+	{
+		buildNewViews(gInventory.getRootFolderID());
+		buildNewViews(gInventory.getLibraryRootFolderID());
+	}
 
 	gIdleCallbacks.addFunction(idle, this);
 
@@ -639,34 +670,10 @@ void LLInventoryPanel::initializeViews()
 	}
 }
 
-LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)
-{
-	LLRect folder_rect(0,
-					   0,
-					   getRect().getWidth(),
-					   0);
-
-	LLFolderView::Params p;
-	
-	p.name = getName();
-	p.title = getLabel();
-	p.rect = folder_rect;
-	p.parent_panel = this;
-	p.tool_tip = p.name;
-	p.listener = bridge;
-	p.view_model = &mInventoryViewModel;
-	p.use_label_suffix = useLabelSuffix;
-	p.allow_multiselect = mAllowMultiSelect;
-	p.show_empty_message = mShowEmptyMessage;
-	p.show_item_link_overlays = mShowItemLinkOverlays;
-	p.root = NULL;
-
-	return LLUICtrlFactory::create<LLFolderView>(p);
-}
 
 LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
 {
-	LLFolderViewFolder::Params params;
+	LLFolderViewFolder::Params params(mParams.folder);
 
 	params.name = bridge->getDisplayName();
 	params.root = mFolderRoot;
@@ -678,7 +685,7 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
 
 LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
 {
-	LLFolderViewItem::Params params;
+	LLFolderViewItem::Params params(mParams.item);
 	
 	params.name = bridge->getDisplayName();
 	params.creation_date = bridge->getCreationDate();
@@ -1329,3 +1336,34 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
 	mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
 }
 
+namespace LLInitParam
+{
+	void TypeValues<LLFolderType::EType>::declareValues()
+	{
+		declare(LLFolderType::lookup(LLFolderType::FT_TEXTURE)          , LLFolderType::FT_TEXTURE);
+		declare(LLFolderType::lookup(LLFolderType::FT_SOUND)            , LLFolderType::FT_SOUND);
+		declare(LLFolderType::lookup(LLFolderType::FT_CALLINGCARD)      , LLFolderType::FT_CALLINGCARD);
+		declare(LLFolderType::lookup(LLFolderType::FT_LANDMARK)         , LLFolderType::FT_LANDMARK);
+		declare(LLFolderType::lookup(LLFolderType::FT_CLOTHING)         , LLFolderType::FT_CLOTHING);
+		declare(LLFolderType::lookup(LLFolderType::FT_OBJECT)           , LLFolderType::FT_OBJECT);
+		declare(LLFolderType::lookup(LLFolderType::FT_NOTECARD)         , LLFolderType::FT_NOTECARD);
+		declare(LLFolderType::lookup(LLFolderType::FT_ROOT_INVENTORY)   , LLFolderType::FT_ROOT_INVENTORY);
+		declare(LLFolderType::lookup(LLFolderType::FT_LSL_TEXT)         , LLFolderType::FT_LSL_TEXT);
+		declare(LLFolderType::lookup(LLFolderType::FT_BODYPART)         , LLFolderType::FT_BODYPART);
+		declare(LLFolderType::lookup(LLFolderType::FT_TRASH)            , LLFolderType::FT_TRASH);
+		declare(LLFolderType::lookup(LLFolderType::FT_SNAPSHOT_CATEGORY), LLFolderType::FT_SNAPSHOT_CATEGORY);
+		declare(LLFolderType::lookup(LLFolderType::FT_LOST_AND_FOUND)   , LLFolderType::FT_LOST_AND_FOUND);
+		declare(LLFolderType::lookup(LLFolderType::FT_ANIMATION)        , LLFolderType::FT_ANIMATION);
+		declare(LLFolderType::lookup(LLFolderType::FT_GESTURE)          , LLFolderType::FT_GESTURE);
+		declare(LLFolderType::lookup(LLFolderType::FT_FAVORITE)         , LLFolderType::FT_FAVORITE);
+		declare(LLFolderType::lookup(LLFolderType::FT_ENSEMBLE_START)   , LLFolderType::FT_ENSEMBLE_START);
+		declare(LLFolderType::lookup(LLFolderType::FT_ENSEMBLE_END)     , LLFolderType::FT_ENSEMBLE_END);
+		declare(LLFolderType::lookup(LLFolderType::FT_CURRENT_OUTFIT)   , LLFolderType::FT_CURRENT_OUTFIT);
+		declare(LLFolderType::lookup(LLFolderType::FT_OUTFIT)           , LLFolderType::FT_OUTFIT);
+		declare(LLFolderType::lookup(LLFolderType::FT_MY_OUTFITS)       , LLFolderType::FT_MY_OUTFITS);
+		declare(LLFolderType::lookup(LLFolderType::FT_MESH )            , LLFolderType::FT_MESH );
+		declare(LLFolderType::lookup(LLFolderType::FT_INBOX)            , LLFolderType::FT_INBOX);
+		declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX)           , LLFolderType::FT_OUTBOX);
+		declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT)       , LLFolderType::FT_BASIC_ROOT);
+	}
+}
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 910325cdbc..b66b53f642 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -41,10 +41,19 @@
 #include <set>
 
 class LLInvFVBridge;
-class LLInventoryFVBridgeBuilder;
+class LLInventoryFolderViewModelBuilder;
 class LLInvPanelComplObserver;
 class LLFolderViewModelInventory;
 
+namespace LLInitParam
+{
+	template<>
+	struct TypeValues<LLFolderType::EType> : public TypeValuesHelper<LLFolderType::EType>
+	{
+		static void declareValues();
+	};
+}
+
 class LLInventoryPanel : public LLPanel
 {
 	//--------------------------------------------------------------------
@@ -64,6 +73,19 @@ public:
 		{}
 	};
 
+	struct StartFolder : public LLInitParam::ChoiceBlock<StartFolder>
+	{
+		Alternative<std::string>			name;
+		Alternative<LLUUID>					id;
+		Alternative<LLFolderType::EType>	type;
+
+		StartFolder()
+		:	name("name"), 
+			id("id"),
+			type("type")
+		{}
+	};
+
 	struct Params 
 	:	public LLInitParam::Block<Params, LLPanel::Params>
 	{
@@ -72,11 +94,14 @@ public:
 		Optional<bool>						allow_multi_select;
 		Optional<bool>						show_item_link_overlays;
 		Optional<Filter>					filter;
-		Optional<std::string>               start_folder;
+		Optional<StartFolder>               start_folder;
 		Optional<bool>						use_label_suffix;
 		Optional<bool>						show_empty_message;
 		Optional<LLScrollContainer::Params>	scroll;
 		Optional<bool>						accepts_drag_and_drop;
+		Optional<LLFolderView::Params>		folder_view;
+		Optional<LLFolderViewFolder::Params> folder;
+		Optional<LLFolderViewItem::Params>	 item;
 
 		Params()
 		:	sort_order_setting("sort_order_setting"),
@@ -88,7 +113,10 @@ public:
 			use_label_suffix("use_label_suffix", true),
 			show_empty_message("show_empty_message", true),
 			scroll("scroll"),
-			accepts_drag_and_drop("accepts_drag_and_drop")
+			accepts_drag_and_drop("accepts_drag_and_drop"),
+			folder_view("folder_view"),
+			folder("folder"),
+			item("item")
 		{}
 	};
 
@@ -98,6 +126,7 @@ public:
 protected:
 	LLInventoryPanel(const Params&);
 	void initFromParams(const Params&);
+
 	friend class LLUICtrlFactory;
 public:
 	virtual ~LLInventoryPanel();
@@ -187,29 +216,30 @@ protected:
 	void openStartFolderOrMyInventory(); // open the first level of inventory
 	void onItemsCompletion();			// called when selected items are complete
 
-        LLUUID						mSelectThisID;	
+    LLUUID						mSelectThisID;	
 	LLInventoryModel*			mInventory;
 	LLInventoryObserver*		mInventoryObserver;
 	LLInvPanelComplObserver*	mCompletionObserver;
-	BOOL						mAcceptsDragAndDrop;
-	BOOL 						mAllowMultiSelect;
-	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons
-	BOOL						mShowEmptyMessage;
+	bool						mAcceptsDragAndDrop;
+	bool 						mAllowMultiSelect;
+	bool 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons
+	bool						mShowEmptyMessage;
 
 	LLFolderView*				mFolderRoot;
 	LLScrollContainer*			mScroller;
 
 	LLFolderViewModelInventory	mInventoryViewModel;
+	Params						mParams;	// stored copy of parameter block
 
 	std::map<LLUUID, LLFolderViewItem*> mItemMap;
 	/**
-	 * Pointer to LLInventoryFVBridgeBuilder.
+	 * Pointer to LLInventoryFolderViewModelBuilder.
 	 *
 	 * It is set in LLInventoryPanel's constructor and can be overridden in derived classes with 
 	 * another implementation.
 	 * Take into account it will not be deleted by LLInventoryPanel itself.
 	 */
-	const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder;
+	const LLInventoryFolderViewModelBuilder* mInvFVBridgeBuilder;
 
 
 	//--------------------------------------------------------------------
@@ -239,19 +269,14 @@ protected:
 	// Builds the UI.  Call this once the inventory is usable.
 	void 				initializeViews();
 
-	virtual void		buildFolderView(const LLInventoryPanel::Params& params);
 	LLFolderViewItem*	buildNewViews(const LLUUID& id);
 	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const;
 	
-	virtual LLFolderView*		createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix);
 	virtual LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge);
 	virtual LLFolderViewItem*	createFolderViewItem(LLInvFVBridge * bridge);
 private:
-	BOOL				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
-	BOOL				mViewsInitialized; // Views have been generated
-	// UUID of category from which hierarchy should be built.  Set with the 
-	// "start_folder" xml property.  Default is LLUUID::null that means total Inventory hierarchy. 
-	LLUUID				mStartFolderID;
+	bool				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
+	bool				mViewsInitialized; // Views have been generated
 };
 
 #endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 4bbab52e5a..1a4f3708ac 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -177,7 +177,7 @@ void LLLandmarksPanelObserver::changed(U32 mask)
 	if (!mIsLibraryLandmarksOpen && library)
 	{
 		// Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827.
-		const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true);
+		const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
 		if (landmarks_cat.notNull())
 		{
 			LLOpenFolderByID opener(landmarks_cat);
@@ -306,8 +306,7 @@ bool LLLandmarksPanel::isSingleItemSelected()
 
 	if (mCurrentSelectedList != NULL)
 	{
-		LLPlacesFolderView* root_view =
-				static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder());
+		LLFolderView* root_view = mCurrentSelectedList->getRootFolder();
 
 		if (root_view->getSelectedCount() == 1)
 		{
@@ -588,7 +587,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
 	initLandmarksPanel(mLibraryInventoryPanel);
 
 	// We want to fetch only "Landmarks" category from the library.
-	const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true);
+	const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
 	if (landmarks_cat.notNull())
 	{
 		LLInventoryModelBackgroundFetch::instance().start(landmarks_cat);
@@ -918,8 +917,9 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 {
 	std::string command_name = userdata.asString();
 
-	LLPlacesFolderView* root_folder_view = mCurrentSelectedList ?
-		static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()) : NULL;
+	LLFolderView* root_folder_view = mCurrentSelectedList 
+		? mCurrentSelectedList->getRootFolder() 
+		: NULL;
 
 	if ("collapse_all" == command_name)
 	{
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 6e5a522297..8ad3929999 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -54,69 +54,11 @@ static LLDefaultChildRegistry::Register<LLInboxFolderViewItem> r3("inbox_folder_
 //
 
 LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p)
-	: LLInventoryPanel(p)
-{
-}
+:	LLInventoryPanel(p)
+{}
 
 LLInboxInventoryPanel::~LLInboxInventoryPanel()
-{
-}
-
-// virtual
-void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	
-	LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
-	
-	// leslie -- temporary HACK to work around sim not creating inbox with proper system folder type
-	if (root_id.isNull())
-	{
-		std::string start_folder_name(params.start_folder());
-		
-		LLInventoryModel::cat_array_t* cats;
-		LLInventoryModel::item_array_t* items;
-		
-		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
-		
-		if (cats)
-		{
-			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
-			{
-				LLInventoryCategory* cat = *cat_it;
-				
-				if (cat->getName() == start_folder_name)
-				{
-					root_id = cat->getUUID();
-					break;
-				}
-			}
-		}
-		
-		if (root_id == LLUUID::null)
-		{
-			llwarns << "No category found that matches inbox inventory panel start_folder: " << start_folder_name << llendl;
-		}
-	}
-	// leslie -- end temporary HACK
-	
-	if (root_id == LLUUID::null)
-	{
-		llwarns << "Inbox inventory panel has no root folder!" << llendl;
-		root_id = LLUUID::generateNewID();
-	}
-	
-	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
-																	LLAssetType::AT_CATEGORY,
-																	LLInventoryType::IT_CATEGORY,
-																	this,
-																	&mInventoryViewModel,
-																	NULL,
-																	root_id);
-	
-	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
-}
+{}
 
 LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
 {
@@ -149,9 +91,9 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
 //
 
 LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p)
-	: LLFolderViewFolder(p)
-	, LLBadgeOwner(getHandle())
-	, mFresh(false)
+:	LLFolderViewFolder(p),
+	LLBadgeOwner(getHandle()),
+	mFresh(false)
 {
 #if SUPPORTING_FRESH_ITEM_COUNT
 	initBadgeParams(p.new_badge());
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index 209f3a4098..d8b8a2fe63 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -46,9 +46,6 @@ public:
 	LLInboxInventoryPanel(const Params& p);
 	~LLInboxInventoryPanel();
 
-	// virtual
-	void buildFolderView(const LLInventoryPanel::Params& params);
-
 	// virtual
 	LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge);
 	LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge);
@@ -63,9 +60,8 @@ public:
 		Optional<LLBadge::Params>	new_badge;
 		
 		Params()
-		: new_badge("new_badge")
-		{
-		}
+		:	new_badge("new_badge")
+		{}
 	};
 	
 	LLInboxFolderViewFolder(const Params& p);
@@ -93,9 +89,8 @@ public:
 		Optional<LLBadge::Params>	new_badge;
 
 		Params()
-			: new_badge("new_badge")
-		{
-		}
+		:	new_badge("new_badge")
+		{}
 	};
 
 	LLInboxFolderViewItem(const Params& p);
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
deleted file mode 100644
index 2885dd6266..0000000000
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/** 
- * @file llpanelmarketplaceoutboxinventory.cpp
- * @brief LLOutboxInventoryPanel  class definition
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelmarketplaceoutboxinventory.h"
-
-#include "llfolderviewitem.h"
-#include "llfolderviewmodel.h"
-#include "llinventorybridge.h"
-#include "llinventoryfunctions.h"
-#include "llpanellandmarks.h"
-#include "llplacesinventorybridge.h"
-#include "lltrans.h"
-#include "llviewerfoldertype.h"
-
-
-//
-// statics
-//
-
-static LLDefaultChildRegistry::Register<LLOutboxInventoryPanel> r1("outbox_inventory_panel");
-static LLDefaultChildRegistry::Register<LLOutboxFolderViewFolder> r2("outbox_folder_view_folder");
-
-
-//
-// LLOutboxInventoryPanel Implementation
-//
-
-LLOutboxInventoryPanel::LLOutboxInventoryPanel(const LLOutboxInventoryPanel::Params& p)
-	: LLInventoryPanel(p)
-{
-}
-
-LLOutboxInventoryPanel::~LLOutboxInventoryPanel()
-{
-}
-
-// virtual
-void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	
-	LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
-	
-	if (root_id == LLUUID::null)
-	{
-		llwarns << "Outbox inventory panel has no root folder!" << llendl;
-		root_id = LLUUID::generateNewID();
-	}
-	
-	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
-																	LLAssetType::AT_CATEGORY,
-																	LLInventoryType::IT_CATEGORY,
-																	this,
-																	&mInventoryViewModel,
-																	NULL,
-																	root_id);
-	
-	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
-}
-
-LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
-{
-	LLOutboxFolderViewFolder::Params params;
-	
-	params.name = bridge->getDisplayName();
-	params.root = mFolderRoot;
-	params.listener = bridge;
-	params.tool_tip = params.name;
-	
-	return LLUICtrlFactory::create<LLOutboxFolderViewFolder>(params);
-}
-
-LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
-{
-	LLFolderViewItem::Params params;
-
-	params.name = bridge->getDisplayName();
-	params.creation_date = bridge->getCreationDate();
-	params.root = mFolderRoot;
-	params.listener = bridge;
-	params.rect = LLRect (0, 0, 0, 0);
-	params.tool_tip = params.name;
-
-	return LLUICtrlFactory::create<LLOutboxFolderViewItem>(params);
-}
-
-//
-// LLOutboxFolderViewFolder Implementation
-//
-
-LLOutboxFolderViewFolder::LLOutboxFolderViewFolder(const Params& p)
-	: LLFolderViewFolder(p)
-{
-}
-
-//
-// LLOutboxFolderViewItem Implementation
-//
-
-LLOutboxFolderViewItem::LLOutboxFolderViewItem(const Params& p)
-	: LLFolderViewItem(p)
-{
-}
-
-BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
-{
-	return TRUE;
-}
-
-void LLOutboxFolderViewItem::openItem()
-{
-	// Intentionally do nothing to block attaching items from the outbox
-}
-
-// eof
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.h b/indra/newview/llpanelmarketplaceoutboxinventory.h
deleted file mode 100644
index a6c522b7c2..0000000000
--- a/indra/newview/llpanelmarketplaceoutboxinventory.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/** 
- * @file llpanelmarketplaceoutboxinventory.h
- * @brief LLOutboxInventoryPanel class declaration
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_OUTBOXINVENTORYPANEL_H
-#define LL_OUTBOXINVENTORYPANEL_H
-
-
-#include "llinventorypanel.h"
-#include "llfolderviewitem.h"
-
-
-class LLOutboxInventoryPanel : public LLInventoryPanel
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
-	{
-		Params() {}
-	};
-	
-	LLOutboxInventoryPanel(const Params& p);
-	~LLOutboxInventoryPanel();
-
-	// virtual
-	void buildFolderView(const LLInventoryPanel::Params& params);
-
-	// virtual
-	LLFolderViewFolder *	createFolderViewFolder(LLInvFVBridge * bridge);
-	LLFolderViewItem *		createFolderViewItem(LLInvFVBridge * bridge);
-};
-
-
-class LLOutboxFolderViewFolder : public LLFolderViewFolder
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
-	{
-		Params() {}
-	};
-	
-	LLOutboxFolderViewFolder(const Params& p);
-};
-
-
-class LLOutboxFolderViewItem : public LLFolderViewItem
-{
-public:
-	LLOutboxFolderViewItem(const Params& p);
-
-	// virtual
-	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
-	void openItem();
-};
-
-
-#endif //LL_OUTBOXINVENTORYPANEL_H
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index 1a5f64e295..ebd9604c5b 100644
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -170,7 +170,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 		if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
 		{
 			// *TODO: Create a link folder handler instead if it is necessary
-			new_listener = LLInventoryFVBridgeBuilder::createBridge(
+			new_listener = LLInventoryFolderViewModelBuilder::createBridge(
 				asset_type,
 				actual_asset_type,
 				inv_type,
@@ -184,7 +184,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 		new_listener = new LLPlacesFolderBridge(inv_type, inventory, root, uuid);
 		break;
 	default:
-		new_listener = LLInventoryFVBridgeBuilder::createBridge(
+		new_listener = LLInventoryFolderViewModelBuilder::createBridge(
 			asset_type,
 			actual_asset_type,
 			inv_type,
diff --git a/indra/newview/llplacesinventorybridge.h b/indra/newview/llplacesinventorybridge.h
index 791502990b..07d18d03c5 100644
--- a/indra/newview/llplacesinventorybridge.h
+++ b/indra/newview/llplacesinventorybridge.h
@@ -82,7 +82,7 @@ protected:
  *
  * It builds Bridges for Landmarks and Folders in Places Landmarks Panel
  */
-class LLPlacesInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
+class LLPlacesInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder
 {
 public:
 	/*virtual*/ LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index c46681f556..db3f245389 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -58,11 +58,6 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()
 	delete mSavedFolderState;
 }
 
-void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
-	LLInventoryPanel::buildFolderView(params);
-}
-
 // save current folder open state
 void LLPlacesInventoryPanel::saveFolderState()
 {
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index f647e7f970..1544b51aed 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -46,8 +46,6 @@ public:
 	LLPlacesInventoryPanel(const Params& p);
 	~LLPlacesInventoryPanel();
 
-	/*virtual*/ void buildFolderView(const LLInventoryPanel::Params& params);
-
 	void saveFolderState();
 	void restoreFolderState();
 
@@ -57,7 +55,7 @@ private:
 	LLSaveFolderState*			mSavedFolderState;
 };
 
-
+//TODO RN: this class is currently unused, make sure that behavior remains
 class LLPlacesFolderView : public LLFolderView
 {
 public:
@@ -77,8 +75,6 @@ public:
 		mParentLandmarksPanel = panel;
 	}
 
-	S32 getSelectedCount() { return (S32)mSelectedItems.size(); }
-
 private:
 	/**
 	 * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 47bd620fc6..acb232c77f 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -260,9 +260,8 @@ void LLSidepanelInventory::updateInbox()
 	//
 
 	const bool do_not_create_folder = false;
-	const bool do_not_find_in_library = false;
 
-	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library);
+	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder);
 	
 	// Set up observer to listen for creation of inbox if at least one of them doesn't exist
 	if (inbox_id.isNull())
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 2680e4451b..94c97158a8 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -812,7 +812,7 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 	if (!handled)
 	{
 		// Disallow drag and drop to 3D from the outbox
-		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 		if (outbox_id.notNull())
 		{
 			for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7c744f3c3f..9268e5a869 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -5318,7 +5318,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 				// crazy cast so that we can overwrite the fade value
 				// even though gcc enforces sets as const
 				// (fade value doesn't affect sort so this is safe)
-				Light* farthest_light = ((Light*) (&(*(mNearbyLights.rbegin()))));
+				Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin()))));
 				if (light->dist < farthest_light->dist)
 				{
 					if (farthest_light->fade >= 0.f)
diff --git a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
index 413e22e444..48d38d50e0 100644
--- a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
@@ -2,7 +2,7 @@
 <inbox_inventory_panel
     accepts_drag_and_drop="false"
     name="inventory_inbox"
-    start_folder="Received Items"
+    start_folder.name="Received Items"
     follows="all" layout="topleft"
     top="0" left="0" height="165" width="308"
     top_pad="0"
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index 2a5933e3e9..39805637a0 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -35,7 +35,7 @@
              left="0"
              mouse_opaque="true"
              name="favorites_list"
-             start_folder="Favorites"
+             start_folder.name="Favorites"
              width="307"/>
         </accordion_tab>
         <accordion_tab
@@ -51,7 +51,7 @@
              left="0"
              mouse_opaque="true"
              name="landmarks_list"
-             start_folder="Landmarks"
+             start_folder.name="Landmarks"
              width="307"/>
         </accordion_tab>
         <accordion_tab
@@ -67,7 +67,7 @@
              left="0"
              mouse_opaque="true"
              name="my_inventory_list"
-             start_folder="My Inventory"
+             start_folder.name="My Inventory"
              width="307"/>
           </accordion_tab>
           <accordion_tab
@@ -83,7 +83,7 @@
              left="0"
              mouse_opaque="true"
              name="library_list"
-             start_folder="LIBRARY"
+             start_folder.name="LIBRARY"
              width="313"/>
         </accordion_tab>
     </accordion>
diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
index a3d39e55af..203febbf18 100644
--- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_inventory_panel
+<inventory_panel
     name="inventory_outbox"
-    start_folder="Outbox"
+    start_folder.name="Outbox"
+    show_empty_message="false"
+    show_load_status="false"
+    start_folder.type="outbox"
     follows="all" layout="topleft"
     top="0" left="0" height="165" width="308"
     top_pad="0"
@@ -12,6 +15,11 @@
     bevel_style="none"
     show_item_link_overlays="true"
     tool_tip="Drag and drop items here to prepare them for sale on your storefront"
-    >
-    <scroll reserve_scroll_corner="false" />
-</outbox_inventory_panel>
+    scroll.reserve_scroll_corner="false">
+      <folder folder_arrow_image="Folder_Arrow"
+              folder_indentation="8"
+              item_height="20"
+              item_top_pad="4"
+              selection_image="Rounded_Square"/>
+      <item allow_open="false"/>
+</inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
index 830c27bdac..d5b10e7f51 100644
--- a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
@@ -1,2 +1,3 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inbox_inventory_panel show_load_status="false" />
+<inbox_inventory_panel show_load_status="false"
+                       start_folder.type="inbox"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
deleted file mode 100644
index d19c47f54f..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_folder_view_folder
-  folder_arrow_image="Folder_Arrow"
-  folder_indentation="8"
-  item_height="20" 
-  item_top_pad="4"
-  selection_image="Rounded_Square"
-  >
-</outbox_folder_view_folder>
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
deleted file mode 100644
index 3964569da2..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_inventory_panel show_empty_message="false" show_load_status="false" />
-- 
cgit v1.2.3


From f29bdc27b3038a19317095ef914bd560f3199d28 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 30 Jul 2012 15:16:01 -0700
Subject: moved method from places inventory up into common llfolderview

---
 indra/llui/llfolderview.h | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index ba37a11bbe..5ebd8f73ac 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -217,6 +217,7 @@ public:
 	BOOL getShowSingleSelection() { return mShowSingleSelection; }
 	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
 	bool getUseEllipses() { return mUseEllipses; }
+	S32 getSelectedCount() { return (S32)mSelectedItems.size(); }
 
 	void	update();						// needs to be called periodically (e.g. once per frame)
 
-- 
cgit v1.2.3


From b57d8e9c06e01cc6aa2eca17fa80da0a36a52b91 Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Mon, 30 Jul 2012 19:09:48 -0700
Subject: CHUI-258: Adding a method to better whether nearby chat is visible or
 not.

---
 indra/newview/llnearbychat.cpp                     | 29 ++++++++++++++++++++++
 indra/newview/llnearbychat.h                       |  3 +--
 indra/newview/llnotificationtiphandler.cpp         |  2 +-
 .../newview/skins/default/xui/en/notifications.xml | 16 ++++++++++++
 4 files changed, 47 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 4e53082c05..3bd5f96add 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -419,6 +419,35 @@ void LLNearbyChat::show()
 	setVisible(TRUE);
 }
 
+bool LLNearbyChat::isChatVisible() const
+{
+	bool isVisible = false;
+
+	if (isChatMultiTab())
+	{
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+		// Is the IM floater container ever null?
+		llassert(im_box != NULL);
+		if (im_box != NULL)
+		{
+			if (gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
+			{
+				isVisible = (im_box->getVisible() && !im_box->isMinimized());
+			}
+			else
+			{
+				isVisible = (getVisible() && !isMinimized());
+			}
+		}
+	}
+	else
+	{
+		isVisible = (getVisible() && !isMinimized());
+	}
+
+	return isVisible;
+}
+
 void LLNearbyChat::showHistory()
 {
 	openFloater();
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 90feb71488..a0928e67ef 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -66,6 +66,7 @@ public:
 
 	void addToHost();
 	void show();
+	bool isChatVisible() const;
 
 	/** @param archive true - to save a message to the chat history log */
 	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());
@@ -99,8 +100,6 @@ protected:
 
 	/* virtual */ bool applyRectControl();
 
-	void onToggleNearbyChatPanel();
-
 	/*virtual*/ void onTearOffClicked();
 
 	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 507c6686fd..a420c0d2ed 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -86,7 +86,7 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 
 		// don't show toast if Nearby Chat is opened
 		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-		if (!nearby_chat->isMinimized() && nearby_chat->getVisible())
+		if (nearby_chat->isChatVisible())
 		{
 			return false;
 		}
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 3d057fa8f5..f3d2762d3f 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4204,6 +4204,8 @@ Are you sure you want to change the Estate Covenant?
   <notification
    icon="notifytip.tga"
    name="RegionEntryAccessBlocked_Notify"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
    <tag>fail</tag>
 The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
@@ -4212,6 +4214,8 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu
   <notification
    icon="notifytip.tga"
    name="RegionEntryAccessBlocked_NotifyAdultsOnly"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <tag>fail</tag>
     The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
@@ -4283,6 +4287,8 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu
   <notification
    icon="notifytip.tga"
    name="TeleportEntryAccessBlocked_Notify"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <unique>
       <context>REGIONMATURITY</context>
@@ -4294,6 +4300,8 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu
   <notification
    icon="notifytip.tga"
    name="TeleportEntryAccessBlocked_NotifyAdultsOnly"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <unique>
       <context>REGIONMATURITY</context>
@@ -4414,6 +4422,8 @@ You won't receive any more notifications that you're about to visit a region wit
   <notification
    icon="notifytip.tga"
    name="LandClaimAccessBlocked_Notify"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
     <tag>fail</tag>
@@ -4422,6 +4432,8 @@ You won't receive any more notifications that you're about to visit a region wit
   <notification
    icon="notifytip.tga"
    name="LandClaimAccessBlocked_NotifyAdultsOnly"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <tag>fail</tag>
     The land you're trying to claim contains [REGIONMATURITY] content, which is accessible to adults only.
@@ -4479,6 +4491,8 @@ You won't receive any more notifications that you're about to visit a region wit
   <notification
    icon="notifytip.tga"
    name="LandBuyAccessBlocked_Notify"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
     <tag>fail</tag>
@@ -4487,6 +4501,8 @@ You won't receive any more notifications that you're about to visit a region wit
   <notification
    icon="notifytip.tga"
    name="LandBuyAccessBlocked_NotifyAdultsOnly"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <tag>fail</tag>
     The land you're trying to buy contains [REGIONMATURITY] content, which is accessible to adults only.
-- 
cgit v1.2.3


From c8bc6a9d663c3abcaeec270eb443e30a9108afc4 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 30 Jul 2012 19:47:02 -0700
Subject: CHUI-229 : Fix disappearance of nearby chat list item by forcing all
 list widgets to be visible.

---
 indra/newview/llimfloatercontainer.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index adcd840dfc..405a2b3255 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -418,6 +418,7 @@ void LLIMFloaterContainer::repositioningWidgets()
 		 widget_it++, ++index)
 	{
 		LLFolderViewItem* widget = widget_it->second;
+		widget->setVisible(TRUE);
 		widget->setRect(LLRect(0,
 							   panel_rect.getHeight() - item_height*index,
 							   panel_rect.getWidth(),
@@ -461,7 +462,7 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 	widget->setVisible(TRUE);
 
 	repositioningWidgets();
-
+	
 	mConversationsListPanel->addChild(widget);
 
 	return;
-- 
cgit v1.2.3


From b7536a307cc51aadacc375a2376dde199f26a7d6 Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Tue, 31 Jul 2012 13:48:59 -0700
Subject: CHUI-258: Ensuring that the teleport lure requests are logged to IM
 and not to nearby chat.

---
 indra/newview/skins/default/xui/en/notifications.xml | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f3d2762d3f..e85637826d 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6413,6 +6413,7 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    icon="notify.tga"
    name="TeleportOffered"
    log_to_im="true"
+   log_to_chat="false"
    type="offer">
 [NAME_SLURL] has offered to teleport you to their location:
 
@@ -6434,6 +6435,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="TeleportOffered_MaturityExceeded"
+   log_to_im="true"
+   log_to_chat="false"
    type="offer">
 [NAME_SLURL] has offered to teleport you to their location:
 
@@ -6457,6 +6460,8 @@ This region contains [REGION_CONTENT_MATURITY] content, but your current prefere
   <notification
    icon="notify.tga"
    name="TeleportOffered_MaturityBlocked"
+   log_to_im="true"
+   log_to_chat="false"
    type="notifytip">
 [NAME_SLURL] has offered to teleport you to their location:
 
@@ -6471,6 +6476,7 @@ However, this region contains content accessible to adults only.
    icon="notify.tga"
    name="TeleportOfferSent"
    log_to_im="true"
+   log_to_chat="false"
    show_toast="false"
    type="offer">
 	Teleport offer sent to [TO_NAME]
-- 
cgit v1.2.3


From bc54fc2750c02ea11e8485efc541739a90d9cb3f Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Tue, 31 Jul 2012 16:33:36 -0700
Subject: CHUI-259: Resovling an issue introduced during the recent merge that
 incorrectly altered the conditional scope of when nametag text segments were
 created.

---
 indra/newview/llvoavatar.cpp | 316 +++++++++++++++++++++----------------------
 1 file changed, 158 insertions(+), 158 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index e5362261cf..2871b7b018 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3124,191 +3124,191 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		{
 			debugAvatarRezTime("AvatarRezLeftAppearanceNotification","left appearance mode");
 		}
+	}
 
-		// Rebuild name tag if state change detected
-		if (mNameString.empty()
-			|| new_name
-			|| (!title && !mTitle.empty())
-			|| (title && mTitle != title->getString())
-			|| is_away != mNameAway 
-			|| is_busy != mNameBusy 
-			|| is_muted != mNameMute
-			|| is_appearance != mNameAppearance 
-			|| is_friend != mNameFriend
-			|| is_cloud != mNameCloud)
-		{
-			LLColor4 name_tag_color = getNameTagColor(is_friend);
+	// Rebuild name tag if state change detected
+	if (mNameString.empty()
+		|| new_name
+		|| (!title && !mTitle.empty())
+		|| (title && mTitle != title->getString())
+		|| is_away != mNameAway 
+		|| is_busy != mNameBusy 
+		|| is_muted != mNameMute
+		|| is_appearance != mNameAppearance 
+		|| is_friend != mNameFriend
+		|| is_cloud != mNameCloud)
+	{
+		LLColor4 name_tag_color = getNameTagColor(is_friend);
 
-			clearNameTag();
+		clearNameTag();
 
-			if (is_away || is_muted || is_busy || is_appearance)
+		if (is_away || is_muted || is_busy || is_appearance)
+		{
+			std::string line;
+			if (is_away)
 			{
-				std::string line;
-				if (is_away)
-				{
-					line += LLTrans::getString("AvatarAway");
-					line += ", ";
-				}
-				if (is_busy)
-				{
-					line += LLTrans::getString("AvatarBusy");
-					line += ", ";
-				}
-				if (is_muted)
-				{
-					line += LLTrans::getString("AvatarMuted");
-					line += ", ";
-				}
-				if (is_appearance)
-				{
-					line += LLTrans::getString("AvatarEditingAppearance");
-					line += ", ";
-				}
-				if (is_cloud)
-				{
-					line += LLTrans::getString("LoadingData");
-					line += ", ";
-				}
-				// trim last ", "
-				line.resize( line.length() - 2 );
-				addNameTagLine(line, name_tag_color, LLFontGL::NORMAL,
-					LLFontGL::getFontSansSerifSmall());
+				line += LLTrans::getString("AvatarAway");
+				line += ", ";
 			}
-
-			if (sRenderGroupTitles
-				&& title && title->getString() && title->getString()[0] != '\0')
+			if (is_busy)
 			{
-				std::string title_str = title->getString();
-				LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
-				addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
-					LLFontGL::getFontSansSerifSmall());
+				line += LLTrans::getString("AvatarBusy");
+				line += ", ";
 			}
-
-			static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
-			static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
-
-			if (LLAvatarNameCache::useDisplayNames())
+			if (is_muted)
 			{
-				LLAvatarName av_name;
-				if (!LLAvatarNameCache::get(getID(), &av_name))
-				{
-					// ...call this function back when the name arrives
-					// and force a rebuild
-					LLAvatarNameCache::get(getID(),
-						boost::bind(&LLVOAvatar::clearNameTag, this));
-				}
-
-				// Might be blank if name not available yet, that's OK
-				if (show_display_names)
-				{
-					addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
-						LLFontGL::getFontSansSerif());
-				}
-				// Suppress SLID display if display name matches exactly (ugh)
-				if (show_usernames && !av_name.mIsDisplayNameDefault)
-				{
-					// *HACK: Desaturate the color
-					LLColor4 username_color = name_tag_color * 0.83f;
-					addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
-						LLFontGL::getFontSansSerifSmall());
-				}
+				line += LLTrans::getString("AvatarMuted");
+				line += ", ";
 			}
-			else
+			if (is_appearance)
 			{
-				const LLFontGL* font = LLFontGL::getFontSansSerif();
-				std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
-				addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
+				line += LLTrans::getString("AvatarEditingAppearance");
+				line += ", ";
 			}
-
-			mNameAway = is_away;
-			mNameBusy = is_busy;
-			mNameMute = is_muted;
-			mNameAppearance = is_appearance;
-			mNameFriend = is_friend;
-			mNameCloud = is_cloud;
-			mTitle = title ? title->getString() : "";
-			LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
-			new_name = TRUE;
+			if (is_cloud)
+			{
+				line += LLTrans::getString("LoadingData");
+				line += ", ";
+			}
+			// trim last ", "
+			line.resize( line.length() - 2 );
+			addNameTagLine(line, name_tag_color, LLFontGL::NORMAL,
+				LLFontGL::getFontSansSerifSmall());
 		}
 
-		if (mVisibleChat)
+		if (sRenderGroupTitles
+			&& title && title->getString() && title->getString()[0] != '\0')
 		{
-			mNameText->setFont(LLFontGL::getFontSansSerif());
-			mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
-			mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
+			std::string title_str = title->getString();
+			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
+			addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
+				LLFontGL::getFontSansSerifSmall());
+		}
 
-			char line[MAX_STRING];		/* Flawfinder: ignore */
-			line[0] = '\0';
-			std::deque<LLChat>::iterator chat_iter = mChats.begin();
-			mNameText->clearString();
+		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
+		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
 
-			LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
-			LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
-			LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
-			if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
+		if (LLAvatarNameCache::useDisplayNames())
+		{
+			LLAvatarName av_name;
+			if (!LLAvatarNameCache::get(getID(), &av_name))
 			{
-				++chat_iter;
+				// ...call this function back when the name arrives
+				// and force a rebuild
+				LLAvatarNameCache::get(getID(),
+					boost::bind(&LLVOAvatar::clearNameTag, this));
 			}
 
-			for(; chat_iter != mChats.end(); ++chat_iter)
+			// Might be blank if name not available yet, that's OK
+			if (show_display_names)
 			{
-				F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
-				LLFontGL::StyleFlags style;
-				switch(chat_iter->mChatType)
-				{
-				case CHAT_TYPE_WHISPER:
-					style = LLFontGL::ITALIC;
-					break;
-				case CHAT_TYPE_SHOUT:
-					style = LLFontGL::BOLD;
-					break;
-				default:
-					style = LLFontGL::NORMAL;
-					break;
-				}
-				if (chat_fade_amt < 1.f)
-				{
-					F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
-					mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
-				}
-				else if (chat_fade_amt < 2.f)
-				{
-					F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
-					mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
-				}
-				else if (chat_fade_amt < 3.f)
-				{
-					// *NOTE: only remove lines down to minimum number
-					mNameText->addLine(chat_iter->mText, old_chat, style);
-				}
+				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
+					LLFontGL::getFontSansSerif());
 			}
-			mNameText->setVisibleOffScreen(TRUE);
-
-			if (mTyping)
+			// Suppress SLID display if display name matches exactly (ugh)
+			if (show_usernames && !av_name.mIsDisplayNameDefault)
 			{
-				S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
-				switch(dot_count)
-				{
-				case 1:
-					mNameText->addLine(".", new_chat);
-					break;
-				case 2:
-					mNameText->addLine("..", new_chat);
-					break;
-				case 3:
-					mNameText->addLine("...", new_chat);
-					break;
-				}
-
+				// *HACK: Desaturate the color
+				LLColor4 username_color = name_tag_color * 0.83f;
+				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
+					LLFontGL::getFontSansSerifSmall());
 			}
 		}
 		else
 		{
-			// ...not using chat bubbles, just names
-			mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
-			mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
-			mNameText->setVisibleOffScreen(FALSE);
+			const LLFontGL* font = LLFontGL::getFontSansSerif();
+			std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
+		}
+
+		mNameAway = is_away;
+		mNameBusy = is_busy;
+		mNameMute = is_muted;
+		mNameAppearance = is_appearance;
+		mNameFriend = is_friend;
+		mNameCloud = is_cloud;
+		mTitle = title ? title->getString() : "";
+		LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
+		new_name = TRUE;
+	}
+
+	if (mVisibleChat)
+	{
+		mNameText->setFont(LLFontGL::getFontSansSerif());
+		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
+
+		char line[MAX_STRING];		/* Flawfinder: ignore */
+		line[0] = '\0';
+		std::deque<LLChat>::iterator chat_iter = mChats.begin();
+		mNameText->clearString();
+
+		LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
+		LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
+		LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
+		if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
+		{
+			++chat_iter;
 		}
+
+		for(; chat_iter != mChats.end(); ++chat_iter)
+		{
+			F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
+			LLFontGL::StyleFlags style;
+			switch(chat_iter->mChatType)
+			{
+			case CHAT_TYPE_WHISPER:
+				style = LLFontGL::ITALIC;
+				break;
+			case CHAT_TYPE_SHOUT:
+				style = LLFontGL::BOLD;
+				break;
+			default:
+				style = LLFontGL::NORMAL;
+				break;
+			}
+			if (chat_fade_amt < 1.f)
+			{
+				F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
+				mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
+			}
+			else if (chat_fade_amt < 2.f)
+			{
+				F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
+				mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
+			}
+			else if (chat_fade_amt < 3.f)
+			{
+				// *NOTE: only remove lines down to minimum number
+				mNameText->addLine(chat_iter->mText, old_chat, style);
+			}
+		}
+		mNameText->setVisibleOffScreen(TRUE);
+
+		if (mTyping)
+		{
+			S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
+			switch(dot_count)
+			{
+			case 1:
+				mNameText->addLine(".", new_chat);
+				break;
+			case 2:
+				mNameText->addLine("..", new_chat);
+				break;
+			case 3:
+				mNameText->addLine("...", new_chat);
+				break;
+			}
+
+		}
+	}
+	else
+	{
+		// ...not using chat bubbles, just names
+		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+		mNameText->setVisibleOffScreen(FALSE);
 	}
 }
 
-- 
cgit v1.2.3


From e9a484f98d0376a5651d4f6eb5a692db4f77c800 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 31 Jul 2012 23:46:13 -0700
Subject: CHUI-254 : Fix Inventory filter and item draw() to highlight matching
 substrings in inventory

---
 indra/llui/llfolderviewitem.cpp              | 47 +++++++++++++---------------
 indra/llui/llfolderviewitem.h                |  2 --
 indra/llui/llfolderviewmodel.h               | 15 ++++++++-
 indra/newview/llfolderviewmodelinventory.cpp |  8 ++---
 indra/newview/llfolderviewmodelinventory.h   |  2 +-
 indra/newview/llimfloatercontainer.h         |  4 ++-
 indra/newview/llinventoryfilter.cpp          | 18 +++++++----
 indra/newview/llinventoryfilter.h            |  6 ++--
 8 files changed, 58 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 0f486d06c9..368e3caea8 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -106,8 +106,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mHasVisibleChildren(FALSE),
 	mIndentation(0),
 	mItemHeight(p.item_height),
-	//TODO RN: create interface for string highlighting
-	//mStringMatchOffset(std::string::npos),
 	mControlLabelRotation(0.f),
 	mDragAndDropTarget(FALSE),
 	mLabel(p.name),
@@ -778,29 +776,28 @@ void LLFolderViewItem::draw()
 	//--------------------------------------------------------------------------------//
 	// Highlight string match
 	//
-	//TODO RN: expose interface for highlighting
-	//if (mStringMatchOffset != std::string::npos)
-	//{
-	//	// don't draw backgrounds for zero-length strings
-	//	S32 filter_string_length = getRoot()->getFilterSubString().size();
-	//	if (filter_string_length > 0)
-	//	{
-	//		std::string combined_string = mLabel + mLabelSuffix;
-	//		S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
-	//		S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
-	//		S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
-	//		S32 top = getRect().getHeight() - TOP_PAD;
-	//	
-	//		LLUIImage* box_image = default_params.selection_image;
-	//		LLRect box_rect(left, top, right, bottom);
-	//		box_image->draw(box_rect, sFilterBGColor);
-	//		F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
-	//		F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-	//		font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
-	//						  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-	//						  filter_string_length, S32_MAX, &right_x, FALSE );
-	//	}
-	//}
+	if (mViewModelItem->hasFilterStringMatch())
+	{
+		// don't draw backgrounds for zero-length strings
+		std::string::size_type filter_string_length = mViewModelItem->getFilterStringSize();
+		if (filter_string_length > 0)
+		{
+			std::string combined_string = mLabel + mLabelSuffix;
+			S32 left = llround(text_left) + font->getWidth(combined_string, 0, mViewModelItem->getFilterStringOffset()) - 1;
+			S32 right = left + font->getWidth(combined_string, mViewModelItem->getFilterStringOffset(), filter_string_length) + 2;
+			S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
+			S32 top = getRect().getHeight() - TOP_PAD;
+
+			LLUIImage* box_image = default_params.selection_image;
+			LLRect box_rect(left, top, right, bottom);
+			box_image->draw(box_rect, sFilterBGColor);
+			F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
+			F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+			font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
+							  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+							  filter_string_length, S32_MAX, &right_x, FALSE );
+		}
+	}
 }
 
 const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index df007dd15d..e323237b13 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -103,8 +103,6 @@ protected:
 	S32							mDragStartX,
 								mDragStartY;
 
-	//TODO RN: create interface for string highlighting
-	//std::string::size_type		mStringMatchOffset;
 	F32							mControlLabelRotation;
 	LLFolderView*				mRoot;
 	bool						mHasVisibleChildren;
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index acdec53602..f655e6e4d6 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -73,6 +73,8 @@ public:
 
 	virtual bool				showAllResults() const = 0;
 
+	virtual std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const = 0;
+	virtual std::string::size_type getFilterStringSize() const = 0;
 	// +-------------------------------------------------------------------+
 	// + Status
 	// +-------------------------------------------------------------------+
@@ -155,8 +157,11 @@ public:
 	virtual void filter( LLFolderViewFilter& filter) = 0;
 	virtual bool passedFilter(S32 filter_generation = -1) = 0;
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
-	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) = 0;
+	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) = 0;
 	virtual void dirtyFilter() = 0;
+	virtual bool hasFilterStringMatch() = 0;
+	virtual std::string::size_type getFilterStringOffset() = 0;
+	virtual std::string::size_type getFilterStringSize() = 0;
 
 	virtual S32	getLastFilterGeneration() const = 0;
 
@@ -193,6 +198,8 @@ public:
 		mPassedFilter(true),
 		mPassedFolderFilter(true),
 		mPrevPassedAllFilters(false),
+		mStringMatchOffsetFilter(std::string::npos),
+		mStringFilterSize(0),
 		mFolderViewItem(NULL),
 		mLastFilterGeneration(-1),
 		mMostFilteredDescendantGeneration(-1),
@@ -216,6 +223,10 @@ public:
 			mParent->dirtyFilter();
 		}	
 	}
+	bool hasFilterStringMatch() { return mStringMatchOffsetFilter != std::string::npos; }
+	std::string::size_type getFilterStringOffset() { return mStringMatchOffsetFilter; }
+	std::string::size_type getFilterStringSize() { return mStringFilterSize; }
+	
 	virtual void addChild(LLFolderViewModelItem* child) 
 	{ 
 		mChildren.push_back(child); 
@@ -234,6 +245,8 @@ protected:
 	bool					mPassedFilter;
 	bool					mPassedFolderFilter;
 	bool					mPrevPassedAllFilters;
+	std::string::size_type	mStringMatchOffsetFilter;
+	std::string::size_type	mStringFilterSize;
 
 	S32						mLastFilterGeneration;
 	S32						mMostFilteredDescendantGeneration;
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 13ca73917b..0878d15d06 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -144,11 +144,13 @@ bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generati
 	return mMostFilteredDescendantGeneration >= filter_generation; 
 }
 
-void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation)
+void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size)
 {
 	mPassedFilter = passed;
 	mPassedFolderFilter = passed_folder;
 	mLastFilterGeneration = filter_generation;
+	mStringMatchOffsetFilter = string_offset;
+	mStringFilterSize = string_size;
 
 	bool passed_filter_before = mPrevPassedAllFilters;
 	mPrevPassedAllFilters = passedFilter(filter_generation);
@@ -226,9 +228,7 @@ void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 								? filter.checkFolder(this)
 								: true;
 
-		setPassedFilter(passed_filter, passed_filter_folder, filter_generation);
-		//TODO RN: create interface for string highlighting
-		//mStringMatchOffset = filter.getStringMatchOffset(this);
+		setPassedFilter(passed_filter, passed_filter_folder, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize());
 	}
 }
 
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index ab67c93897..72c8047325 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -58,7 +58,7 @@ public:
 	virtual bool potentiallyVisible();
 	virtual bool passedFilter(S32 filter_generation = -1);
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1);
-	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
+	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0);
 	virtual void filter( LLFolderViewFilter& filter);
 	virtual void filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
 
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 7005ab7b6a..9b487dd652 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -91,7 +91,7 @@ public:
 	virtual bool potentiallyVisible() { return true; }
 	virtual void filter( LLFolderViewFilter& filter) { }
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
-	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation) { }
+	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { }
 	virtual bool passedFilter(S32 filter_generation = -1) { return true; }
 
 	// The action callbacks
@@ -142,6 +142,8 @@ public:
 	void 				setEmptyLookupMessage(const std::string& message) { }
 	std::string			getEmptyLookupMessage() const { return mEmpty; }
 	bool				showAllResults() const { return true; }
+	std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const { return std::string::npos; }
+	std::string::size_type getFilterStringSize() const { return 0; }
 		
 	bool 				isActive() const { return false; }
 	bool 				isModified() const { return false; }
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index b4be927b09..4f4030550f 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -95,9 +95,9 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
 		return passed_clipboard;
 	}
 
-	std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : 0;
+	std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos;
 
-	BOOL passed = string_offset !=  std::string::npos;
+	BOOL passed = (mFilterSubString.size() == 0 || string_offset != std::string::npos);
 	passed = passed && checkAgainstFilterType(listener);
 	passed = passed && checkAgainstPermissions(listener);
 	passed = passed && checkAgainstFilterLinks(listener);
@@ -108,7 +108,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
 
 bool LLInventoryFilter::check(const LLInventoryItem* item)
 {
-	std::string::size_type string_offset = mFilterSubString.size() ?   item->getName().find(mFilterSubString) : std::string::npos;
+	std::string::size_type string_offset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
 
 	const bool passed_filtertype = checkAgainstFilterType(item);
 	const bool passed_permissions = checkAgainstPermissions(item);
@@ -116,7 +116,7 @@ bool LLInventoryFilter::check(const LLInventoryItem* item)
 	const bool passed = (passed_filtertype 
 		&& passed_permissions
 		&& passed_clipboard 
-		&&	(mFilterSubString.size() == 0 || string_offset !=  std::string::npos));
+		&&	(mFilterSubString.size() == 0 || string_offset != std::string::npos));
 
 	return passed;
 }
@@ -383,9 +383,10 @@ const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
 	return mFilterSubString;
 }
 
-std::string::size_type   LLInventoryFilter::getStringMatchOffset(LLFolderViewItem* item) const
+std::string::size_type LLInventoryFilter::getStringMatchOffset(LLFolderViewModelItem* item) const
 {
-	return mFilterSubString.size() ? item->getName().find(mFilterSubString)   : std::string::npos;
+	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item);
+	return mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos;
 }
 
 bool LLInventoryFilter::isDefault() const
@@ -1004,6 +1005,11 @@ bool LLInventoryFilter::hasFilterString() const
 	return mFilterSubString.size() > 0;
 }
 
+std::string::size_type LLInventoryFilter::getFilterStringSize() const
+{
+	return mFilterSubString.size();
+}
+
 PermissionMask LLInventoryFilter::getFilterPermissions() const
 {
 	return mFilterOps.mPermissions;
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index af245a9c3b..a8d39735f3 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -193,10 +193,8 @@ public:
 
 	bool				showAllResults() const;
 
-
-	std::string::size_type getStringMatchOffset() const;
-
-	std::string::size_type getStringMatchOffset(LLFolderViewItem* item)   const;
+	std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const;
+	std::string::size_type getFilterStringSize() const;
 	// +-------------------------------------------------------------------+
 	// + Presentation
 	// +-------------------------------------------------------------------+
-- 
cgit v1.2.3


From a204059d2e69fb33cb1a3c8d2fbed35d3967297c Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 1 Aug 2012 01:14:27 -0700
Subject: CHUI-267 FIX Full inventory listing not always shown for test account
 changed LLFolderViewModelInterface::getFilter() to return a reference, since
 it is never NULL removed sort order from filter, which was causing unneeded
 filtering

---
 indra/llui/llfolderview.cpp                        | 12 ++--
 indra/llui/llfolderview.h                          |  2 +-
 indra/llui/llfolderviewitem.cpp                    | 68 +++++++-----------
 indra/llui/llfolderviewitem.h                      | 20 +++---
 indra/llui/llfolderviewmodel.cpp                   |  8 +--
 indra/llui/llfolderviewmodel.h                     | 82 ++++++++++++++++------
 indra/newview/llfloateroutbox.cpp                  |  2 +-
 indra/newview/llfolderviewmodelinventory.cpp       | 40 ++++-------
 indra/newview/llfolderviewmodelinventory.h         | 36 ++++++----
 indra/newview/llinventorybridge.cpp                |  2 +-
 indra/newview/llinventoryfilter.cpp                | 17 -----
 indra/newview/llinventoryfilter.h                  | 25 +++----
 indra/newview/llinventorypanel.cpp                 | 53 +++++++-------
 indra/newview/llinventorypanel.h                   | 10 ++-
 indra/newview/llpanellandmarks.cpp                 | 24 ++-----
 indra/newview/llpanelmaininventory.cpp             | 76 ++++++++++----------
 indra/newview/llpanelmarketplaceinbox.cpp          |  4 +-
 indra/newview/llpanelmarketplaceinboxinventory.cpp |  6 +-
 indra/newview/llpanelmarketplaceinboxinventory.h   |  2 +-
 indra/newview/llpanelobjectinventory.cpp           |  7 +-
 indra/newview/lltexturectrl.cpp                    | 10 +--
 21 files changed, 239 insertions(+), 267 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index e09026fc33..d714d4623d 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -274,7 +274,7 @@ BOOL LLFolderView::canFocusChildren() const
 	return FALSE;
 }
 
-BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
+void LLFolderView::addFolder( LLFolderViewFolder* folder)
 {
 	LLFolderViewFolder::addFolder(folder);
 
@@ -288,8 +288,6 @@ BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
 	//{
 	//	mFolders.insert(mFolders.begin(), folder);
 	//}
-
-	return TRUE;
 }
 
 void LLFolderView::closeAllFolders()
@@ -1769,14 +1767,14 @@ void LLFolderView::update()
 	// until that inventory is loaded up.
 	LLFastTimer t2(FTM_INVENTORY);
 
-	if (getFolderViewModel()->getFilter()->isModified() && getFolderViewModel()->getFilter()->isNotDefault())
+	if (getFolderViewModel()->getFilter().isModified() && getFolderViewModel()->getFilter().isNotDefault())
 	{
 		mNeedsAutoSelect = TRUE;
 	}
-	getFolderViewModel()->getFilter()->clearModified();
+	getFolderViewModel()->getFilter().clearModified();
 
 	// filter to determine visibility before arranging
-	filter(*(getFolderViewModel()->getFilter()));
+	filter(getFolderViewModel()->getFilter());
 
 	// automatically show matching items, and select first one if we had a selection
 	if (mNeedsAutoSelect)
@@ -1794,7 +1792,7 @@ void LLFolderView::update()
 
 		// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
 		// Used by LLPlacesFolderView.
-		if (getFolderViewModel()->getFilter()->showAllResults())
+		if (getFolderViewModel()->getFilter().showAllResults())
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 5ebd8f73ac..05beff9bd8 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -121,7 +121,7 @@ public:
 	void closeAllFolders();
 	void openTopLevelFolders();
 
-	virtual BOOL addFolder( LLFolderViewFolder* folder);
+	virtual void addFolder( LLFolderViewFolder* folder);
 
 	// Find width and height of this object and its children. Also
 	// makes sure that this view and its children are the right size.
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 0f486d06c9..167c8123a1 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -221,11 +221,11 @@ void LLFolderViewItem::refresh()
 	mIconOpen = vmi.getIconOpen();
 	mIconOverlay = vmi.getIconOverlay();
 
-		if (mRoot->useLabelSuffix())
-		{
+	if (mRoot->useLabelSuffix())
+	{
 		mLabelStyle = vmi.getLabelStyle();
 		mLabelSuffix = vmi.getLabelSuffix();
-}
+	}
 
 	//TODO RN: make sure this logic still fires
 	//std::string searchable_label(mLabel);
@@ -255,7 +255,7 @@ void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
 	LLFolderView* root = getRoot();
 	if (getParentFolder())
 	{
-	getParentFolder()->requestArrange();
+		getParentFolder()->requestArrange();
 	}
 	if(set_selection)
 	{
@@ -275,9 +275,9 @@ std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const
 }
 
 // addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
+void LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 {
-	return folder->addItem(this);
+	folder->addItem(this);
 }
 
 
@@ -418,12 +418,12 @@ void LLFolderViewItem::rename(const std::string& new_name)
 	{
 		getViewModelItem()->renameItem(new_name);
 
-			if(mParentFolder)
-			{
-				mParentFolder->requestSort();
-			}
-		}
+		//if(mParentFolder)
+		//{
+		//	mParentFolder->requestSort();
+		//}
 	}
+}
 
 const std::string& LLFolderViewItem::getName( void ) const
 {
@@ -839,9 +839,9 @@ LLFolderViewFolder::~LLFolderViewFolder( void )
 }
 
 // addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
+void LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
 {
-	return folder->addFolder(this);
+	folder->addFolder(this);
 }
 
 static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
@@ -1008,11 +1008,6 @@ BOOL LLFolderViewFolder::needsArrange()
 	return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); 
 }
 
-void LLFolderViewFolder::requestSort()
-{
-	getViewModelItem()->requestSort();
-}
-
 //TODO RN: get height resetting working
 //void LLFolderViewFolder::setPassedFilter(BOOL passed, BOOL passed_folder, S32 filter_generation)
 //{
@@ -1417,7 +1412,6 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
 	}
 	//item has been removed, need to update filter
 	getViewModelItem()->removeChild(item->getViewModelItem());
-	getViewModelItem()->dirtyFilter();
 	//because an item is going away regardless of filter status, force rearrange
 	requestArrange();
 	removeChild(item);
@@ -1483,7 +1477,7 @@ BOOL LLFolderViewFolder::isRemovable()
 }
 
 // this is an internal method used for adding items to folders. 
-BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
+void LLFolderViewFolder::addItem(LLFolderViewItem* item)
 {
 	if (item->getParentFolder())
 	{
@@ -1496,7 +1490,6 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
 	item->setVisible(FALSE);
 	
-	addChild(item);
 
 	// TODO RN - port creation date management to new code location
 #if 0
@@ -1504,10 +1497,7 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
 #endif
 
-	// Handle sorting
-	requestArrange();
-	requestSort();
-
+	addChild(item);
 	getViewModelItem()->addChild(item->getViewModelItem());
 	// TODO RN - port creation date management to new code location
 #if 0
@@ -1533,14 +1523,10 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
 
 	//	parentp = parentp->getParentFolder();
 	//}
-
-	item->getViewModelItem()->dirtyFilter();
-
-	return TRUE;
 }
 
 // this is an internal method used for adding items to folders. 
-BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
+void LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 {
 	if (folder->mParentFolder)
 	{
@@ -1551,30 +1537,26 @@ BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 	folder->setOrigin(0, 0);
 	folder->reshape(getRect().getWidth(), 0);
 	folder->setVisible(FALSE);
-	addChild( folder );
 	// rearrange all descendants too, as our indentation level might have changed
-	folder->requestArrange();
-	requestSort();
+	//folder->requestArrange();
+	//requestSort();
 
+	addChild( folder );
 	getViewModelItem()->addChild(folder->getViewModelItem());
-  //After addChild since addChild assigns parent to bubble up to when calling dirtyFilter
-	folder->getViewModelItem()->dirtyFilter();
-
-	return TRUE;
 }
 
 void LLFolderViewFolder::requestArrange()
 { 
 	//if ( mLastArrangeGeneration != -1)
 	{
-	mLastArrangeGeneration = -1; 
-	// flag all items up to root
-	if (mParentFolder)
-	{
-		mParentFolder->requestArrange();
-	}
+		mLastArrangeGeneration = -1; 
+		// flag all items up to root
+		if (mParentFolder)
+		{
+			mParentFolder->requestArrange();
 		}
 	}
+}
 
 void LLFolderViewFolder::toggleOpen()
 {
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index df007dd15d..baa12b38f3 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -116,8 +116,8 @@ protected:
 
 	// this is an internal method used for adding items to folders. A
 	// no-op at this level, but reimplemented in derived classes.
-	virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
-	virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
+	virtual void addItem(LLFolderViewItem*) { }
+	virtual void addFolder(LLFolderViewFolder*) { }
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
@@ -131,7 +131,7 @@ public:
 	virtual ~LLFolderViewItem( void );
 
 	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-	virtual BOOL addToFolder(LLFolderViewFolder* folder);
+	virtual void addToFolder(LLFolderViewFolder* folder);
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
@@ -297,7 +297,7 @@ public:
 	LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE  );
 
 	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-	virtual BOOL addToFolder(LLFolderViewFolder* folder);
+	virtual void addToFolder(LLFolderViewFolder* folder);
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
@@ -356,8 +356,6 @@ public:
 	// Called when a child is refreshed.
 	virtual void requestArrange();
 
-	virtual void requestSort();
-
 	// internal method which doesn't update the entire view. This
 	// method was written because the list iterators destroy the state
 	// of other iterations, thus, we can't arrange while iterating
@@ -381,8 +379,6 @@ public:
 	void applyFunctorToChildren(LLFolderViewFunctor& functor);
 
 	virtual void openItem( void );
-	virtual BOOL addItem(LLFolderViewItem* item);
-	virtual BOOL addFolder( LLFolderViewFolder* folder);
 
 	// LLView functionality
 	virtual BOOL handleHover(S32 x, S32 y, MASK mask);
@@ -412,6 +408,14 @@ public:
 	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
 	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);
 
+protected:
+	friend void LLFolderViewItem::addToFolder(LLFolderViewFolder*);
+	// internal functions for tracking folders and items separately
+	// use addToFolder() virtual method to ensure folders are always added to mFolders
+	// and not mItems
+	void addItem(LLFolderViewItem* item);
+	void addFolder( LLFolderViewFolder* folder);
+
 public:
 	//WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
 	template<typename SORT_FUNC> void sortFolders(const SORT_FUNC& func) { mFolders.sort(func); }
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index dc6e4d754b..6aa4a63edc 100644
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -36,18 +36,18 @@ bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
 
 std::string LLFolderViewModelCommon::getStatusText()
 {
-	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter()->getCurrentGeneration())
+	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter().getCurrentGeneration())
 	{
 		return LLTrans::getString("Searching");
 	}
 	else
 	{
-		return getFilter()->getEmptyLookupMessage();
+		return getFilter().getEmptyLookupMessage();
 	}
 }
 
 void LLFolderViewModelCommon::filter()
 {
-	getFilter()->setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
-	mFolderView->getViewModelItem()->filter(*getFilter());
+	getFilter().setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
+	mFolderView->getViewModelItem()->filter(getFilter());
 }
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index acdec53602..81de15923a 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -107,6 +107,24 @@ public:
 	virtual S32 				getFirstRequiredGeneration() const = 0;
 };
 
+class LLFolderViewModelInterface
+{
+public:
+	virtual ~LLFolderViewModelInterface() {}
+	virtual void requestSortAll() = 0;
+
+	virtual void sort(class LLFolderViewFolder*) = 0;
+	virtual void filter() = 0;
+
+	virtual bool contentsReady() = 0;
+	virtual void setFolderView(LLFolderView* folder_view) = 0;
+	virtual LLFolderViewFilter& getFilter() = 0;
+	virtual const LLFolderViewFilter& getFilter() const = 0;
+	virtual std::string getStatusText() = 0;
+
+	virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
+};
+
 // This is am abstract base class that users of the folderview classes
 // would use to bridge the folder view with the underlying data
 class LLFolderViewModelItem
@@ -188,15 +206,15 @@ protected:
 class LLFolderViewModelItemCommon : public LLFolderViewModelItem
 {
 public:
-	LLFolderViewModelItemCommon()
+	LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model)
 	:	mSortVersion(-1),
 		mPassedFilter(true),
 		mPassedFolderFilter(true),
-		mPrevPassedAllFilters(false),
 		mFolderViewItem(NULL),
 		mLastFilterGeneration(-1),
 		mMostFilteredDescendantGeneration(-1),
-		mParent(NULL)
+		mParent(NULL),
+		mRootViewModel(root_view_model)
 	{
 		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
 	}
@@ -220,20 +238,55 @@ public:
 	{ 
 		mChildren.push_back(child); 
 		child->setParent(this); 
+		dirtyFilter();
+		requestSort();
 	}
 	virtual void removeChild(LLFolderViewModelItem* child) 
 	{ 
 		mChildren.remove(child); 
 		child->setParent(NULL); 
+		dirtyFilter();
+	}
+
+	void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation)
+	{
+		mPassedFilter = passed;
+		mPassedFolderFilter = passed_folder;
+		mLastFilterGeneration = filter_generation;
+	}
+
+	virtual bool potentiallyVisible()
+	{
+		return passedFilter() // we've passed the filter
+			|| getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration() // or we don't know yet
+			|| descendantsPassedFilter();
 	}
 
+	virtual bool passedFilter(S32 filter_generation = -1) 
+	{ 
+		if (filter_generation < 0) 
+			filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
+
+		bool passed_folder_filter = mPassedFolderFilter && mLastFilterGeneration >= filter_generation;
+		bool passed_filter = mPassedFilter && mLastFilterGeneration >= filter_generation;
+		return passed_folder_filter
+				&& (descendantsPassedFilter(filter_generation)
+					|| passed_filter);
+	}
+
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1)
+	{ 
+		if (filter_generation < 0) filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
+		return mMostFilteredDescendantGeneration >= filter_generation; 
+	}
+
+
 protected:
 	virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
 
 	S32						mSortVersion;
 	bool					mPassedFilter;
 	bool					mPassedFolderFilter;
-	bool					mPrevPassedAllFilters;
 
 	S32						mLastFilterGeneration;
 	S32						mMostFilteredDescendantGeneration;
@@ -242,28 +295,13 @@ protected:
 	typedef std::list<LLFolderViewModelItem*> child_list_t;
 	child_list_t			mChildren;
 	LLFolderViewModelItem*	mParent;
+	LLFolderViewModelInterface& mRootViewModel;
 
 	void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
 	LLFolderViewItem*		mFolderViewItem;
 };
 
-class LLFolderViewModelInterface
-{
-public:
-	virtual ~LLFolderViewModelInterface() {}
-	virtual void requestSortAll() = 0;
-
-	virtual void sort(class LLFolderViewFolder*) = 0;
-	virtual void filter() = 0;
-
-	virtual bool contentsReady() = 0;
-	virtual void setFolderView(LLFolderView* folder_view) = 0;
-	virtual LLFolderViewFilter* getFilter() = 0;
-	virtual const LLFolderViewFilter* getFilter() const = 0;
-	virtual std::string getStatusText() = 0;
 
-	virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
-};
 
 class LLFolderViewModelCommon : public LLFolderViewModelInterface
 {
@@ -307,8 +345,8 @@ public:
 	virtual const SortType& getSorter() const 		 { return mSorter; }
 	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
 
-	virtual FilterType* getFilter() 				 { return &mFilter; }
-	virtual const FilterType* getFilter() const		 { return &mFilter; }
+	virtual FilterType& getFilter() 				 { return mFilter; }
+	virtual const FilterType& getFilter() const		 { return mFilter; }
 	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
 
 	// TODO RN: remove this and put all filtering logic in view model
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index e4ed97892e..18ed36d0f3 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -251,7 +251,7 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
 	// Set the sort order newest to oldest
 
 	mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
-	mOutboxInventoryPanel->getFilter()->markDefault();
+	mOutboxInventoryPanel->getFilter().markDefault();
 	
 	fetchOutboxContents();
 	
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 13ca73917b..21218850a6 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -109,7 +109,12 @@ bool LLFolderViewModelInventory::contentsReady()
 void LLFolderViewModelItemInventory::requestSort()
 {
 	LLFolderViewModelItemCommon::requestSort();
-	if (mRootViewModel.getSorter().isByDate())
+	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(mFolderViewItem);
+	if (folderp)
+	{
+		folderp->requestArrange();
+	}
+	if (static_cast<LLFolderViewModelInventory&>(mRootViewModel).getSorter().isByDate())
 	{
 		// sort by date potentially affects parent folders which use a date
 		// derived from newest item in them
@@ -120,35 +125,9 @@ void LLFolderViewModelItemInventory::requestSort()
 	}
 }
 
-bool LLFolderViewModelItemInventory::potentiallyVisible()
-{
-	return passedFilter() // we've passed the filter
-		|| getLastFilterGeneration() < mRootViewModel.getFilter()->getFirstSuccessGeneration() // or we don't know yet
-		|| descendantsPassedFilter();
-}
-
-bool LLFolderViewModelItemInventory::passedFilter(S32 filter_generation) 
-{ 
-	if (filter_generation < 0) 
-		filter_generation = mRootViewModel.getFilter()->getFirstSuccessGeneration();
-
-	return mPassedFolderFilter 
-		&& (descendantsPassedFilter(filter_generation)
-			|| (mLastFilterGeneration >= filter_generation 
-				&& mPassedFilter));
-}
-
-bool LLFolderViewModelItemInventory::descendantsPassedFilter(S32 filter_generation)
-{ 
-	if (filter_generation < 0) filter_generation = mRootViewModel.getFilter()->getFirstSuccessGeneration();
-	return mMostFilteredDescendantGeneration >= filter_generation; 
-}
-
 void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation)
 {
-	mPassedFilter = passed;
-	mPassedFolderFilter = passed_folder;
-	mLastFilterGeneration = filter_generation;
+	LLFolderViewModelItemCommon::setPassedFilter(passed, passed_folder, filter_generation);
 
 	bool passed_filter_before = mPrevPassedAllFilters;
 	mPrevPassedAllFilters = passedFilter(filter_generation);
@@ -324,3 +303,8 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a,
 	}
 }
 
+LLFolderViewModelItemInventory::LLFolderViewModelItemInventory( class LLFolderViewModelInventory& root_view_model ) 
+	:	LLFolderViewModelItemCommon(root_view_model),
+	mPrevPassedAllFilters(false)
+{
+}
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index ab67c93897..5b0ad5e46e 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -37,9 +37,7 @@ class LLFolderViewModelItemInventory
 	:	public LLFolderViewModelItemCommon
 {
 public:
-	LLFolderViewModelItemInventory(class LLFolderViewModelInventory& root_view_model)
-	:	mRootViewModel(root_view_model)
-	{}
+	LLFolderViewModelItemInventory(class LLFolderViewModelInventory& root_view_model);
 	virtual const LLUUID& getUUID() const = 0;
 	virtual time_t getCreationDate() const = 0;	// UTC seconds
 	virtual void setCreationDate(time_t creation_date_utc) = 0;
@@ -55,9 +53,6 @@ public:
 	virtual EInventorySortGroup getSortGroup() const = 0;
 	virtual LLInventoryObject* getInventoryObject() const = 0;
 	virtual void requestSort();
-	virtual bool potentiallyVisible();
-	virtual bool passedFilter(S32 filter_generation = -1);
-	virtual bool descendantsPassedFilter(S32 filter_generation = -1);
 	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation);
 	virtual void filter( LLFolderViewFilter& filter);
 	virtual void filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
@@ -66,25 +61,36 @@ public:
 	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
 
 protected:
-	class LLFolderViewModelInventory& mRootViewModel;
+	bool								mPrevPassedAllFilters;
 };
 
 class LLInventorySort
 {
 public:
-	LLInventorySort(U32 order = 0)
-		:	mSortOrder(order),
-		mByDate(false),
-		mSystemToTop(false),
-		mFoldersByName(false)
+	struct Params : public LLInitParam::Block<Params>
 	{
-		mByDate = (order & LLInventoryFilter::SO_DATE);
-		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
-		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+		Optional<S32> order;
+
+		Params()
+		:	order("order", 0)
+		{}
+	};
+
+	LLInventorySort(S32 order = 0)
+	{
+		fromParams(Params().order(order));
 	}
 
 	bool isByDate() const { return mByDate; }
 	U32 getSortOrder() const { return mSortOrder; }
+	void toParams(Params& p) { p.order(mSortOrder);}
+	void fromParams(Params& p) 
+	{ 
+		mSortOrder = p.order; 
+		mByDate = (mSortOrder & LLInventoryFilter::SO_DATE);
+		mSystemToTop = (mSortOrder & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+		mFoldersByName = (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+	}
 
 	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
 private:
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 14616ca7ab..43c4ce1278 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -900,7 +900,7 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const
 LLInventoryFilter* LLInvFVBridge::getInventoryFilter() const
 {
 	LLInventoryPanel* panel = mInventoryPanel.get();
-	return panel ? panel->getFilter() : NULL;
+	return panel ? &(panel->getFilter()) : NULL;
 }
 
 BOOL LLInvFVBridge::isItemInTrash() const
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index b4be927b09..7993dd04c5 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -69,7 +69,6 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
 	mFilterModified(FILTER_NONE),
 	mEmptyLookupMessage("InventoryNoMatchingItems"),
     mFilterOps(p.filter_ops),
-	mOrder(p.sort_order),
 	mFilterSubString(p.substring),
 	mCurrentGeneration(0),
 	mFirstRequiredGeneration(0),
@@ -703,15 +702,6 @@ void LLInventoryFilter::setShowFolderState(EFolderShow state)
 	}
 }
 
-void LLInventoryFilter::setSortOrder(U32 order)
-{
-	if (mOrder != order)
-	{
-		mOrder = order;
-		setModified();
-	}
-}
-
 void LLInventoryFilter::markDefault()
 {
 	mDefaultFilterOps = mFilterOps;
@@ -944,7 +934,6 @@ LLInventoryFilter& LLInventoryFilter::operator=( const  LLInventoryFilter&  othe
 	setShowFolderState(other.getShowFolderState());
 	setFilterPermissions(other.getFilterPermissions());
 	setFilterSubString(other.getFilterSubString());
-	setSortOrder(other.getSortOrder());
 	setDateRangeLastLogoff(other.isSinceLogoff());
 	return *this;
 }
@@ -961,7 +950,6 @@ void LLInventoryFilter::toParams(Params& params) const
 	params.filter_ops.show_folder_state = getShowFolderState();
 	params.filter_ops.permissions = getFilterPermissions();
 	params.substring = getFilterSubString();
-	params.sort_order = getSortOrder();
 	params.since_logoff = isSinceLogoff();
 }
 
@@ -980,7 +968,6 @@ void LLInventoryFilter::fromParams(const Params& params)
 	setShowFolderState(params.filter_ops.show_folder_state);
 	setFilterPermissions(params.filter_ops.permissions);
 	setFilterSubString(params.substring);
-	setSortOrder(params.sort_order);
 	setDateRangeLastLogoff(params.since_logoff);
 }
 
@@ -1030,10 +1017,6 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
 { 
 	return mFilterOps.mShowFolderState; 
 }
-U32 LLInventoryFilter::getSortOrder() const 
-{ 
-	return mOrder; 
-}
 
 void LLInventoryFilter::setFilterCount(S32 count) 
 { 
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index af245a9c3b..b560730873 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -74,8 +74,8 @@ public:
 	{
 		struct DateRange : public LLInitParam::Block<DateRange>
 		{
-			Optional<time_t> min_date;
-			Optional<time_t> max_date;
+			Optional<time_t>	min_date,
+								max_date;
 
 			DateRange()
 			:	min_date("min_date", time_min()),
@@ -115,18 +115,18 @@ public:
 		FilterOps(const Params& = Params());
 
 		U32 			mFilterTypes;
-
-		U64				mFilterObjectTypes;   // For _OBJECT
-		U64				mFilterWearableTypes;
-		U64				mFilterCategoryTypes; // For _CATEGORY
+		U64				mFilterObjectTypes,   // For _OBJECT
+						mFilterWearableTypes,
+						mFilterLinks,
+						mFilterCategoryTypes; // For _CATEGORY
 		LLUUID      	mFilterUUID; 		  // for UUID
 
-		time_t			mMinDate;
-		time_t			mMaxDate;
+		time_t			mMinDate,
+						mMaxDate;
 		U32				mHoursAgo;
+
 		EFolderShow		mShowFolderState;
 		PermissionMask	mPermissions;
-		U64				mFilterLinks;
 	};
 							
 	struct Params : public LLInitParam::Block<Params>
@@ -134,14 +134,12 @@ public:
 		Optional<std::string>		name;
 		Optional<FilterOps::Params>	filter_ops;
 		Optional<std::string>		substring;
-		Optional<U32>				sort_order;
 		Optional<bool>				since_logoff;
 
 		Params()
 		:	name("name"),
 			filter_ops(""),
 			substring("substring"),
-			sort_order("sort_order"),
 			since_logoff("since_logoff")
 		{}
 	};
@@ -203,9 +201,6 @@ public:
 	void 				setShowFolderState( EFolderShow state);
 	EFolderShow 		getShowFolderState() const;
 
-	void 				setSortOrder(U32 order);
-	U32 				getSortOrder() const;
-
 	void 				setEmptyLookupMessage(const std::string& message);
 	std::string			getEmptyLookupMessage() const;
 
@@ -261,8 +256,6 @@ private:
 	bool 				checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;
 	bool				checkAgainstClipboard(const LLUUID& object_id) const;
 
-	U32						mOrder;
-
 	FilterOps				mFilterOps;
 	FilterOps				mDefaultFilterOps;
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index e9b128e836..1b3391f7ee 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -239,13 +239,13 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	}
 
 	// hide inbox
-	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
-	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
+	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
 
 	// set the filter for the empty folder if the debug setting is on
 	if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders"))
 	{
-		getFilter()->setFilterEmptySystemFolders();
+		getFilter().setFilterEmptySystemFolders();
 	}
 	
 	// keep track of the clipboard state so that we avoid filtering too much
@@ -285,18 +285,18 @@ void LLInventoryPanel::draw()
 	if (mClipboardState != LLClipboard::instance().getGeneration())
 	{
 		mClipboardState = LLClipboard::instance().getGeneration();
-		getFilter()->setModified(LLClipboard::instance().isCutMode() ? LLInventoryFilter::FILTER_MORE_RESTRICTIVE : LLInventoryFilter::FILTER_LESS_RESTRICTIVE);
+		getFilter().setModified(LLClipboard::instance().isCutMode() ? LLInventoryFilter::FILTER_MORE_RESTRICTIVE : LLInventoryFilter::FILTER_LESS_RESTRICTIVE);
 	}
 	
 	LLPanel::draw();
 }
 
-const LLInventoryFilter* LLInventoryPanel::getFilter() const
+const LLInventoryFilter& LLInventoryPanel::getFilter() const
 {
 	return getFolderViewModel()->getFilter();
 }
 
-LLInventoryFilter* LLInventoryPanel::getFilter()
+LLInventoryFilter& LLInventoryPanel::getFilter()
 {
 	return getFolderViewModel()->getFilter();
 }
@@ -304,50 +304,49 @@ LLInventoryFilter* LLInventoryPanel::getFilter()
 void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
 {
 	if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
-		getFilter()->setFilterObjectTypes(types);
+		getFilter().setFilterObjectTypes(types);
 	if (filter_type == LLInventoryFilter::FILTERTYPE_CATEGORY)
-		getFilter()->setFilterCategoryTypes(types);
+		getFilter().setFilterCategoryTypes(types);
 }
 
 U32 LLInventoryPanel::getFilterObjectTypes() const 
 { 
-	return getFilter()->getFilterObjectTypes();
+	return getFilter().getFilterObjectTypes();
 }
 
 U32 LLInventoryPanel::getFilterPermMask() const 
 { 
-	return getFilter()->getFilterPermissions();
+	return getFilter().getFilterPermissions();
 }
 
 
 void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
 {
-	getFilter()->setFilterPermissions(filter_perm_mask);
+	getFilter().setFilterPermissions(filter_perm_mask);
 }
 
 void LLInventoryPanel::setFilterWearableTypes(U64 types)
 {
-	getFilter()->setFilterWearableTypes(types);
+	getFilter().setFilterWearableTypes(types);
 }
 
 void LLInventoryPanel::setFilterSubString(const std::string& string)
 {
-	getFilter()->setFilterSubString(string);
+	getFilter().setFilterSubString(string);
 }
 
 const std::string LLInventoryPanel::getFilterSubString() 
 { 
-	return getFilter()->getFilterSubString();
+	return getFilter().getFilterSubString();
 }
 
 
 void LLInventoryPanel::setSortOrder(U32 order)
 {
-        LLInventorySort sorter(order);
-	getFilter()->setSortOrder(order);
+    LLInventorySort sorter(order);
 	if (order != getFolderViewModel()->getSorter().getSortOrder())
 	{
-		getFolderViewModel()->setSorter(LLInventorySort(order));
+		getFolderViewModel()->setSorter(sorter);
 		// try to keep selection onscreen, even if it wasn't to start with
 		mFolderRoot->scrollToShowSelection();
 	}
@@ -360,27 +359,27 @@ U32 LLInventoryPanel::getSortOrder() const
 
 void LLInventoryPanel::setSinceLogoff(BOOL sl)
 {
-	getFilter()->setDateRangeLastLogoff(sl);
+	getFilter().setDateRangeLastLogoff(sl);
 }
 
 void LLInventoryPanel::setHoursAgo(U32 hours)
 {
-	getFilter()->setHoursAgo(hours);
+	getFilter().setHoursAgo(hours);
 }
 
 void LLInventoryPanel::setFilterLinks(U64 filter_links)
 {
-	getFilter()->setFilterLinks(filter_links);
+	getFilter().setFilterLinks(filter_links);
 }
 
 void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
 {
-	getFilter()->setShowFolderState(show);
+	getFilter().setShowFolderState(show);
 }
 
 LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
 {
-	return getFilter()->getShowFolderState();
+	return getFilter().getShowFolderState();
 }
 
 void LLInventoryPanel::modelChanged(U32 mask)
@@ -473,7 +472,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 		{
 			if (view_folder)
 			{
-				view_folder->requestSort();
+				view_folder->getViewModelItem()->requestSort();
 			}
 		}	
 
@@ -1088,7 +1087,7 @@ bool LLInventoryPanel::attachObject(const LLSD& userdata)
 
 BOOL LLInventoryPanel::getSinceLogoff()
 {
-	return getFilter()->isSinceLogoff();
+	return getFilter().isSinceLogoff();
 }
 
 // DEBUG ONLY
@@ -1214,12 +1213,12 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
 
 void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)
 {
-	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));
+	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << folder_type));
 }
 
 BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const
 {
-	return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
+	return !(getFilter().getFilterCategoryTypes() & (1ULL << folder_type));
 }
 
 void LLInventoryPanel::addItemID( const LLUUID& id, LLFolderViewItem*   itemp )
@@ -1321,7 +1320,7 @@ public:
 	{
 		LLInventoryPanel::initFromParams(p);
 		// turn on inbox for recent items
-		getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
+		getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
 	}
 
 protected:
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index b66b53f642..e9bfcb0ccf 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -120,6 +120,12 @@ public:
 		{}
 	};
 
+	struct InventoryState : public LLInitParam::Block<InventoryState>
+	{
+		Mandatory<LLInventoryFilter::Params> filter;
+		Mandatory<LLInventorySort::Params> sort;
+	};
+
 	//--------------------------------------------------------------------
 	// Initialization
 	//--------------------------------------------------------------------
@@ -155,8 +161,8 @@ public:
 	void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
 	void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
 	void clearSelection();
-	LLInventoryFilter* getFilter();
-	const LLInventoryFilter* getFilter() const;
+	LLInventoryFilter& getFilter();
+	const LLInventoryFilter& getFilter() const;
 	void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
 	U32 getFilterObjectTypes() const;
 	void setFilterPermMask(PermissionMask filter_perm_mask);
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 1a4f3708ac..9225ea3d53 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -247,10 +247,7 @@ void LLLandmarksPanel::onSearchEdit(const std::string& string)
 		LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView());
 		if (NULL == inventory_list) continue;
 
-		if (inventory_list->getFilter())
-		{
-			filter_list(inventory_list, string);
-		}
+		filter_list(inventory_list, string);
 	}
 
 	if (sFilterSubString != string)
@@ -365,9 +362,6 @@ void LLLandmarksPanel::onSelectorButtonClicked()
 
 void LLLandmarksPanel::updateShowFolderState()
 {
-	if (!mLandmarksInventoryPanel->getFilter())
-		return;
-
 	bool show_all_folders =   mLandmarksInventoryPanel->getFilterSubString().empty();
 	if (show_all_folders)
 	{
@@ -547,7 +541,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel()
 	mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list");
 
 	initLandmarksPanel(mFavoritesInventoryPanel);
-	mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems");
+	mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
 
 	initAccordion("tab_favorites", mFavoritesInventoryPanel, true);
 }
@@ -558,12 +552,7 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
 
 	initLandmarksPanel(mLandmarksInventoryPanel);
 
-	// Check if mLandmarksInventoryPanel is properly initialized and has a Filter created.
-	// In case of a dummy widget getFilter() will return NULL.
-	if (mLandmarksInventoryPanel->getFilter())
-	{
-		mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
-	}
+	mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
 
 	// subscribe to have auto-rename functionality while creating New Folder
 	mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2));
@@ -599,12 +588,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
 
 void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list)
 {
-	// In case of a dummy widget further we have no Folder View widget and no Filter,
-	// so further initialization leads to crash.
-	if (!inventory_list->getFilter())
-		return;
-
-	inventory_list->getFilter()->setEmptyLookupMessage("PlacesNoMatchingItems");
+	inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems");
 	inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
 	inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
 
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index fea27b37d3..e1aa70cc4a 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -89,9 +89,9 @@ public:
 	static void selectNoTypes(void* user_data);
 private:
 	LLPanelMainInventory*	mPanelMainInventory;
-	LLSpinCtrl*			mSpinSinceDays;
-	LLSpinCtrl*			mSpinSinceHours;
-	LLInventoryFilter*	mFilter;
+	LLSpinCtrl*				mSpinSinceDays;
+	LLSpinCtrl*				mSpinSinceHours;
+	LLInventoryFilter*		mFilter;
 };
 
 ///----------------------------------------------------------------------------
@@ -131,7 +131,7 @@ BOOL LLPanelMainInventory::postBuild()
 	mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
 	mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
 	
-	//panel->getFilter()->markDefault();
+	//panel->getFilter().markDefault();
 
 	// Set up the default inv. panel/filter settings.
 	mActivePanel = getChild<LLInventoryPanel>("All Items");
@@ -139,7 +139,7 @@ BOOL LLPanelMainInventory::postBuild()
 	{
 		// "All Items" is the previous only view, so it gets the InventorySortOrder
 		mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
-		mActivePanel->getFilter()->markDefault();
+		mActivePanel->getFilter().markDefault();
 		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
 		mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
 		mResortActivePanel = true;
@@ -150,7 +150,7 @@ BOOL LLPanelMainInventory::postBuild()
 		recent_items_panel->setSinceLogoff(TRUE);
 		recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
 		recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
-		recent_items_panel->getFilter()->markDefault();
+		recent_items_panel->getFilter().markDefault();
 		recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
 	}
 
@@ -169,14 +169,14 @@ BOOL LLPanelMainInventory::postBuild()
 		// Note that the "All Items" settings do not persist.
 		if(recent_items_panel)
 		{
-			if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
+			if(savedFilterState.has(recent_items_panel->getFilter().getName()))
 			{
 				LLSD recent_items = savedFilterState.get(
-					recent_items_panel->getFilter()->getName());
+					recent_items_panel->getFilter().getName());
 				LLInventoryFilter::Params p;
 				LLParamSDParser parser;
 				parser.readSD(recent_items, p);
-				recent_items_panel->getFilter()->fromParams(p);
+				recent_items_panel->getFilter().fromParams(p);
 			}
 		}
 
@@ -213,29 +213,29 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
 	LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
 	if (all_items_panel)
 	{
-		LLInventoryFilter* filter = all_items_panel->getFilter();
-		if (filter)
+		LLSD filterState;
+		LLInventoryPanel::InventoryState p;
+		all_items_panel->getFilter().toParams(p.filter);
+		all_items_panel->getRootViewModel().getSorter().toParams(p.sort);
+		if (p.validateBlock(false))
 		{
-			LLSD filterState;
-			LLInventoryFilter::Params p;
-			filter->toParams(p);
-			if (p.validateBlock(false))
-			{
-				LLParamSDParser().writeSD(filterState, p);
-				filterRoot[filter->getName()] = filterState;
-			}
+			LLParamSDParser().writeSD(filterState, p);
+			filterRoot[all_items_panel->getName()] = filterState;
 		}
 	}
 
-	LLInventoryFilter* filter = findChild<LLInventoryPanel>("Recent Items")->getFilter();
-	if (filter)
+	LLInventoryPanel* panel = findChild<LLInventoryPanel>("Recent Items");
+	if (panel)
 	{
 		LLSD filterState;
-		LLInventoryFilter::Params p;
-		filter->toParams(p);
-		LLParamSDParser parser;
-		parser.writeSD(filterState, p);
-		filterRoot[filter->getName()] = filterState;
+		LLInventoryPanel::InventoryState p;
+		panel->getFilter().toParams(p.filter);
+		panel->getRootViewModel().getSorter().toParams(p.sort);
+		if (p.validateBlock(false))
+		{
+			LLParamSDParser().writeSD(filterState, p);
+			filterRoot[panel->getName()] = filterState;
+		}
 	}
 
 	std::ostringstream filterSaveName;
@@ -321,7 +321,7 @@ void LLPanelMainInventory::doCreate(const LLSD& userdata)
 void LLPanelMainInventory::resetFilters()
 {
 	LLFloaterInventoryFinder *finder = getFinder();
-	getActivePanel()->getFilter()->resetDefault();
+	getActivePanel()->getFilter().resetDefault();
 	if (finder)
 	{
 		finder->updateElementsFromFilter();
@@ -426,7 +426,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
 	}
 
 	// save current folder open state if no filter currently applied
-	if (!mActivePanel->getFilter()->isNotDefault())
+	if (!mActivePanel->getFilter().isNotDefault())
 	{
 		mSavedFolderState->setApply(FALSE);
 		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -488,13 +488,13 @@ void LLPanelMainInventory::onFilterSelected()
 	}
 
 	setFilterSubString(mFilterSubString);
-	LLInventoryFilter* filter = mActivePanel->getFilter();
+	LLInventoryFilter& filter = mActivePanel->getFilter();
 	LLFloaterInventoryFinder *finder = getFinder();
 	if (finder)
 	{
-		finder->changeFilter(filter);
+		finder->changeFilter(&filter);
 	}
-	if (filter->isActive())
+	if (filter.isActive())
 	{
 		// If our filter is active we may be the first thing requiring a fetch so we better start it here.
 		LLInventoryModelBackgroundFetch::instance().start();
@@ -607,7 +607,7 @@ void LLPanelMainInventory::onFocusReceived()
 
 void LLPanelMainInventory::setFilterTextFromFilter() 
 { 
-	mFilterText = mActivePanel->getFilter()->getFilterText(); 
+	mFilterText = mActivePanel->getFilter().getFilterText(); 
 }
 
 void LLPanelMainInventory::toggleFindOptions()
@@ -657,7 +657,7 @@ LLFloaterInventoryFinder* LLPanelMainInventory::getFinder()
 LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :	
 	LLFloater(LLSD()),
 	mPanelMainInventory(inventory_view),
-	mFilter(inventory_view->getPanel()->getFilter())
+	mFilter(&inventory_view->getPanel()->getFilter())
 {
 	buildFromFile("floater_inventory_view_finder.xml");
 	updateElementsFromFilter();
@@ -1082,14 +1082,14 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		const std::string &item_name = current_item->getViewModelItem()->getName();
 		mFilterSubString = item_name;
-		LLInventoryFilter *filter = mActivePanel->getFilter();
-		filter->setFilterSubString(item_name);
+		LLInventoryFilter &filter = mActivePanel->getFilter();
+		filter.setFilterSubString(item_name);
 		mFilterEditor->setText(item_name);
 
 		mFilterEditor->setFocus(TRUE);
-		filter->setFilterUUID(item_id);
-		filter->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
-		filter->setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS);
+		filter.setFilterUUID(item_id);
+		filter.setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+		filter.setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS);
 	}
 }
 
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 3547156197..ea0521e3a7 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -95,13 +95,13 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
 	
 	// Set the sort order newest to oldest
 	mInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_DATE);
-	mInventoryPanel->getFilter()->markDefault();
+	mInventoryPanel->getFilter().markDefault();
 
 	// Set selection callback for proper update of inventory status buttons
 	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
 
 	// Set up the note to display when the inbox is empty
-	mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryInboxNoItems");
+	mInventoryPanel->getFilter().setEmptyLookupMessage("InventoryInboxNoItems");
 	
 	// Hide the placeholder text
 	inbox_inventory_placeholder->setVisible(FALSE);
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 8ad3929999..0d3fbe66d7 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -182,9 +182,9 @@ LLInboxFolderViewItem::LLInboxFolderViewItem(const Params& p)
 #endif
 }
 
-BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)
+void LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 {
-	BOOL retval = LLFolderViewItem::addToFolder(folder);
+	LLFolderViewItem::addToFolder(folder);
 
 #if SUPPORTING_FRESH_ITEM_COUNT
 	// Compute freshness if our parent is the root folder for the inbox
@@ -193,8 +193,6 @@ BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 		computeFreshness();
 	}
 #endif
-	
-	return retval;
 }
 
 BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index d8b8a2fe63..098969aca6 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -95,7 +95,7 @@ public:
 
 	LLInboxFolderViewItem(const Params& p);
 
-	BOOL addToFolder(LLFolderViewFolder* folder);
+	void addToFolder(LLFolderViewFolder* folder);
 	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
 
 	void draw();
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 4f2c515bde..82956beb3d 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1567,11 +1567,8 @@ void LLPanelObjectInventory::reset()
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 	// this ensures that we never say "searching..." or "no items found"
 	//TODO RN: make this happen by manipulating filter object directly
-  	LLInventoryFilter* inventoryFilter = dynamic_cast<LLInventoryFilter*>(mFolders->getFolderViewModel()->getFilter());
-  	if(inventoryFilter)
-	{
-    	inventoryFilter->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
-  	}
+  	LLInventoryFilter& inventoryFilter = dynamic_cast<LLInventoryFilter&>(mFolders->getFolderViewModel()->getFilter());
+   	inventoryFilter.setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
   
 	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 2d3f144588..65f0290060 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -455,7 +455,7 @@ BOOL LLFloaterTexturePicker::postBuild()
 
 		// Commented out to scroll to currently selected texture. See EXT-5403.
 		// // store this filter as the default one
-		// mInventoryPanel->getRootFolder()->getFilter()->markDefault();
+		// mInventoryPanel->getRootFolder()->getFilter().markDefault();
 
 		// Commented out to stop opening all folders with textures
 		// mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE);
@@ -638,10 +638,10 @@ void LLFloaterTexturePicker::draw()
 		LLFolderView* folder_view = mInventoryPanel->getRootFolder();
 		if (!folder_view) return;
 
-		LLFolderViewFilter* filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
+		LLFolderViewFilter& filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
 
-		bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter->getCurrentGeneration() &&
-				filter->isNotDefault();
+		bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() &&
+				filter.isNotDefault();
 
 		// After inventory panel filter is applied we have to update
 		// constraint rect for the selected item because of folder view
@@ -1012,7 +1012,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
 	else if (mInventoryPanel->getFilterSubString().empty())
 	{
 		// first letter in search term, save existing folder open state
-		if (!mInventoryPanel->getFilter()->isNotDefault())
+		if (!mInventoryPanel->getFilter().isNotDefault())
 		{
 			mSavedFolderState.setApply(FALSE);
 			mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
-- 
cgit v1.2.3


From 8ccaa8b0b8e65d6022c6ad0d449cecdd8a72f81d Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 1 Aug 2012 01:48:39 -0700
Subject: build fix attempt

---
 indra/llui/llfolderviewmodel.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 3f825a8670..c4d98657e2 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -259,7 +259,7 @@ public:
 		dirtyFilter();
 	}
 
-	void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size)
+	void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
 	{
 		mPassedFilter = passed;
 		mPassedFolderFilter = passed_folder;
-- 
cgit v1.2.3


From c3bc6de8ba90216d3687f70e01e92accde956a85 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 1 Aug 2012 09:36:10 -0700
Subject: CHUI-218 FIX (Items and Item count is not show in Received Items
 folder in Inventory) forgot to check in

---
 indra/newview/skins/default/xui/en/panel_inbox_inventory.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
index 48d38d50e0..433a3181cd 100644
--- a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
@@ -2,7 +2,7 @@
 <inbox_inventory_panel
     accepts_drag_and_drop="false"
     name="inventory_inbox"
-    start_folder.name="Received Items"
+    start_folder.type="inbox"
     follows="all" layout="topleft"
     top="0" left="0" height="165" width="308"
     top_pad="0"
-- 
cgit v1.2.3


From 4256b54ee78a89dc5e790cc13556451e1a7c43fa Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 1 Aug 2012 10:45:11 -0700
Subject: build fix

---
 indra/llui/llfolderviewitem.h          | 3 ---
 indra/newview/llimfloatercontainer.cpp | 8 +++++---
 indra/newview/llimfloatercontainer.h   | 3 ++-
 3 files changed, 7 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 19caa7f020..4eda02f13f 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -406,15 +406,12 @@ public:
 	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
 	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);
 
-protected:
-	friend void LLFolderViewItem::addToFolder(LLFolderViewFolder*);
 	// internal functions for tracking folders and items separately
 	// use addToFolder() virtual method to ensure folders are always added to mFolders
 	// and not mItems
 	void addItem(LLFolderViewItem* item);
 	void addFolder( LLFolderViewFolder* folder);
 
-public:
 	//WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
 	template<typename SORT_FUNC> void sortFolders(const SORT_FUNC& func) { mFolders.sort(func); }
 	template<typename SORT_FUNC> void sortItems(const SORT_FUNC& func) { mItems.sort(func); }
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 405a2b3255..cc094fcaa1 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -100,7 +100,7 @@ BOOL LLIMFloaterContainer::postBuild()
 	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
 	// CHUI-98 : View Model for conversations
-	LLConversationItem* base_item = new LLConversationItem();
+	LLConversationItem* base_item = new LLConversationItem(this);
 	LLFolderView::Params p;
 	p.view_model = &mConversationViewModel;
 	p.parent_panel = mConversationsListPanel;
@@ -456,7 +456,7 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 	mConversationsWidgets[floaterp] = widget;
 
 	// Add a new conversation widget to the root folder of a folder view.
-	mConversationsRoot->addItem(widget);
+	widget->addToFolder(mConversationsRoot);
 
 	// Add it to the UI
 	widget->setVisible(TRUE);
@@ -533,6 +533,7 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
 
 // Conversation items
 LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp) :
+	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
 	mName(name),
 	mUUID(uuid),
     mFloater(floaterp),
@@ -540,7 +541,8 @@ LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLF
 {
 }
 
-LLConversationItem::LLConversationItem() :
+LLConversationItem::LLConversationItem(LLIMFloaterContainer* containerp) :
+	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
 	mName(""),
 	mUUID(),
 	mFloater(NULL),
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 9b487dd652..b352e8a004 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -57,7 +57,7 @@ class LLConversationItem : public LLFolderViewModelItemCommon
 {
 public:
 	LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
-	LLConversationItem();
+	LLConversationItem(LLIMFloaterContainer* containerp);
 	virtual ~LLConversationItem() {}
 
 	// Stub those things we won't really be using in this conversation context
@@ -241,6 +241,7 @@ public:
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {};
+	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
-- 
cgit v1.2.3


From 4cb1e766fcfcaba702c2638f4c7daa9dd17bcbd8 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 1 Aug 2012 21:08:42 +0300
Subject: CHUI-268 (Transfer the common functionality from LLNearbyChat and
 LLIMFloater to LLIMConversation): Remove duplication of functionality from
 LLNearbyChat; transfer mChatHistory, mInputEditor and some its settings and
 callbacks to the base class.

---
 indra/llui/llfloater.h             |   2 +-
 indra/newview/llimconversation.cpp |  31 ++++++-----
 indra/newview/llimconversation.h   |   8 +--
 indra/newview/llimfloater.cpp      |  18 ++----
 indra/newview/llimfloater.h        |   3 -
 indra/newview/llnearbychat.cpp     | 109 +++++++++++--------------------------
 indra/newview/llnearbychat.h       |   8 +--
 7 files changed, 59 insertions(+), 120 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 17402b8d63..5be6e6d922 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -324,7 +324,7 @@ public:
 	virtual void    setDocked(bool docked, bool pop_on_undock = true);
 
 	virtual void    setTornOff(bool torn_off) { mTornOff = torn_off; }
-	bool getTornOff() {return mTornOff;}
+	bool isTornOff() {return mTornOff;}
 	void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mPositioning = pos;}
 
 	// Return a closeable floater, if any, given the current focus.
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index ec534b903d..3e23d75d28 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -94,12 +94,16 @@ BOOL LLIMConversation::postBuild()
 	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
 
 	mChatHistory = getChild<LLChatHistory>("chat_history");
-	mInputEditor = getChild<LLChatEntry>("chat_editor");
 
+	mInputEditor = getChild<LLChatEntry>("chat_editor");
 	mInputEditor->setTextExpandedCallback(boost::bind(&LLIMConversation::reshapeChatHistory, this));
+	mInputEditor->setCommitOnFocusLost( FALSE );
+	mInputEditor->setPassDelete(TRUE);
+	mInputEditor->setFont(LLViewerChat::getChatFont());
+
 	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
 
-	if (!getTornOff())
+	if (!isTornOff())
 	{
 		setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 	}
@@ -221,18 +225,16 @@ bool LLIMConversation::onIMShowModesMenuItemEnable(const LLSD& userdata)
 
 void LLIMConversation::hideOrShowTitle()
 {
-	bool is_hosted = getHost() != NULL;
-
 	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
 	S32 floater_header_size = default_params.header_height;
 	LLView* floater_contents = getChild<LLView>("contents_view");
 
 	LLRect floater_rect = getLocalRect();
-	S32 top_border_of_contents = floater_rect.mTop - (is_hosted? 0 : floater_header_size);
+	S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0);
 	LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents);
 	LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom);
 	mDragHandle->setShape(handle_rect);
-	mDragHandle->setVisible(! is_hosted);
+	mDragHandle->setVisible(isTornOff());
 	floater_contents->setShape(contents_rect);
 }
 
@@ -250,9 +252,8 @@ void LLIMConversation::hideAllStandardButtons()
 
 void LLIMConversation::updateHeaderAndToolbar()
 {
-	bool is_hosted = getHost() != NULL;
-
-	if (is_hosted)
+	bool is_torn_off = isTornOff();
+	if (!is_torn_off)
 	{
 		hideAllStandardButtons();
 	}
@@ -261,7 +262,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 	// Participant list should be visible only in torn off floaters.
 	bool is_participant_list_visible =
-			!is_hosted
+			is_torn_off
 			&& gSavedSettings.getBOOL("IMShowControlPanel")
 			&& !mIsP2PChat;
 
@@ -269,21 +270,21 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
-	bool is_expanded = is_hosted || is_participant_list_visible;
+	bool is_expanded = !is_torn_off || is_participant_list_visible;
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
 
 	// toggle floater's drag handle and title visibility
 	if (mDragHandle)
 	{
-		mDragHandle->setTitleVisible(!is_hosted);
+		mDragHandle->setTitleVisible(is_torn_off);
 	}
 
 	// The button (>>) should be disabled for torn off P2P conversations.
-	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat);
+	mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat);
 
-	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
+	mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon"));
 
-	mCloseBtn->setVisible(is_hosted && !mIsNearbyChat);
+	mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat);
 
 	enableDisableCallBtn();
 
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index c3dff96d5d..649c200899 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -99,6 +99,10 @@ protected:
 	LLParticipantList* mParticipantList;
 	LLUUID mSessionID;
 
+	LLChatHistory* mChatHistory;
+	LLChatEntry* mInputEditor;
+	int mInputEditorTopPad; // padding between input field and chat history
+
 	LLButton* mExpandCollapseBtn;
 	LLButton* mTearOffBtn;
 	LLButton* mCloseBtn;
@@ -117,10 +121,6 @@ private:
 	 */
 	void reshapeChatHistory();
 
-	LLChatHistory* mChatHistory;
-	LLChatEntry* mInputEditor;
-	int mInputEditorTopPad; // padding between input field and chat history
-
 	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
 };
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 1b08c454b7..3399a88c9e 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -66,11 +66,9 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
   : LLIMConversation(session_id),
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
-	mInputEditor(NULL),
 	mSavedTitle(),
 	mTypingStart(),
 	mShouldSendTypingState(false),
-	mChatHistory(NULL),
 	mMeTyping(false),
 	mOtherTyping(false),
 	mTypingTimer(),
@@ -80,6 +78,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mStartConferenceInSameFloater(false)
 {
 	mIsNearbyChat = false;
+
 	initIMSession(session_id);
 		
 	setOverlapsScreenChannel(true);
@@ -313,9 +312,8 @@ void LLIMFloater::initIMFloater()
 //virtual
 BOOL LLIMFloater::postBuild()
 {
-	LLIMConversation::postBuild();
+	BOOL result = LLIMConversation::postBuild();
 
-	mInputEditor = getChild<LLChatEntry>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
 	// enable line history support for instant message bar
 	// XXX stinson TODO : resolve merge by adding autoreplace to text editors
@@ -323,19 +321,11 @@ BOOL LLIMFloater::postBuild()
 	// *TODO Establish LineEditor with autoreplace callback
 	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
 #endif
-
-	LLFontGL* font = LLViewerChat::getChatFont();
-	mInputEditor->setFont(font);	
 	
 	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
 	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
 	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
-	mInputEditor->setCommitOnFocusLost( FALSE );
-	mInputEditor->setPassDelete( TRUE );
-
 	mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this));
-	
-	mChatHistory = getChild<LLChatHistory>("chat_history");
 
 	setDocked(true);
 
@@ -358,7 +348,7 @@ BOOL LLIMFloater::postBuild()
 	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
 	im_box->addConversationListItem(getTitle(), getKey(), this);
 
-	return TRUE;
+	return result;
 }
 
 void LLIMFloater::onAddButtonClicked()
@@ -1004,7 +994,7 @@ void LLIMFloater::onInputEditorKeystroke(LLTextEditor* caller, void* userdata)
 
 		// Deleting all text counts as stopping typing.
 	self->setTyping(!text.empty());
-	}
+}
 
 void LLIMFloater::setTyping(bool typing)
 {
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 7e45cf42c2..434613ff43 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -184,11 +184,8 @@ private:
 	LLIMModel::LLIMSession* mSession;
 	S32 mLastMessageIndex;
 
-	LLChatHistory* mChatHistory;
-
 	EInstantMessage mDialog;
 	LLUUID mOtherParticipantUUID;
-	LLChatEntry* mInputEditor;
 	bool mPositioned;
 
 	std::string mSavedTitle;
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 3bd5f96add..b628697bbc 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -125,30 +125,24 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
 
 LLNearbyChat::LLNearbyChat(const LLSD& key)
 :	LLIMConversation(key),
-	mChatBox(NULL),
-	mChatHistory(NULL),
 	//mOutputMonitor(NULL),
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
 {
+	mIsNearbyChat = true;
 	setIsChrome(TRUE);
 	mKey = LLSD();
-	mIsNearbyChat = true;
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
 }
 
 //virtual
 BOOL LLNearbyChat::postBuild()
 {
-	mChatBox = getChild<LLChatEntry>("chat_editor");
-
-	mChatBox->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this));
-	mChatBox->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
-	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
-	mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this));
-	mChatBox->setCommitOnFocusLost( FALSE );
-	mChatBox->setPassDelete(TRUE);
-	mChatBox->setFont(LLViewerChat::getChatFont());
+    BOOL result = LLIMConversation::postBuild();
+	mInputEditor->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this));
+	mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
+	mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
+	mInputEditor->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this));
 
 //	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
 //	mOutputMonitor->setVisible(FALSE);
@@ -180,7 +174,6 @@ BOOL LLNearbyChat::postBuild()
 	// obsolete, but may be needed for backward compatibility?
 	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
 
-	mChatHistory = getChild<LLChatHistory>("chat_history");
 	if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
 	{
 		loadHistory();
@@ -190,7 +183,7 @@ BOOL LLNearbyChat::postBuild()
 	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
 	im_box->addConversationListItem(getTitle(), LLSD(), this);
 
-	return LLIMConversation::postBuild();
+	return result;
 }
 
 // virtual
@@ -227,10 +220,6 @@ bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
 	return false;
 }
 
-void LLNearbyChat::getAllowedRect(LLRect& rect)
-{
-	rect = gViewerWindow->getWorldViewRectScaled();
-}
 ////////////////////////////////////////////////////////////////////////////////
 //
 void LLNearbyChat::onFocusReceived()
@@ -352,10 +341,8 @@ void LLNearbyChat::onTearOffClicked()
 {
 	LLIMConversation::onTearOffClicked();
 
-	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-
 	// see CHUI-170: Save torn-off state of the nearby chat between sessions
-	BOOL in_the_multifloater = (getHost() == im_box);
+	BOOL in_the_multifloater = !isTornOff();
 	gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
 }
 
@@ -389,18 +376,12 @@ void LLNearbyChat::onOpen(const LLSD& key)
 	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 }
 
-bool LLNearbyChat::applyRectControl()
-{
-	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-	return LLFloater::applyRectControl();
-}
-
 void LLNearbyChat::onChatFontChange(LLFontGL* fontp)
 {
 	// Update things with the new font whohoo
-	if (mChatBox)
+	if (mInputEditor)
 	{
-		mChatBox->setFont(fontp);
+		mInputEditor->setFont(fontp);
 	}
 }
 
@@ -416,33 +397,20 @@ void LLNearbyChat::show()
 	{
 		openFloater(getKey());
 	}
-	setVisible(TRUE);
 }
 
 bool LLNearbyChat::isChatVisible() const
 {
 	bool isVisible = false;
-
-	if (isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-		// Is the IM floater container ever null?
-		llassert(im_box != NULL);
-		if (im_box != NULL)
-		{
-			if (gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
-			{
-				isVisible = (im_box->getVisible() && !im_box->isMinimized());
-			}
-			else
-			{
-				isVisible = (getVisible() && !isMinimized());
-			}
-		}
-	}
-	else
+	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+	// Is the IM floater container ever null?
+	llassert(im_box != NULL);
+	if (im_box != NULL)
 	{
-		isVisible = (getVisible() && !isMinimized());
+		isVisible =
+				isChatMultiTab() && gSavedSettings.getBOOL("NearbyChatIsNotTornOff")?
+						im_box->getVisible() && !im_box->isMinimized() :
+						getVisible() && !isMinimized();
 	}
 
 	return isVisible;
@@ -452,22 +420,11 @@ void LLNearbyChat::showHistory()
 {
 	openFloater();
 	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-
-	bool is_torn_off = getHost() == NULL;
-
-	// Reshape and enable resize controls only if it's a torn off floater.
-	// Otherwise all the size changes should be handled by LLIMFloaterContainer.
-	if (is_torn_off)
-	{
-		reshape(getRect().getWidth(), mExpandedHeight);
-		enableResizeCtrls(true);
-		storeRectControl();
-	}
 }
 
 std::string LLNearbyChat::getCurrentChat()
 {
-	return mChatBox ? mChatBox->getText() : LLStringUtil::null;
+	return mInputEditor ? mInputEditor->getText() : LLStringUtil::null;
 }
 
 // virtual
@@ -516,7 +473,7 @@ void LLNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata)
 
 	LLNearbyChat* self = (LLNearbyChat *)userdata;
 
-	LLWString raw_text = self->mChatBox->getWText();
+	LLWString raw_text = self->mInputEditor->getWText();
 
 	// Can't trim the end, because that will cause autocompletion
 	// to eat trailing spaces that might be part of a gesture.
@@ -563,17 +520,17 @@ void LLNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata)
 		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
 		{
 			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+			self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
 
 			// Select to end of line, starting from the character
 			// after the last one the user typed.
-			self->mChatBox->selectNext(rest_of_match, false);
+			self->mInputEditor->selectNext(rest_of_match, false);
 		}
 		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
 		{
 			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
-			self->mChatBox->endOfDoc();
+			self->mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
+			self->mInputEditor->endOfDoc();
 		}
 
 		//llinfos << "GESTUREDEBUG " << trigger 
@@ -592,7 +549,7 @@ void LLNearbyChat::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata
 
 void LLNearbyChat::onChatBoxFocusReceived()
 {
-	mChatBox->setEnabled(!gDisconnected);
+	mInputEditor->setEnabled(!gDisconnected);
 }
 
 EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str)
@@ -629,9 +586,9 @@ EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str
 
 void LLNearbyChat::sendChat( EChatType type )
 {
-	if (mChatBox)
+	if (mInputEditor)
 	{
-		LLWString text = mChatBox->getWText();
+		LLWString text = mInputEditor->getWText();
 		LLWStringUtil::trim(text);
 		LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
 		if (!text.empty())
@@ -664,7 +621,7 @@ void LLNearbyChat::sendChat( EChatType type )
 			}
 		}
 
-		mChatBox->setText(LLStringExplicit(""));
+		mInputEditor->setText(LLStringExplicit(""));
 	}
 
 	gAgent.stopTyping();
@@ -735,7 +692,7 @@ void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
 
 void LLNearbyChat::onChatBoxCommit()
 {
-	if (mChatBox->getText().length() > 0)
+	if (mInputEditor->getText().length() > 0)
 	{
 		sendChat(CHAT_TYPE_NORMAL);
 	}
@@ -837,15 +794,15 @@ void LLNearbyChat::startChat(const char* line)
 		cb->show();
 		cb->setVisible(TRUE);
 		cb->setFocus(TRUE);
-		cb->mChatBox->setFocus(TRUE);
+		cb->mInputEditor->setFocus(TRUE);
 
 		if (line)
 		{
 			std::string line_string(line);
-			cb->mChatBox->setText(line_string);
+			cb->mInputEditor->setText(line_string);
 		}
 
-		cb->mChatBox->endOfDoc();
+		cb->mInputEditor->endOfDoc();
 	}
 }
 
@@ -857,7 +814,7 @@ void LLNearbyChat::stopChat()
 
 	if (cb)
 	{
-		cb->mChatBox->setFocus(FALSE);
+		cb->mInputEditor->setFocus(FALSE);
 
 		// stop typing animation
 		gAgent.stopTyping();
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index a0928e67ef..7c58e3037e 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -39,7 +39,6 @@
 #include "llpanel.h"
 
 class LLResizeBar;
-class LLChatHistory;
 
 class LLNearbyChat
 	:	public LLIMConversation
@@ -73,7 +72,7 @@ public:
 	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);
 	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
 
-	LLChatEntry* getChatBox() { return mChatBox; }
+	LLChatEntry* getChatBox() { return mInputEditor; }
 
 	std::string getCurrentChat();
 
@@ -98,8 +97,6 @@ protected:
 	void onChatBoxCommit();
 	void onChatFontChange(LLFontGL* fontp);
 
-	/* virtual */ bool applyRectControl();
-
 	/*virtual*/ void onTearOffClicked();
 
 	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
@@ -113,7 +110,6 @@ protected:
 	// Which non-zero channel did we last chat on?
 	static S32 sLastSpecialChatChannel;
 
-	LLChatEntry*			mChatBox;
 	LLOutputMonitorCtrl*	mOutputMonitor;
 	LLLocalSpeakerMgr*		mSpeakerMgr;
 
@@ -121,7 +117,6 @@ protected:
 
 private:
 
-	void	getAllowedRect		(LLRect& rect);
 	// prepare chat's params and out one message to chatHistory
 	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	void	onNearbySpeakers	();
@@ -130,7 +125,6 @@ private:
 
 	LLHandle<LLView>	mPopupMenuHandle;
 	std::vector<LLChat> mMessageArchive;
-	LLChatHistory*		mChatHistory;
 
 };
 
-- 
cgit v1.2.3


From 898ec6cd362cd92ceef8dca8faf3fb8ed119b1be Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 1 Aug 2012 14:44:29 -0700
Subject: CHUI-254 FIX Fix Inventory filter and item draw() to highlight
 matching substrings in inventory made background highlighting sit behind
 label, so as not to obscure neighboring characters in label

---
 indra/llui/llfolderviewitem.cpp | 50 ++++++++++++++++++++---------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 9b802157f2..480332ae70 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -747,15 +747,29 @@ void LLFolderViewItem::draw()
 		return;
 	}
 
+	std::string::size_type filter_string_length = mViewModelItem->hasFilterStringMatch() ? mViewModelItem->getFilterStringSize() : 0;
+	F32 right_x  = 0;
+	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
+	std::string combined_string = mLabel + mLabelSuffix;
+
+	if (filter_string_length > 0)
+	{
+		S32 left = llround(text_left) + font->getWidth(combined_string, 0, mViewModelItem->getFilterStringOffset()) - 2;
+		S32 right = left + font->getWidth(combined_string, mViewModelItem->getFilterStringOffset(), filter_string_length) + 2;
+		S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
+		S32 top = getRect().getHeight() - TOP_PAD;
+
+		LLUIImage* box_image = default_params.selection_image;
+		LLRect box_rect(left, top, right, bottom);
+		box_image->draw(box_rect, sFilterBGColor);
+	}
+
 	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
 	//TODO RN: implement this in terms of getColor()
 	//if (highlight_link) color = sLinkColor;
 	//if (gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
 	
-	F32 right_x  = 0;
-	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
-
 	//--------------------------------------------------------------------------------//
 	// Draw the actual label text
 	//
@@ -776,27 +790,13 @@ void LLFolderViewItem::draw()
 	//--------------------------------------------------------------------------------//
 	// Highlight string match
 	//
-	if (mViewModelItem->hasFilterStringMatch())
-	{
-		// don't draw backgrounds for zero-length strings
-		std::string::size_type filter_string_length = mViewModelItem->getFilterStringSize();
-		if (filter_string_length > 0)
-		{
-			std::string combined_string = mLabel + mLabelSuffix;
-			S32 left = llround(text_left) + font->getWidth(combined_string, 0, mViewModelItem->getFilterStringOffset()) - 1;
-			S32 right = left + font->getWidth(combined_string, mViewModelItem->getFilterStringOffset(), filter_string_length) + 2;
-			S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
-			S32 top = getRect().getHeight() - TOP_PAD;
-
-			LLUIImage* box_image = default_params.selection_image;
-			LLRect box_rect(left, top, right, bottom);
-			box_image->draw(box_rect, sFilterBGColor);
-			F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
-			F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-			font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
-							  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-							  filter_string_length, S32_MAX, &right_x, FALSE );
-		}
+	if (filter_string_length > 0)
+	{
+		F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
+		F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+		font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
+							sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+							filter_string_length, S32_MAX, &right_x, FALSE );
 	}
 }
 
-- 
cgit v1.2.3


From c6d981a8430f02a5a78afbeece9afeb7b2f108c8 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 1 Aug 2012 17:29:34 -0700
Subject: CHUI-214: Scrolling to offscreen content now works. Problem was due
 to the icon height/width not being computed before scrolling to the new item.
 There was also a problem with the computation that determines if the item
 being scrolled to is within the visible region.

---
 indra/llui/llfolderview.cpp | 45 +++++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 20 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index e09026fc33..bc286c1868 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1704,9 +1704,6 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
 	if(item)
 	{
 		LLRect local_rect = item->getLocalRect();
-		LLRect item_scrolled_rect; // item position relative to display area of scroller
-		LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect();
-		
 		S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); 
 		S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight(); 
 		// when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
@@ -1815,6 +1812,20 @@ void LLFolderView::update()
 		mNeedsAutoSelect = FALSE;
 	}
 
+  BOOL is_visible = isInVisibleChain();
+
+  //Puts folders/items in proper positions
+  if ( is_visible )
+  {
+    sanitizeSelection();
+    if( needsArrange() )
+    {
+      S32 height = 0;
+      S32 width = 0;
+      S32 total_height = arrange( &width, &height );
+      notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
+    }
+  }
 
 	// during filtering process, try to pin selected item's location on screen
 	// this will happen when searching your inventory and when new items arrive
@@ -1826,18 +1837,26 @@ void LLFolderView::update()
 			// lets pin it!
 			mPinningSelectedItem = TRUE;
 
-			LLRect visible_content_rect = (mScrollContainer ? mScrollContainer->getVisibleContentRect() : LLRect());
+      //Computes visible area 
+			const LLRect visible_content_rect = (mScrollContainer ? mScrollContainer->getVisibleContentRect() : LLRect());
 			LLFolderViewItem* selected_item = mSelectedItems.back();
 
+      //Computes location of selected content, content outside visible area will be scrolled to using below code
 			LLRect item_rect;
 			selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
-			// if item is visible in scrolled region
-			if (visible_content_rect.overlaps(item_rect))
+			
+      //Computes intersected region of the selected content and visible area
+      LLRect overlap_rect(item_rect);
+      overlap_rect.intersectWith(visible_content_rect);
+
+      //Don't scroll when the selected content exists within the visible area
+			if (overlap_rect.getHeight() >= selected_item->getItemHeight())
 			{
 				// then attempt to keep it in same place on screen
 				mScrollConstraintRect = item_rect;
 				mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
 			}
+      //Scroll because the selected content is outside the visible area
 			else
 			{
 				// otherwise we just want it onscreen somewhere
@@ -1868,20 +1887,6 @@ void LLFolderView::update()
 		constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
 	}
 
-	BOOL is_visible = isInVisibleChain();
-
-	if ( is_visible )
-	{
-		sanitizeSelection();
-		if( needsArrange() )
-		{
-			S32 height = 0;
-			S32 width = 0;
-			S32 total_height = arrange( &width, &height );
-			notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
-		}
-	}
-
 	if (mSelectedItems.size() && mNeedsScroll)
 	{
 		scrollToShowItem(mSelectedItems.back(), constraint_rect);
-- 
cgit v1.2.3


From c009cf4f7656ec27347e1e9c740da26c12726c99 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 1 Aug 2012 19:42:22 -0700
Subject: CHUI-223 WIP Selecting to cut an inventory item causes all open
 inventory windows to refresh improved filtering behavior that should result
 in less flashes of emptiness

---
 indra/llui/llfolderviewitem.cpp              |  6 ++--
 indra/llui/llfolderviewmodel.h               | 20 +++++++++----
 indra/llui/lltooltip.cpp                     |  2 +-
 indra/newview/llfolderviewmodelinventory.cpp | 42 ++++++++++++++++++----------
 indra/newview/llfolderviewmodelinventory.h   |  6 ++--
 indra/newview/llimfloatercontainer.h         |  4 +--
 6 files changed, 52 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 480332ae70..5238bfd7e4 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -801,14 +801,14 @@ void LLFolderViewItem::draw()
 }
 
 const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
-	{
+{
 	return getRoot()->getFolderViewModel();
 }
 
 LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
-		{
+{
 	return getRoot()->getFolderViewModel();
-		}
+}
 
 
 ///----------------------------------------------------------------------------
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index c4d98657e2..9908e538a4 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -172,10 +172,11 @@ public:
 	
 	virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
 
-	virtual void filter( LLFolderViewFilter& filter) = 0;
+	virtual bool filter( LLFolderViewFilter& filter) = 0;
 	virtual bool passedFilter(S32 filter_generation = -1) = 0;
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
-	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) = 0;
+	virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) = 0;
+	virtual void setPassedFolderFilter(bool passed, S32 filter_generation) = 0;
 	virtual void dirtyFilter() = 0;
 	virtual bool hasFilterStringMatch() = 0;
 	virtual std::string::size_type getFilterStringOffset() = 0;
@@ -219,6 +220,7 @@ public:
 		mStringFilterSize(0),
 		mFolderViewItem(NULL),
 		mLastFilterGeneration(-1),
+		mLastFolderFilterGeneration(-1),
 		mMostFilteredDescendantGeneration(-1),
 		mParent(NULL),
 		mRootViewModel(root_view_model)
@@ -231,9 +233,11 @@ public:
 	void setSortVersion(S32 version) { mSortVersion = version;}
 
 	S32	getLastFilterGeneration() const { return mLastFilterGeneration; }
+	S32	getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
 	void dirtyFilter()
 	{
 		mLastFilterGeneration = -1;
+		mLastFolderFilterGeneration = -1;
 
 		// bubble up dirty flag all the way to root
 		if (mParent)
@@ -259,15 +263,20 @@ public:
 		dirtyFilter();
 	}
 
-	void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
+	void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
 	{
 		mPassedFilter = passed;
-		mPassedFolderFilter = passed_folder;
 		mLastFilterGeneration = filter_generation;
 		mStringMatchOffsetFilter = string_offset;
 		mStringFilterSize = string_size;
 	}
 
+	void setPassedFolderFilter(bool passed, S32 filter_generation)
+	{
+		mPassedFolderFilter = passed;
+		mLastFolderFilterGeneration = filter_generation;
+	}
+
 	virtual bool potentiallyVisible()
 	{
 		return passedFilter() // we've passed the filter
@@ -280,7 +289,7 @@ public:
 		if (filter_generation < 0) 
 			filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
 
-		bool passed_folder_filter = mPassedFolderFilter && mLastFilterGeneration >= filter_generation;
+		bool passed_folder_filter = mPassedFolderFilter && mLastFolderFilterGeneration >= filter_generation;
 		bool passed_filter = mPassedFilter && mLastFilterGeneration >= filter_generation;
 		return passed_folder_filter
 				&& (descendantsPassedFilter(filter_generation)
@@ -304,6 +313,7 @@ protected:
 	std::string::size_type	mStringFilterSize;
 
 	S32						mLastFilterGeneration;
+	S32						mLastFolderFilterGeneration;
 	S32						mMostFilteredDescendantGeneration;
 
 
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index f737d48abf..d4670efedf 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -288,7 +288,7 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
 		mTextBox->setText(p.message());
 	}
 
-	S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth());
+	S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth() + 1);
 	S32 text_height = mTextBox->getTextPixelHeight();
 	mTextBox->reshape(text_width, text_height);
 	if (mInfoButton)
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index e2376b18d5..8a4b4bae84 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -125,9 +125,9 @@ void LLFolderViewModelItemInventory::requestSort()
 	}
 }
 
-void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size)
+void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset, std::string::size_type string_size)
 {
-	LLFolderViewModelItemCommon::setPassedFilter(passed, passed_folder, filter_generation, string_offset, string_size);
+	LLFolderViewModelItemCommon::setPassedFilter(passed, filter_generation, string_offset, string_size);
 
 	bool passed_filter_before = mPrevPassedAllFilters;
 	mPrevPassedAllFilters = passedFilter(filter_generation);
@@ -143,14 +143,15 @@ void LLFolderViewModelItemInventory::setPassedFilter(bool passed, bool passed_fo
 	}
 }
 
-void LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
+bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
 {
 	S32 filter_generation = filter.getCurrentGeneration();
 
+	bool continue_filtering = true;
 	if (item->getLastFilterGeneration() < filter_generation)
 	{
 		// recursive application of the filter for child items
-		item->filter( filter );
+		continue_filtering = item->filter( filter );
 	}
 
 	// track latest generation to pass any child items, for each folder up to root
@@ -164,22 +165,31 @@ void LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* ite
 			view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent);
 		}
 	}
+
+	return continue_filtering;
 }
 
-void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
+bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 {
 	const S32 filter_generation = filter.getCurrentGeneration();
 	const S32 must_pass_generation = filter.getFirstRequiredGeneration();
 
 	if (getLastFilterGeneration() >= must_pass_generation 
+		&& getLastFolderFilterGeneration() >= must_pass_generation
 		&& !passedFilter(must_pass_generation))
 	{
 		// failed to pass an earlier filter that was a subset of the current one
 		// go ahead and flag this item as done
-		setPassedFilter(false, false, filter_generation);
-		return;
+		setPassedFilter(false, filter_generation);
+		setPassedFolderFilter(false, filter_generation);
+		return true;
 	}
 
+	const bool passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) 
+		? filter.checkFolder(this)
+		: true;
+	setPassedFolderFilter(passed_filter_folder, filter_generation);
+
 	if(!mChildren.empty()
 		&& (getLastFilterGeneration() < must_pass_generation // haven't checked descendants against minimum required generation to pass
 			|| descendantsPassedFilter(must_pass_generation))) // or at least one descendant has passed the minimum requirement
@@ -189,7 +199,10 @@ void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 			iter != end_iter && filter.getFilterCount() > 0;
 			++iter)
 		{
-			filterChildItem((*iter), filter);
+			if (!filterChildItem((*iter), filter))
+			{
+				break;
+			}
 		}
 	}
 
@@ -200,12 +213,13 @@ void LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
 	{
 		filter.decrementFilterCount();
 
-		const BOOL passed_filter = filter.check(this);
-		const BOOL passed_filter_folder = (getInventoryType() == LLInventoryType::IT_CATEGORY) 
-								? filter.checkFolder(this)
-								: true;
-
-		setPassedFilter(passed_filter, passed_filter_folder, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize());
+		const bool passed_filter = filter.check(this);
+		setPassedFilter(passed_filter, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize());
+		return true;
+	}
+	else
+	{
+		return false;
 	}
 }
 
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index 664addf336..890d03d1c9 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -53,9 +53,9 @@ public:
 	virtual EInventorySortGroup getSortGroup() const = 0;
 	virtual LLInventoryObject* getInventoryObject() const = 0;
 	virtual void requestSort();
-	virtual void setPassedFilter(bool filtered, bool filtered_folder, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0);
-	virtual void filter( LLFolderViewFilter& filter);
-	virtual void filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+	virtual void setPassedFilter(bool filtered, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0);
+	virtual bool filter( LLFolderViewFilter& filter);
+	virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
 
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
 	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index b352e8a004..5154b02dd6 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -89,9 +89,9 @@ public:
 	virtual bool hasChildren() const { return FALSE; }
 
 	virtual bool potentiallyVisible() { return true; }
-	virtual void filter( LLFolderViewFilter& filter) { }
+	virtual bool filter( LLFolderViewFilter& filter) { return false; }
 	virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
-	virtual void setPassedFilter(bool passed, bool passed_folder, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { }
+	virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { }
 	virtual bool passedFilter(S32 filter_generation = -1) { return true; }
 
 	// The action callbacks
-- 
cgit v1.2.3


From 88e81f99293c992944787289699bf885568bf327 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Wed, 1 Aug 2012 20:07:42 -0700
Subject: CHUI-223 WIP Selecting to cut an inventory item causes all open
 inventory windows to refresh avoid moving selection when cutting

---
 indra/llui/llfolderview.cpp        | 57 +++++++++++++++++++-------------------
 indra/llui/llfolderviewitem.cpp    |  6 ++++
 indra/llui/llfolderviewitem.h      |  1 +
 indra/newview/llinventorypanel.cpp | 17 ++++++------
 4 files changed, 44 insertions(+), 37 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index d714d4623d..5d98dc9663 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -717,33 +717,6 @@ void LLFolderView::closeRenamer( void )
 	}
 }
 
-bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
-{
-	LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
-
-	if (item_parent)
-	{
-		for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
-		{
-			const LLFolderViewItem* const selected_item = (*it);
-
-			LLFolderViewItem* parent = item_parent;
-
-			while (parent)
-			{
-				if (selected_item == parent)
-				{
-					return true;
-				}
-
-				parent = dynamic_cast<LLFolderViewItem*>(parent->getParent());
-			}
-		}
-	}
-
-	return false;
-}
-
 void LLFolderView::removeSelectedItems()
 {
 	if(getVisible() && getEnabled())
@@ -815,7 +788,7 @@ void LLFolderView::removeSelectedItems()
 			if (!new_selection)
 			{
 				new_selection = last_item->getPreviousOpenNode(FALSE);
-				while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items)))
+				while (new_selection && (new_selection->isInSelection()))
 				{
 					new_selection = new_selection->getPreviousOpenNode(FALSE);
 				}
@@ -1060,16 +1033,42 @@ void LLFolderView::cut()
 	if(getVisible() && getEnabled() && (count > 0))
 	{
 		LLFolderViewModelItem* listener = NULL;
+
+		LLFolderViewItem* last_item = *mSelectedItems.rbegin();;
+		LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
+		while(new_selection && new_selection->isSelected())
+		{
+			new_selection = new_selection->getNextOpenNode(FALSE);
+		}
+		if (!new_selection)
+		{
+			new_selection = last_item->getPreviousOpenNode(FALSE);
+			while (new_selection && (new_selection->isInSelection()))
+			{
+				new_selection = new_selection->getPreviousOpenNode(FALSE);
+			}
+		}
+
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
-			listener = (*item_it)->getViewModelItem();
+			LLFolderViewItem* item_to_cut = *item_it;
+			listener = item_to_cut->getViewModelItem();
 			if(listener)
 			{
 				listener->cutToClipboard();
 				listener->removeItem();
 			}
 		}
+
+		if (new_selection)
+		{
+			setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
+		}
+		else
+		{
+			setSelection(NULL, mParentPanel->hasFocus());
+		}
 	}
 	mSearchString.clear();
 }
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 5238bfd7e4..68b442dd9a 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -810,6 +810,12 @@ LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
 	return getRoot()->getFolderViewModel();
 }
 
+bool LLFolderViewItem::isInSelection() const
+{
+	return mIsSelected || (mParentFolder && mParentFolder->isInSelection());
+}
+
+
 
 ///----------------------------------------------------------------------------
 /// Class LLFolderViewFolder
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 4eda02f13f..e75059bc01 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -164,6 +164,7 @@ public:
 	virtual void destroyView();
 
 	BOOL isSelected() const { return mIsSelected; }
+	bool isInSelection() const;
 
 	void setUnselected() { mIsSelected = FALSE; }
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 1b3391f7ee..9403ccdabe 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -281,13 +281,6 @@ void LLInventoryPanel::draw()
 	// Select the desired item (in case it wasn't loaded when the selection was requested)
 	updateSelection();
 	
-	// Nudge the filter if the clipboard state changed
-	if (mClipboardState != LLClipboard::instance().getGeneration())
-	{
-		mClipboardState = LLClipboard::instance().getGeneration();
-		getFilter().setModified(LLClipboard::instance().isCutMode() ? LLInventoryFilter::FILTER_MORE_RESTRICTIVE : LLInventoryFilter::FILTER_LESS_RESTRICTIVE);
-	}
-	
 	LLPanel::draw();
 }
 
@@ -586,7 +579,6 @@ LLUUID LLInventoryPanel::getRootFolderID()
 	}
 }
 
-
 // static
 void LLInventoryPanel::onIdle(void *userdata)
 {
@@ -608,6 +600,15 @@ void LLInventoryPanel::onIdle(void *userdata)
 void LLInventoryPanel::idle(void* user_data)
 {
 	LLInventoryPanel* panel = (LLInventoryPanel*)user_data;
+	// Nudge the filter if the clipboard state changed
+	if (panel->mClipboardState != LLClipboard::instance().getGeneration())
+	{
+		panel->mClipboardState = LLClipboard::instance().getGeneration();
+		panel->getFilter().setModified(LLClipboard::instance().isCutMode() 
+										? LLInventoryFilter::FILTER_MORE_RESTRICTIVE 
+										: LLInventoryFilter::FILTER_LESS_RESTRICTIVE);
+	}
+
 	panel->mFolderRoot->update();
 	// while dragging, update selection rendering to reflect single/multi drag status
 	if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
-- 
cgit v1.2.3


From 0fa1e2b9ae41bb06e5c7db90900d4f469f44b8d3 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 2 Aug 2012 18:43:44 +0300
Subject: CHUI-230, CHUI-232, CHUI-261 Forced resize of a conversation's
 floater in the IM-container; support of the rectControls for
 IM-conversations; fixed LLFloater and LLMultiFloater for the correct hosting
 of floaters with mSaveRect

---
 indra/llui/llfloater.cpp                           | 61 +++++++++++++---------
 indra/llui/llfloater.h                             |  1 +
 indra/llui/llmultifloater.cpp                      |  3 ++
 indra/llui/llmultifloater.h                        |  9 ++--
 indra/newview/llimconversation.cpp                 | 15 ++++--
 indra/newview/llimfloatercontainer.cpp             |  5 ++
 indra/newview/llnearbychat.cpp                     |  2 -
 .../skins/default/xui/en/floater_im_session.xml    |  3 +-
 8 files changed, 61 insertions(+), 38 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index a1c902d562..8145d6d347 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1175,7 +1175,6 @@ void LLFloater::setMinimized(BOOL minimize)
 	{
 		// minimized flag should be turned on before release focus
 		mMinimized = TRUE;
-
 		mExpandedRect = getRect();
 
 		// If the floater has been dragged while minimized in the
@@ -1248,7 +1247,6 @@ void LLFloater::setMinimized(BOOL minimize)
 		}
 
 		setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom );
-
 		if (mButtonsEnabled[BUTTON_RESTORE])
 		{
 			mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
@@ -1284,7 +1282,6 @@ void LLFloater::setMinimized(BOOL minimize)
 
 		// Reshape *after* setting mMinimized
 		reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
-		applyPositioning(NULL, false);
 	}
 
 	make_ui_sound("UISndWindowClose");
@@ -1658,10 +1655,12 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		gFloaterView->addChild(self);
 
 		self->openFloater(self->getKey());
-		
-		// only force position for floaters that don't have that data saved
-		if (self->mRectControl.empty())
+		if (self->mSaveRect && !self->mRectControl.empty())
 		{
+			self->applyRectControl();
+		}
+		else
+		{   // only force position for floaters that don't have that data saved
 			new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());
 			self->setRect(new_rect);
 		}
@@ -1675,6 +1674,10 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get();
 		if (new_host)
 		{
+			if (self->mSaveRect)
+			{
+				self->storeRectControl();
+			}
 			self->setMinimized(FALSE); // to reenable minimize button if it was minimized
 			new_host->showFloater(self);
 			// make sure host is visible
@@ -1709,6 +1712,18 @@ void LLFloater::onClickHelp( LLFloater* self )
 	}
 }
 
+void LLFloater::initRectControl()
+{
+	// save_rect and save_visibility only apply to registered floaters
+	if (mSaveRect)
+	{
+		std::string ctrl_name = getControlName(mInstanceName, mKey);
+		mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
+		mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
+		mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
+	}
+}
+
 // static 
 LLFloater* LLFloater::getClosableFloaterFromFocus()
 {
@@ -2940,28 +2955,22 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
 
 void LLFloater::setInstanceName(const std::string& name)
 {
-	if (name == mInstanceName)
-		return;
-	llassert_always(mInstanceName.empty());
-	mInstanceName = name;
-	if (!mInstanceName.empty())
+	if (name != mInstanceName)
 	{
-		std::string ctrl_name = getControlName(mInstanceName, mKey);
-
-		// save_rect and save_visibility only apply to registered floaters
-		if (mSaveRect)
-		{
-			mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
-			mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
-			mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
-		}
-		if (!mVisibilityControl.empty())
+		llassert_always(mInstanceName.empty());
+		mInstanceName = name;
+		if (!mInstanceName.empty())
 		{
-			mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name);
-		}
-		if(!mDocStateControl.empty())
-		{
-			mDocStateControl = LLFloaterReg::declareDockStateControl(ctrl_name);
+			std::string ctrl_name = getControlName(mInstanceName, mKey);
+			initRectControl();
+			if (!mVisibilityControl.empty())
+			{
+				mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name);
+			}
+			if(!mDocStateControl.empty())
+			{
+				mDocStateControl = LLFloaterReg::declareDockStateControl(ctrl_name);
+			}
 		}
 	}
 }
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 5be6e6d922..a1cac64a4a 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -358,6 +358,7 @@ protected:
 
 	void			stackWith(LLFloater& other);
 
+	virtual void    initRectControl();
 	virtual bool	applyRectControl();
 	bool			applyDockState();
 	void			applyPositioning(LLFloater* other, bool on_open);
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index e80799b16d..02ff64dbc6 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -188,11 +188,13 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
 	floater_data.mHeight = floaterp->getRect().getHeight();
 	floater_data.mCanMinimize = floaterp->isMinimizeable();
 	floater_data.mCanResize = floaterp->isResizable();
+    floater_data.mSaveRect = floaterp->mSaveRect;
 
 	// remove minimize and close buttons
 	floaterp->setCanMinimize(FALSE);
 	floaterp->setCanResize(FALSE);
 	floaterp->setCanDrag(FALSE);
+	floaterp->mSaveRect = FALSE;
 	floaterp->storeRectControl();
 	// avoid double rendering of floater background (makes it more opaque)
 	floaterp->setBackgroundVisible(FALSE);
@@ -291,6 +293,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)
 	{
 		LLFloaterData& floater_data = found_data_it->second;
 		floaterp->setCanMinimize(floater_data.mCanMinimize);
+		floaterp->mSaveRect = floater_data.mSaveRect;
 		if (!floater_data.mCanResize)
 		{
 			// restore original size
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index 44514a6246..d992212650 100644
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -79,10 +79,11 @@ public:
 protected:
 	struct LLFloaterData
 	{
-		S32		mWidth;
-		S32		mHeight;
-		BOOL	mCanMinimize;
-		BOOL	mCanResize;
+		S32		    mWidth;
+		S32		    mHeight;
+		BOOL	    mCanMinimize;
+		BOOL	    mCanResize;
+		BOOL        mSaveRect;
 	};
 
 	LLTabContainer*		mTabContainer;
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 3e23d75d28..b56f30312a 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -103,15 +103,15 @@ BOOL LLIMConversation::postBuild()
 
 	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
 
-	if (!isTornOff())
-	{
-		setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
-	}
+	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 
 	buildParticipantList();
 
 	updateHeaderAndToolbar();
 
+	mSaveRect = isTornOff();
+	initRectControl();
+
 	if (isChatMultiTab())
 	{
 		if (mIsNearbyChat)
@@ -364,12 +364,14 @@ void LLIMConversation::onSlide(LLIMConversation* self)
 void LLIMConversation::onOpen(const LLSD& key)
 {
 	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
-	if (host_floater)
+    bool is_hosted = !!host_floater;
+	if (is_hosted)
 	{
 		// Show the messages pane when opening a floater hosted in the Conversations
 		host_floater->collapseMessagesPane(false);
 	}
 
+	setTornOff(!is_hosted);
 	updateHeaderAndToolbar();
 }
 
@@ -389,6 +391,9 @@ void LLIMConversation::onClose(bool app_quitting)
 
 void LLIMConversation::onTearOffClicked()
 {
+    setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
+    mSaveRect = isTornOff();
+    initRectControl();
 	LLFloater::onClickTearOff(this);
 	updateHeaderAndToolbar();
 }
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index cc094fcaa1..d618e7491a 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -174,6 +174,11 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 		mSessions[session_id] = floaterp;
 		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
 	}
+
+	// forced resize of the floater
+	LLRect wrapper_rect = this->mTabContainer->getLocalRect();
+	floaterp->setRect(wrapper_rect);
+
 	mTabContainer->setTabImage(floaterp, icon);
 }
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index b628697bbc..8f0e6b4c83 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -150,8 +150,6 @@ BOOL LLNearbyChat::postBuild()
 	// Register for font change notifications
 	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChat::onChatFontChange, this, _1));
 
-	enableResizeCtrls(true, true, false);
-
 	// title must be defined BEFORE call addConversationListItem() because
 	// it is used for show the item's name in the conversations list
 	setTitle(getString("NearbyChatTitle"));
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 09c1510004..675967035f 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -15,7 +15,8 @@
  can_resize="true"
  can_tear_off="false"
  min_width="250"
- min_height="190">
+ min_height="190"
+ positioning="relative">
     <floater.string 
      name="NearbyChatTitle"
      value="Nearby Chat"/>
-- 
cgit v1.2.3


From 4e7c2c6942b6169812459f19cb13c9f4101dcaf1 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 2 Aug 2012 22:49:42 +0300
Subject: CHUI-228 FIX Inventory object creation date initialized with 0 to
 avoid some folders reporting wrong creation date.

---
 indra/llinventory/llinventory.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 6e54f9d78a..a80ae73dca 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -75,13 +75,15 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,
 	mUUID(uuid),
 	mParentUUID(parent_uuid),
 	mType(type),
-	mName(name)
+	mName(name),
+	mCreationDate(0)
 {
 	correctInventoryName(mName);
 }
 
 LLInventoryObject::LLInventoryObject() :
-	mType(LLAssetType::AT_NONE)
+	mType(LLAssetType::AT_NONE),
+	mCreationDate(0)
 {
 }
 
-- 
cgit v1.2.3


From c44aa1c96655bc762f74583f92eedc155cf23a45 Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Thu, 2 Aug 2012 17:26:09 -0700
Subject: CHUI-262: Reordering the steps to remove a view item and view item
 model during the deletion process to avoid a crash.

---
 indra/newview/llinventorypanel.cpp | 5 ++++-
 indra/newview/llvopartgroup.cpp    | 4 ++--
 2 files changed, 6 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 9403ccdabe..e67b59ddcc 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -514,10 +514,13 @@ void LLInventoryPanel::modelChanged(U32 mask)
 						}
 						else 
 						{
+							// Remove the item ID before destroying the view because the view-model-item gets
+							// destroyed when the view is destroyed
+                            removeItemID(viewmodel_item->getUUID());
+
 							// Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that 
 							// doesn't include trash).  Just remove the item's UI.
 							view_item->destroyView();
-                            removeItemID(viewmodel_item->getUUID());
 						}
 					}
 				}
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index e21358b65a..a2794bec56 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -149,8 +149,8 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
 void LLVOPartGroup::freeVBSlot(S32 idx)
 {
 	llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
-	llassert(sVBSlotCursor > sVBSlotFree);
-	llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
+	//llassert(sVBSlotCursor > sVBSlotFree);
+	//llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
 
 	if (sVBSlotCursor > sVBSlotFree)
 	{
-- 
cgit v1.2.3


From ae2de6bdcfa5ed40f820652193753b29bceaef80 Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Thu, 2 Aug 2012 18:38:38 -0700
Subject: Re-enabling the voice-dot until I have more time to invest in the new
 CHUI version.

---
 indra/newview/llhudobject.h         |    2 +
 indra/newview/llvoavatar.cpp        |    2 +
 indra/newview/llvoicevisualizer.cpp | 1285 ++++++++++++++++++-----------------
 indra/newview/llvoicevisualizer.h   |    1 +
 4 files changed, 648 insertions(+), 642 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 21cf5fe17c..32cffe6839 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -39,6 +39,8 @@
 #include "lldrawpool.h"		// TODO: eliminate, unused below
 #include <list>
 
+#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
+
 class LLViewerCamera;
 class LLFontGL;
 class LLFace;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 2871b7b018..20b33b5bea 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -34,6 +34,8 @@
 
 #include "llvoavatar.h"
 
+#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
+
 #include <stdio.h>
 #include <ctype.h>
 
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index dcf33bce10..d380a8672f 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -1,642 +1,643 @@
-/** 
- * @file llvoicevisualizer.cpp
- * @brief Draws in-world speaking indicators.
- *
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-//----------------------------------------------------------------------
-// Voice Visualizer
-// author: JJ Ventrella
-// (information about this stuff can be found in "llvoicevisualizer.h")
-//----------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-#include "llviewercontrol.h"
-#include "llglheaders.h"
-#include "llsphere.h"
-#include "llvoicevisualizer.h"
-#include "llviewercamera.h"
-#include "llviewerobject.h"
-#include "llviewertexture.h"
-#include "llviewertexturelist.h"
-#include "llvoiceclient.h"
-#include "llrender.h"
-
-//brent's wave image
-//29de489d-0491-fb00-7dab-f9e686d31e83
-
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//--------------------------------------------------------------------------------------
-// sound symbol constants
-//--------------------------------------------------------------------------------------
-const F32	HEIGHT_ABOVE_HEAD	= 0.3f;		// how many meters vertically above the av's head the voice symbol will appear
-const F32	RED_THRESHOLD		= LLVoiceClient::OVERDRIVEN_POWER_LEVEL;		// value above which speaking amplitude causes the voice symbol to turn red
-const F32	GREEN_THRESHOLD		= 0.2f;		// value above which speaking amplitude causes the voice symbol to turn green
-const F32	FADE_OUT_DURATION	= 0.4f;		// how many seconds it takes for a pair of waves to fade away
-const F32	EXPANSION_RATE		= 1.0f;		// how many seconds it takes for the waves to expand to twice their original size
-const F32	EXPANSION_MAX		= 1.5f;		// maximum size scale to which the waves can expand before popping back to 1.0 
-const F32	WAVE_WIDTH_SCALE	= 0.03f;	// base width of the waves 
-const F32	WAVE_HEIGHT_SCALE	= 0.02f;	// base height of the waves 
-const F32	BASE_BRIGHTNESS		= 0.7f;		// gray level of the voice indicator when quiet (below green threshold)
-const F32	DOT_SIZE			= 0.05f;	// size of the dot billboard texture
-const F32	DOT_OPACITY			= 0.7f;		// how opaque the dot is
-const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a function of speaking amplitude
-#endif // XXX_STINSON_CHUI_REWORK
-
-//--------------------------------------------------------------------------------------
-// gesticulation constants
-//--------------------------------------------------------------------------------------
-const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE	= 0.2f; 
-const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f;
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//--------------------------------------------------------------------------------------
-// other constants
-//--------------------------------------------------------------------------------------
-const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. 
-const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
-#endif // XXX_STINSON_CHUI_REWORK
-
-//------------------------------------------------------------------
-// Initialize the statics
-//------------------------------------------------------------------
-bool LLVoiceVisualizer::sPrefsInitialized	= false;
-BOOL LLVoiceVisualizer::sLipSyncEnabled		= FALSE;
-F32* LLVoiceVisualizer::sOoh				= NULL;
-F32* LLVoiceVisualizer::sAah				= NULL;
-U32	 LLVoiceVisualizer::sOohs				= 0;
-U32	 LLVoiceVisualizer::sAahs				= 0;
-F32	 LLVoiceVisualizer::sOohAahRate			= 0.0f;
-F32* LLVoiceVisualizer::sOohPowerTransfer	= NULL;
-U32	 LLVoiceVisualizer::sOohPowerTransfers	= 0;
-F32	 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
-F32* LLVoiceVisualizer::sAahPowerTransfer	= NULL;
-U32	 LLVoiceVisualizer::sAahPowerTransfers	= 0;
-F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
-
-
-//-----------------------------------------------
-// constructor
-//-----------------------------------------------
-#ifdef XXX_STINSON_CHUI_REWORK
-LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
-#else // XXX_STINSON_CHUI_REWORK
-LLVoiceVisualizer::LLVoiceVisualizer()
-	: LLRefCount(),
-	mTimer(),
-	mStartTime(0.0),
-	mCurrentlySpeaking(false),
-	mSpeakingAmplitude(0.0f),
-	mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE),
-	mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE)
-#endif // XXX_STINSON_CHUI_REWORK
-{
-#ifdef XXX_STINSON_CHUI_REWORK
-	mCurrentTime					= mTimer.getTotalSeconds();
-	mPreviousTime					= mCurrentTime;
-	mStartTime						= mCurrentTime;
-#else // XXX_STINSON_CHUI_REWORK
-	mStartTime						= mTimer.getTotalSeconds();
-#endif // XXX_STINSON_CHUI_REWORK
-#ifdef XXX_STINSON_CHUI_REWORK
-	mVoiceSourceWorldPosition		= LLVector3( 0.0f, 0.0f, 0.0f );
-	mSpeakingAmplitude				= 0.0f;
-	mCurrentlySpeaking				= false;
-	mVoiceEnabled					= false;
-	mMinGesticulationAmplitude		= DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
-	mMaxGesticulationAmplitude		= DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
-	mSoundSymbol.mActive			= true;
-	mSoundSymbol.mPosition			= LLVector3( 0.0f, 0.0f, 0.0f );
-#endif // XXX_STINSON_CHUI_REWORK
-	
-	mTimer.reset();
-	
-#ifdef XXX_STINSON_CHUI_REWORK
-	const char* sound_level_img[] = 
-	{
-		"voice_meter_dot.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c",
-		"voice_meter_rings.j2c"
-	};
-
-	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
-	{
-		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
-		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
-		mSoundSymbol.mWaveActive			[i] = false;
-		mSoundSymbol.mWaveOpacity			[i] = 1.0f;
-		mSoundSymbol.mWaveExpansion			[i] = 1.0f;
-	}
-
-	mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-#endif // XXX_STINSON_CHUI_REWORK
-
-	// The first instance loads the initial state from prefs.
-	if (!sPrefsInitialized)
-	{
-		setPreferences();
-       
-		// Set up our listener to get updates on all prefs values we care about.
-		gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
-		
-		sPrefsInitialized = true;
-	}
-
-}//---------------------------------------------------
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//---------------------------------------------------
-void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
-{
-	mMinGesticulationAmplitude = m;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
-{
-	mMaxGesticulationAmplitude = m;
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setVoiceEnabled( bool v )
-{
-	mVoiceEnabled = v;
-
-}//---------------------------------------------------
-#endif // XXX_STINSON_CHUI_REWORK
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setStartSpeaking()
-{
-	mStartTime				= mTimer.getTotalSeconds();
-	mCurrentlySpeaking		= true;
-#ifdef XXX_STINSON_CHUI_REWORK
-	mSoundSymbol.mActive	= true;
-#endif // XXX_STINSON_CHUI_REWORK
-		
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-bool LLVoiceVisualizer::getCurrentlySpeaking()
-{
-	return mCurrentlySpeaking;
-	
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setStopSpeaking()
-{
-	mCurrentlySpeaking = false;
-	mSpeakingAmplitude = 0.0f;
-	
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
-{
-	mSpeakingAmplitude = a;
-	
-}//---------------------------------------------------
-
-//------------------------------------------------------------------
-// handles parameter updates
-//------------------------------------------------------------------
-bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
-{
-	// Note: Ignore the specific event value, we look up the ones we want
-	LLVoiceVisualizer::setPreferences();
-	return true;
-}
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setPreferences( )
-{
-	sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
-	sOohAahRate		= gSavedSettings.getF32("LipSyncOohAahRate");
-
-	std::string oohString = gSavedSettings.getString("LipSyncOoh");
-	lipStringToF32s (oohString, sOoh, sOohs);
-
-	std::string aahString = gSavedSettings.getString("LipSyncAah");
-	lipStringToF32s (aahString, sAah, sAahs);
-
-	std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
-	lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
-	sOohPowerTransfersf = (F32) sOohPowerTransfers;
-
-	std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
-	lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
-	sAahPowerTransfersf = (F32) sAahPowerTransfers;
-
-}//---------------------------------------------------
-
-
-//---------------------------------------------------
-// convert a string of digits to an array of floats.
-// the result for each digit is the value of the
-// digit multiplied by 0.11
-//---------------------------------------------------
-void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
-{
-	delete[] out_F32s;	// get rid of the current array
-
-	count_F32s = in_string.length();
-	if (count_F32s == 0)
-	{
-		// we don't like zero length arrays
-
-		count_F32s  = 1;
-		out_F32s	   = new F32[1];
-		out_F32s[0] = 0.0f;
-	}
-	else
-	{
-		out_F32s = new F32[count_F32s];
-
-		for (U32 i=0; i<count_F32s; i++)
-		{
-			// we convert the characters 0 to 9 to their numeric value
-			// anything else we take the low order four bits with a ceiling of 9
-
-		    U8 digit = in_string[i];
-			U8 four_bits = digit % 16;
-			if (four_bits > 9)
-			{
-				four_bits = 9;
-			}
-			out_F32s[i] = 0.11f * (F32) four_bits;
-		} 
-	}
-
-}//---------------------------------------------------
-
-
-//--------------------------------------------------------------------------
-// find the amount to blend the ooh and aah mouth morphs
-//--------------------------------------------------------------------------
-void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
-{
-	if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
-	{
-		U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
-		if (transfer_index >= sOohPowerTransfers)
-		{
-		   transfer_index = sOohPowerTransfers - 1;
-		}
-		F32 transfer_ooh = sOohPowerTransfer[transfer_index];
-
-		transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
-		if (transfer_index >= sAahPowerTransfers)
-		{
-		   transfer_index = sAahPowerTransfers - 1;
-		}
-		F32 transfer_aah = sAahPowerTransfer[transfer_index];
-
-		F64 current_time   = mTimer.getTotalSeconds();
-		F64 elapsed_time   = current_time - mStartTime;
-		U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
-		U32 elapsed_oohs   = elapsed_frames % sOohs;
-		U32 elapsed_aahs   = elapsed_frames % sAahs;
-
-		ooh = transfer_ooh * sOoh[elapsed_oohs];
-		aah = transfer_aah * sAah[elapsed_aahs];
-
-		/*
-		llinfos << " elapsed frames " << elapsed_frames
-				<< " ooh "            << ooh
-				<< " aah "            << aah
-				<< " transfer ooh"    << transfer_ooh
-				<< " transfer aah"    << transfer_aah
-				<< " start time "     << mStartTime
-				<< " current time "   << current_time
-				<< " elapsed time "   << elapsed_time
-				<< " elapsed oohs "   << elapsed_oohs
-				<< " elapsed aahs "   << elapsed_aahs
-				<< llendl;
-		*/
-	}
-	else
-	{
-		ooh = 0.0f;
-		aah = 0.0f;
-	}
-	
-}//---------------------------------------------------
-
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//---------------------------------------------------
-// this method is inherited from HUD Effect
-//---------------------------------------------------
-void LLVoiceVisualizer::render()
-{
-	if ( ! mVoiceEnabled )
-	{
-		return;
-	}
-	
-	if ( mSoundSymbol.mActive ) 
-	{				
-		mPreviousTime = mCurrentTime;
-		mCurrentTime = mTimer.getTotalSeconds();
-	
-		//---------------------------------------------------------------
-		// set the sound symbol position over the source (avatar's head)
-		//---------------------------------------------------------------
-		mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
-	
-		//---------------------------------------------------------------
-		// some gl state
-		//---------------------------------------------------------------
-		LLGLSPipelineAlpha alpha_blend;
-		LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-		
-		//-------------------------------------------------------------
-		// create coordinates of the geometry for the dot
-		//-------------------------------------------------------------
-		LLViewerCamera* camera = LLViewerCamera::getInstance();
-		LLVector3 l	= camera->getLeftAxis() * DOT_SIZE;
-		LLVector3 u	= camera->getUpAxis()   * DOT_SIZE;
-
-		LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
-		LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
-		LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
-		LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
-		
-		//-----------------------------
-		// bind texture 0 (the dot)
-		//-----------------------------
-		gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
-		
-		//-------------------------------------------------------------
-		// now render the dot
-		//-------------------------------------------------------------
-		gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );	
-		
-		gGL.begin( LLRender::TRIANGLE_STRIP );
-			gGL.texCoord2i( 0,	0	); gGL.vertex3fv( bottomLeft.mV );
-			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
-			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
-		gGL.end();
-
-		gGL.begin( LLRender::TRIANGLE_STRIP );
-			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
-			gGL.texCoord2i( 1,	1	); gGL.vertex3fv( topRight.mV );
-			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
-		gGL.end();
-		
-		
-		
-		//--------------------------------------------------------------------------------------
-		// if currently speaking, trigger waves (1 through 6) based on speaking amplitude
-		//--------------------------------------------------------------------------------------
-		if ( mCurrentlySpeaking )
-		{
-			F32 min = 0.2f;
-			F32 max = 0.7f;
-			F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
-		
-			// in case mSpeakingAmplitude > max....
-			if ( fraction > 1.0f )
-			{
-				fraction = 1.0f;
-			}
-														
-			S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
-																										
-			for (int i=0; i<level+1; i++)
-			{
-				mSoundSymbol.mWaveActive			[i] = true;
-				mSoundSymbol.mWaveOpacity			[i] = 1.0f;
-				mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
-			}			
-			
-		} // if currently speaking
-								
-		//---------------------------------------------------
-		// determine color
-		//---------------------------------------------------
-		F32 red		= 0.0f;
-		F32 green	= 0.0f;
-		F32 blue	= 0.0f;
-        if ( mSpeakingAmplitude < RED_THRESHOLD )
-        {
-			if ( mSpeakingAmplitude < GREEN_THRESHOLD )
-			{
-				red		= BASE_BRIGHTNESS;
-				green	= BASE_BRIGHTNESS;
-				blue	= BASE_BRIGHTNESS;
-			}
-			else
-			{
-				//---------------------------------------------------
-				// fade from gray to bright green
-				//---------------------------------------------------
-				F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
-				red		= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
-				green	= BASE_BRIGHTNESS +   fraction * ( 1.0f - BASE_BRIGHTNESS );
-				blue	= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
-			}
-        }
-        else
-        {
-			//---------------------------------------------------
-			// redish
-			//---------------------------------------------------
-			red		= 1.0f;
-			green	= 0.2f;
-			blue	= 0.2f;
-        }
-														
-		for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
-		{
-			if ( mSoundSymbol.mWaveActive[i] ) 
-			{
-				F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
-
-				mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
-				
-				if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
-				{
-					mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
-					mSoundSymbol.mWaveOpacity			[i] = 0.0f;
-					mSoundSymbol.mWaveActive			[i] = false;
-				}
-				
-				//----------------------------------------------------------------------------------
-				// This is where we calculate the expansion of the waves - that is, the
-				// rate at which they are scaled greater than 1.0 so that they grow over time.
-				//----------------------------------------------------------------------------------
-				F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
-				F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
-				mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
-				
-				if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
-				{
-					mSoundSymbol.mWaveExpansion[i] = 1.0f;
-				}			
-								
-				//----------------------------------------------------------------------------------
-				// create geometry for the wave billboard textures
-				//----------------------------------------------------------------------------------
-				F32 width	= i * WAVE_WIDTH_SCALE  * mSoundSymbol.mWaveExpansion[i];
-				F32 height	= i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
-
-				LLVector3 l	= camera->getLeftAxis() * width;
-				LLVector3 u	= camera->getUpAxis()   * height;
-
-				LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
-				LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
-				LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
-				LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
-							
-				gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );		
-				gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
-
-				
-				//---------------------------------------------------
-				// now, render the mofo
-				//---------------------------------------------------
-				gGL.begin( LLRender::TRIANGLE_STRIP );
-					gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
-					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
-					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
-				gGL.end();
-
-				gGL.begin( LLRender::TRIANGLE_STRIP );
-					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
-					gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
-					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
-				gGL.end();
-				
-			} //if ( mSoundSymbol.mWaveActive[i] ) 
-			
-		}// for loop
-											
-	}//if ( mSoundSymbol.mActive ) 
-
-}//---------------------------------------------------
-
-//---------------------------------------------------
-void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
-{
-	mVoiceSourceWorldPosition	= p;
-
-}//---------------------------------------------------
-#endif // XXX_STINSON_CHUI_REWORK
-
-//---------------------------------------------------
-VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
-{
-	VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
-	
-	//-----------------------------------------------------------------------------------------
-	// Within the range of gesticulation amplitudes, the sound signal is split into
-	// three equal amplitude regimes, each specifying one of three gesticulation levels.
-	//-----------------------------------------------------------------------------------------
-	F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
-	
-			if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH;		}
-	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM;	}
-	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW;		}
-
-	return gesticulationLevel;
-
-}//---------------------------------------------------
-
-
-
-//------------------------------------
-// Destructor
-//------------------------------------
-LLVoiceVisualizer::~LLVoiceVisualizer()
-{
-}//----------------------------------------------
-
-
-#ifdef XXX_STINSON_CHUI_REWORK
-//---------------------------------------------------
-// "packData" is inherited from HUDEffect
-//---------------------------------------------------
-void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
-{
-	// Pack the default data
-	LLHUDEffect::packData(mesgsys);
-
-	// TODO -- pack the relevant data for voice effects
-	// we'll come up with some cool configurations....TBD
-	//U8 packed_data[41];
-	//mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
-	U8 packed_data = 0;
-	mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
-}
-
-
-//---------------------------------------------------
-// "unpackData" is inherited from HUDEffect
-//---------------------------------------------------
-void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
-{
-	// TODO -- find the speaker, unpack binary data, set the properties of this effect
-	/*
-	LLHUDEffect::unpackData(mesgsys, blocknum);
-	LLUUID source_id;
-	LLUUID target_id;
-	S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
-	if (size != 1)
-	{
-		llwarns << "Voice effect with bad size " << size << llendl;
-		return;
-	}
-	mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
-	*/
-}
-
-
-//------------------------------------------------------------------
-// this method is inherited from HUD Effect
-//------------------------------------------------------------------
-void LLVoiceVisualizer::markDead()
-{
-	mCurrentlySpeaking		= false;
-	mVoiceEnabled			= false;
-	mSoundSymbol.mActive	= false;
-
-	LLHUDEffect::markDead();
-}//------------------------------------------------------------------
-
-#endif // XXX_STINSON_CHUI_REWORK
+/** 
+ * @file llvoicevisualizer.cpp
+ * @brief Draws in-world speaking indicators.
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+//----------------------------------------------------------------------
+// Voice Visualizer
+// author: JJ Ventrella
+// (information about this stuff can be found in "llvoicevisualizer.h")
+//----------------------------------------------------------------------
+#include "llviewerprecompiledheaders.h"
+#include "llviewercontrol.h"
+#include "llglheaders.h"
+#include "llsphere.h"
+#include "llvoicevisualizer.h"
+#include "llviewercamera.h"
+#include "llviewerobject.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+#include "llvoiceclient.h"
+#include "llrender.h"
+
+//brent's wave image
+//29de489d-0491-fb00-7dab-f9e686d31e83
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//--------------------------------------------------------------------------------------
+// sound symbol constants
+//--------------------------------------------------------------------------------------
+const F32	HEIGHT_ABOVE_HEAD	= 0.3f;		// how many meters vertically above the av's head the voice symbol will appear
+const F32	RED_THRESHOLD		= LLVoiceClient::OVERDRIVEN_POWER_LEVEL;		// value above which speaking amplitude causes the voice symbol to turn red
+const F32	GREEN_THRESHOLD		= 0.2f;		// value above which speaking amplitude causes the voice symbol to turn green
+const F32	FADE_OUT_DURATION	= 0.4f;		// how many seconds it takes for a pair of waves to fade away
+const F32	EXPANSION_RATE		= 1.0f;		// how many seconds it takes for the waves to expand to twice their original size
+const F32	EXPANSION_MAX		= 1.5f;		// maximum size scale to which the waves can expand before popping back to 1.0 
+const F32	WAVE_WIDTH_SCALE	= 0.03f;	// base width of the waves 
+const F32	WAVE_HEIGHT_SCALE	= 0.02f;	// base height of the waves 
+const F32	BASE_BRIGHTNESS		= 0.7f;		// gray level of the voice indicator when quiet (below green threshold)
+const F32	DOT_SIZE			= 0.05f;	// size of the dot billboard texture
+const F32	DOT_OPACITY			= 0.7f;		// how opaque the dot is
+const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a function of speaking amplitude
+#endif // XXX_STINSON_CHUI_REWORK
+
+//--------------------------------------------------------------------------------------
+// gesticulation constants
+//--------------------------------------------------------------------------------------
+const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE	= 0.2f; 
+const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f;
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//--------------------------------------------------------------------------------------
+// other constants
+//--------------------------------------------------------------------------------------
+const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. 
+const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
+#endif // XXX_STINSON_CHUI_REWORK
+
+//------------------------------------------------------------------
+// Initialize the statics
+//------------------------------------------------------------------
+bool LLVoiceVisualizer::sPrefsInitialized	= false;
+BOOL LLVoiceVisualizer::sLipSyncEnabled		= FALSE;
+F32* LLVoiceVisualizer::sOoh				= NULL;
+F32* LLVoiceVisualizer::sAah				= NULL;
+U32	 LLVoiceVisualizer::sOohs				= 0;
+U32	 LLVoiceVisualizer::sAahs				= 0;
+F32	 LLVoiceVisualizer::sOohAahRate			= 0.0f;
+F32* LLVoiceVisualizer::sOohPowerTransfer	= NULL;
+U32	 LLVoiceVisualizer::sOohPowerTransfers	= 0;
+F32	 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
+F32* LLVoiceVisualizer::sAahPowerTransfer	= NULL;
+U32	 LLVoiceVisualizer::sAahPowerTransfers	= 0;
+F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
+
+
+//-----------------------------------------------
+// constructor
+//-----------------------------------------------
+#ifdef XXX_STINSON_CHUI_REWORK
+LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
+	: LLHUDEffect(type)
+#else // XXX_STINSON_CHUI_REWORK
+LLVoiceVisualizer::LLVoiceVisualizer()
+	: LLRefCount(),
+	mTimer(),
+	mStartTime(0.0),
+	mCurrentlySpeaking(false),
+	mSpeakingAmplitude(0.0f),
+	mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE),
+	mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE)
+#endif // XXX_STINSON_CHUI_REWORK
+{
+#ifdef XXX_STINSON_CHUI_REWORK
+	mCurrentTime					= mTimer.getTotalSeconds();
+	mPreviousTime					= mCurrentTime;
+	mStartTime						= mCurrentTime;
+#else // XXX_STINSON_CHUI_REWORK
+	mStartTime						= mTimer.getTotalSeconds();
+#endif // XXX_STINSON_CHUI_REWORK
+#ifdef XXX_STINSON_CHUI_REWORK
+	mVoiceSourceWorldPosition		= LLVector3( 0.0f, 0.0f, 0.0f );
+	mSpeakingAmplitude				= 0.0f;
+	mCurrentlySpeaking				= false;
+	mVoiceEnabled					= false;
+	mMinGesticulationAmplitude		= DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
+	mMaxGesticulationAmplitude		= DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
+	mSoundSymbol.mActive			= true;
+	mSoundSymbol.mPosition			= LLVector3( 0.0f, 0.0f, 0.0f );
+#endif // XXX_STINSON_CHUI_REWORK
+	
+	mTimer.reset();
+	
+#ifdef XXX_STINSON_CHUI_REWORK
+	const char* sound_level_img[] = 
+	{
+		"voice_meter_dot.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c",
+		"voice_meter_rings.j2c"
+	};
+
+	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
+	{
+		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
+		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
+		mSoundSymbol.mWaveActive			[i] = false;
+		mSoundSymbol.mWaveOpacity			[i] = 1.0f;
+		mSoundSymbol.mWaveExpansion			[i] = 1.0f;
+	}
+
+	mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+#endif // XXX_STINSON_CHUI_REWORK
+
+	// The first instance loads the initial state from prefs.
+	if (!sPrefsInitialized)
+	{
+		setPreferences();
+       
+		// Set up our listener to get updates on all prefs values we care about.
+		gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		
+		sPrefsInitialized = true;
+	}
+
+}//---------------------------------------------------
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
+{
+	mMinGesticulationAmplitude = m;
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
+{
+	mMaxGesticulationAmplitude = m;
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setVoiceEnabled( bool v )
+{
+	mVoiceEnabled = v;
+
+}//---------------------------------------------------
+#endif // XXX_STINSON_CHUI_REWORK
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setStartSpeaking()
+{
+	mStartTime				= mTimer.getTotalSeconds();
+	mCurrentlySpeaking		= true;
+#ifdef XXX_STINSON_CHUI_REWORK
+	mSoundSymbol.mActive	= true;
+#endif // XXX_STINSON_CHUI_REWORK
+		
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+bool LLVoiceVisualizer::getCurrentlySpeaking()
+{
+	return mCurrentlySpeaking;
+	
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setStopSpeaking()
+{
+	mCurrentlySpeaking = false;
+	mSpeakingAmplitude = 0.0f;
+	
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
+{
+	mSpeakingAmplitude = a;
+	
+}//---------------------------------------------------
+
+//------------------------------------------------------------------
+// handles parameter updates
+//------------------------------------------------------------------
+bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
+{
+	// Note: Ignore the specific event value, we look up the ones we want
+	LLVoiceVisualizer::setPreferences();
+	return true;
+}
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setPreferences( )
+{
+	sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
+	sOohAahRate		= gSavedSettings.getF32("LipSyncOohAahRate");
+
+	std::string oohString = gSavedSettings.getString("LipSyncOoh");
+	lipStringToF32s (oohString, sOoh, sOohs);
+
+	std::string aahString = gSavedSettings.getString("LipSyncAah");
+	lipStringToF32s (aahString, sAah, sAahs);
+
+	std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
+	lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
+	sOohPowerTransfersf = (F32) sOohPowerTransfers;
+
+	std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
+	lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
+	sAahPowerTransfersf = (F32) sAahPowerTransfers;
+
+}//---------------------------------------------------
+
+
+//---------------------------------------------------
+// convert a string of digits to an array of floats.
+// the result for each digit is the value of the
+// digit multiplied by 0.11
+//---------------------------------------------------
+void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
+{
+	delete[] out_F32s;	// get rid of the current array
+
+	count_F32s = in_string.length();
+	if (count_F32s == 0)
+	{
+		// we don't like zero length arrays
+
+		count_F32s  = 1;
+		out_F32s	   = new F32[1];
+		out_F32s[0] = 0.0f;
+	}
+	else
+	{
+		out_F32s = new F32[count_F32s];
+
+		for (U32 i=0; i<count_F32s; i++)
+		{
+			// we convert the characters 0 to 9 to their numeric value
+			// anything else we take the low order four bits with a ceiling of 9
+
+		    U8 digit = in_string[i];
+			U8 four_bits = digit % 16;
+			if (four_bits > 9)
+			{
+				four_bits = 9;
+			}
+			out_F32s[i] = 0.11f * (F32) four_bits;
+		} 
+	}
+
+}//---------------------------------------------------
+
+
+//--------------------------------------------------------------------------
+// find the amount to blend the ooh and aah mouth morphs
+//--------------------------------------------------------------------------
+void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
+{
+	if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
+	{
+		U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
+		if (transfer_index >= sOohPowerTransfers)
+		{
+		   transfer_index = sOohPowerTransfers - 1;
+		}
+		F32 transfer_ooh = sOohPowerTransfer[transfer_index];
+
+		transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
+		if (transfer_index >= sAahPowerTransfers)
+		{
+		   transfer_index = sAahPowerTransfers - 1;
+		}
+		F32 transfer_aah = sAahPowerTransfer[transfer_index];
+
+		F64 current_time   = mTimer.getTotalSeconds();
+		F64 elapsed_time   = current_time - mStartTime;
+		U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
+		U32 elapsed_oohs   = elapsed_frames % sOohs;
+		U32 elapsed_aahs   = elapsed_frames % sAahs;
+
+		ooh = transfer_ooh * sOoh[elapsed_oohs];
+		aah = transfer_aah * sAah[elapsed_aahs];
+
+		/*
+		llinfos << " elapsed frames " << elapsed_frames
+				<< " ooh "            << ooh
+				<< " aah "            << aah
+				<< " transfer ooh"    << transfer_ooh
+				<< " transfer aah"    << transfer_aah
+				<< " start time "     << mStartTime
+				<< " current time "   << current_time
+				<< " elapsed time "   << elapsed_time
+				<< " elapsed oohs "   << elapsed_oohs
+				<< " elapsed aahs "   << elapsed_aahs
+				<< llendl;
+		*/
+	}
+	else
+	{
+		ooh = 0.0f;
+		aah = 0.0f;
+	}
+	
+}//---------------------------------------------------
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+// this method is inherited from HUD Effect
+//---------------------------------------------------
+void LLVoiceVisualizer::render()
+{
+	if ( ! mVoiceEnabled )
+	{
+		return;
+	}
+	
+	if ( mSoundSymbol.mActive ) 
+	{				
+		mPreviousTime = mCurrentTime;
+		mCurrentTime = mTimer.getTotalSeconds();
+	
+		//---------------------------------------------------------------
+		// set the sound symbol position over the source (avatar's head)
+		//---------------------------------------------------------------
+		mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
+	
+		//---------------------------------------------------------------
+		// some gl state
+		//---------------------------------------------------------------
+		LLGLSPipelineAlpha alpha_blend;
+		LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+		
+		//-------------------------------------------------------------
+		// create coordinates of the geometry for the dot
+		//-------------------------------------------------------------
+		LLViewerCamera* camera = LLViewerCamera::getInstance();
+		LLVector3 l	= camera->getLeftAxis() * DOT_SIZE;
+		LLVector3 u	= camera->getUpAxis()   * DOT_SIZE;
+
+		LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
+		LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
+		LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
+		LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
+		
+		//-----------------------------
+		// bind texture 0 (the dot)
+		//-----------------------------
+		gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
+		
+		//-------------------------------------------------------------
+		// now render the dot
+		//-------------------------------------------------------------
+		gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );	
+		
+		gGL.begin( LLRender::TRIANGLE_STRIP );
+			gGL.texCoord2i( 0,	0	); gGL.vertex3fv( bottomLeft.mV );
+			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
+			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
+		gGL.end();
+
+		gGL.begin( LLRender::TRIANGLE_STRIP );
+			gGL.texCoord2i( 1,	0	); gGL.vertex3fv( bottomRight.mV );
+			gGL.texCoord2i( 1,	1	); gGL.vertex3fv( topRight.mV );
+			gGL.texCoord2i( 0,	1	); gGL.vertex3fv( topLeft.mV );
+		gGL.end();
+		
+		
+		
+		//--------------------------------------------------------------------------------------
+		// if currently speaking, trigger waves (1 through 6) based on speaking amplitude
+		//--------------------------------------------------------------------------------------
+		if ( mCurrentlySpeaking )
+		{
+			F32 min = 0.2f;
+			F32 max = 0.7f;
+			F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
+		
+			// in case mSpeakingAmplitude > max....
+			if ( fraction > 1.0f )
+			{
+				fraction = 1.0f;
+			}
+														
+			S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
+																										
+			for (int i=0; i<level+1; i++)
+			{
+				mSoundSymbol.mWaveActive			[i] = true;
+				mSoundSymbol.mWaveOpacity			[i] = 1.0f;
+				mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
+			}			
+			
+		} // if currently speaking
+								
+		//---------------------------------------------------
+		// determine color
+		//---------------------------------------------------
+		F32 red		= 0.0f;
+		F32 green	= 0.0f;
+		F32 blue	= 0.0f;
+        if ( mSpeakingAmplitude < RED_THRESHOLD )
+        {
+			if ( mSpeakingAmplitude < GREEN_THRESHOLD )
+			{
+				red		= BASE_BRIGHTNESS;
+				green	= BASE_BRIGHTNESS;
+				blue	= BASE_BRIGHTNESS;
+			}
+			else
+			{
+				//---------------------------------------------------
+				// fade from gray to bright green
+				//---------------------------------------------------
+				F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
+				red		= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
+				green	= BASE_BRIGHTNESS +   fraction * ( 1.0f - BASE_BRIGHTNESS );
+				blue	= BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
+			}
+        }
+        else
+        {
+			//---------------------------------------------------
+			// redish
+			//---------------------------------------------------
+			red		= 1.0f;
+			green	= 0.2f;
+			blue	= 0.2f;
+        }
+														
+		for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
+		{
+			if ( mSoundSymbol.mWaveActive[i] ) 
+			{
+				F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
+
+				mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
+				
+				if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
+				{
+					mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
+					mSoundSymbol.mWaveOpacity			[i] = 0.0f;
+					mSoundSymbol.mWaveActive			[i] = false;
+				}
+				
+				//----------------------------------------------------------------------------------
+				// This is where we calculate the expansion of the waves - that is, the
+				// rate at which they are scaled greater than 1.0 so that they grow over time.
+				//----------------------------------------------------------------------------------
+				F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
+				F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
+				mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
+				
+				if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
+				{
+					mSoundSymbol.mWaveExpansion[i] = 1.0f;
+				}			
+								
+				//----------------------------------------------------------------------------------
+				// create geometry for the wave billboard textures
+				//----------------------------------------------------------------------------------
+				F32 width	= i * WAVE_WIDTH_SCALE  * mSoundSymbol.mWaveExpansion[i];
+				F32 height	= i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
+
+				LLVector3 l	= camera->getLeftAxis() * width;
+				LLVector3 u	= camera->getUpAxis()   * height;
+
+				LLVector3 bottomLeft	= mSoundSymbol.mPosition + l - u;
+				LLVector3 bottomRight	= mSoundSymbol.mPosition - l - u;
+				LLVector3 topLeft		= mSoundSymbol.mPosition + l + u;
+				LLVector3 topRight		= mSoundSymbol.mPosition - l + u;
+							
+				gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );		
+				gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
+
+				
+				//---------------------------------------------------
+				// now, render the mofo
+				//---------------------------------------------------
+				gGL.begin( LLRender::TRIANGLE_STRIP );
+					gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
+					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
+					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
+				gGL.end();
+
+				gGL.begin( LLRender::TRIANGLE_STRIP );
+					gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
+					gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
+					gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
+				gGL.end();
+				
+			} //if ( mSoundSymbol.mWaveActive[i] ) 
+			
+		}// for loop
+											
+	}//if ( mSoundSymbol.mActive ) 
+
+}//---------------------------------------------------
+
+//---------------------------------------------------
+void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
+{
+	mVoiceSourceWorldPosition	= p;
+
+}//---------------------------------------------------
+#endif // XXX_STINSON_CHUI_REWORK
+
+//---------------------------------------------------
+VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
+{
+	VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
+	
+	//-----------------------------------------------------------------------------------------
+	// Within the range of gesticulation amplitudes, the sound signal is split into
+	// three equal amplitude regimes, each specifying one of three gesticulation levels.
+	//-----------------------------------------------------------------------------------------
+	F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
+	
+			if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH;		}
+	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM;	}
+	else	if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f	)	{ gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW;		}
+
+	return gesticulationLevel;
+
+}//---------------------------------------------------
+
+
+
+//------------------------------------
+// Destructor
+//------------------------------------
+LLVoiceVisualizer::~LLVoiceVisualizer()
+{
+}//----------------------------------------------
+
+
+#ifdef XXX_STINSON_CHUI_REWORK
+//---------------------------------------------------
+// "packData" is inherited from HUDEffect
+//---------------------------------------------------
+void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
+{
+	// Pack the default data
+	LLHUDEffect::packData(mesgsys);
+
+	// TODO -- pack the relevant data for voice effects
+	// we'll come up with some cool configurations....TBD
+	//U8 packed_data[41];
+	//mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
+	U8 packed_data = 0;
+	mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
+}
+
+
+//---------------------------------------------------
+// "unpackData" is inherited from HUDEffect
+//---------------------------------------------------
+void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
+{
+	// TODO -- find the speaker, unpack binary data, set the properties of this effect
+	/*
+	LLHUDEffect::unpackData(mesgsys, blocknum);
+	LLUUID source_id;
+	LLUUID target_id;
+	S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
+	if (size != 1)
+	{
+		llwarns << "Voice effect with bad size " << size << llendl;
+		return;
+	}
+	mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
+	*/
+}
+
+
+//------------------------------------------------------------------
+// this method is inherited from HUD Effect
+//------------------------------------------------------------------
+void LLVoiceVisualizer::markDead()
+{
+	mCurrentlySpeaking		= false;
+	mVoiceEnabled			= false;
+	mSoundSymbol.mActive	= false;
+
+	LLHUDEffect::markDead();
+}//------------------------------------------------------------------
+
+#endif // XXX_STINSON_CHUI_REWORK
diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h
index 6258de163d..5da592c48e 100644
--- a/indra/newview/llvoicevisualizer.h
+++ b/indra/newview/llvoicevisualizer.h
@@ -42,6 +42,7 @@
 #ifndef LL_VOICE_VISUALIZER_H
 #define LL_VOICE_VISUALIZER_H
 
+#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
 #ifdef XXX_STINSON_CHUI_REWORK
 #include "llhudeffect.h"
 #else // XXX_STINSON_CHUI_REWORK
-- 
cgit v1.2.3


From faac868b682360df1bf461624667cc6e0bbdd8c6 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 2 Aug 2012 20:45:52 -0700
Subject: CHUI-223 FIX Selecting to cut an inventory item causes all open
 inventory windows to refresh

---
 indra/llui/llfolderview.cpp        | 95 +++++++++++++-------------------------
 indra/llui/llfolderview.h          | 10 ++--
 indra/newview/llinventorypanel.cpp | 22 +++++++--
 3 files changed, 56 insertions(+), 71 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 5d98dc9663..fb09f7f0aa 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -749,28 +749,18 @@ void LLFolderView::removeSelectedItems()
 		// iterate through the new container.
 		count = items.size();
 		LLUUID new_selection_id;
+		LLFolderViewItem* item_to_select = getNextUnselectedItem();
+
 		if(count == 1)
 		{
 			LLFolderViewItem* item_to_delete = items[0];
 			LLFolderViewFolder* parent = item_to_delete->getParentFolder();
-			LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE);
-			if (!new_selection)
-			{
-				new_selection = item_to_delete->getPreviousOpenNode(FALSE);
-			}
 			if(parent)
 			{
 				if (item_to_delete->remove())
 				{
 					// change selection on successful delete
-					if (new_selection)
-					{
-						getRoot()->setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
-					}
-					else
-					{
-						getRoot()->setSelection(NULL, mParentPanel->hasFocus());
-					}
+					setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
 				}
 			}
 			arrangeAll();
@@ -779,28 +769,8 @@ void LLFolderView::removeSelectedItems()
 		{
 			LLDynamicArray<LLFolderViewModelItem*> listeners;
 			LLFolderViewModelItem* listener;
-			LLFolderViewItem* last_item = items[count - 1];
-			LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
-			while(new_selection && new_selection->isSelected())
-			{
-				new_selection = new_selection->getNextOpenNode(FALSE);
-			}
-			if (!new_selection)
-			{
-				new_selection = last_item->getPreviousOpenNode(FALSE);
-				while (new_selection && (new_selection->isInSelection()))
-				{
-					new_selection = new_selection->getPreviousOpenNode(FALSE);
-				}
-			}
-			if (new_selection)
-			{
-				getRoot()->setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
-			}
-			else
-			{
-				getRoot()->setSelection(NULL, mParentPanel->hasFocus());
-			}
+
+			setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
 
 			for(S32 i = 0; i < count; ++i)
 			{
@@ -1032,28 +1002,13 @@ void LLFolderView::cut()
 	S32 count = mSelectedItems.size();
 	if(getVisible() && getEnabled() && (count > 0))
 	{
-		LLFolderViewModelItem* listener = NULL;
-
-		LLFolderViewItem* last_item = *mSelectedItems.rbegin();;
-		LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
-		while(new_selection && new_selection->isSelected())
-		{
-			new_selection = new_selection->getNextOpenNode(FALSE);
-		}
-		if (!new_selection)
-		{
-			new_selection = last_item->getPreviousOpenNode(FALSE);
-			while (new_selection && (new_selection->isInSelection()))
-			{
-				new_selection = new_selection->getPreviousOpenNode(FALSE);
-			}
-		}
+		LLFolderViewItem* item_to_select = getNextUnselectedItem();
 
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
 			LLFolderViewItem* item_to_cut = *item_it;
-			listener = item_to_cut->getViewModelItem();
+			LLFolderViewModelItem* listener = item_to_cut->getViewModelItem();
 			if(listener)
 			{
 				listener->cutToClipboard();
@@ -1061,14 +1016,7 @@ void LLFolderView::cut()
 			}
 		}
 
-		if (new_selection)
-		{
-			setSelection(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
-		}
-		else
-		{
-			setSelection(NULL, mParentPanel->hasFocus());
-		}
+		setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
 	}
 	mSearchString.clear();
 }
@@ -1274,12 +1222,12 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 					if (next->isSelected())
 					{
 						// shrink selection
-						getRoot()->changeSelection(last_selected, FALSE);
+						changeSelection(last_selected, FALSE);
 					}
 					else if (last_selected->getParentFolder() == next->getParentFolder())
 					{
 						// grow selection
-						getRoot()->changeSelection(next, TRUE);
+						changeSelection(next, TRUE);
 					}
 				}
 			}
@@ -1338,12 +1286,12 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 					if (prev->isSelected())
 					{
 						// shrink selection
-						getRoot()->changeSelection(last_selected, FALSE);
+						changeSelection(last_selected, FALSE);
 					}
 					else if (last_selected->getParentFolder() == prev->getParentFolder())
 					{
 						// grow selection
-						getRoot()->changeSelection(prev, TRUE);
+						changeSelection(prev, TRUE);
 					}
 				}
 			}
@@ -2083,3 +2031,22 @@ S32 LLFolderView::getItemHeight()
 	}
 	return 0;
 }
+
+LLFolderViewItem* LLFolderView::getNextUnselectedItem()
+{
+	LLFolderViewItem* last_item = *mSelectedItems.rbegin();
+	LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
+	while(new_selection && new_selection->isSelected())
+	{
+		new_selection = new_selection->getNextOpenNode(FALSE);
+	}
+	if (!new_selection)
+	{
+		new_selection = last_item->getPreviousOpenNode(FALSE);
+		while (new_selection && (new_selection->isInSelection()))
+		{
+			new_selection = new_selection->getPreviousOpenNode(FALSE);
+		}
+	}
+	return new_selection;
+}
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 05beff9bd8..81b0f087e8 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -172,17 +172,19 @@ public:
 	BOOL isOpen() const { return TRUE; } // root folder always open
 
 	// Copy & paste
-	virtual void	copy();
 	virtual BOOL	canCopy() const;
+	virtual void	copy();
 
-	virtual void	cut();
 	virtual BOOL	canCut() const;
+	virtual void	cut();
 
-	virtual void	paste();
 	virtual BOOL	canPaste() const;
+	virtual void	paste();
 
-	virtual void	doDelete();
 	virtual BOOL	canDoDelete() const;
+	virtual void	doDelete();
+
+	LLFolderViewItem* getNextUnselectedItem();
 
 	// Public rename functionality - can only start the process
 	void startRenamingSelectedItem( void );
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 9403ccdabe..b02d08955f 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -604,9 +604,25 @@ void LLInventoryPanel::idle(void* user_data)
 	if (panel->mClipboardState != LLClipboard::instance().getGeneration())
 	{
 		panel->mClipboardState = LLClipboard::instance().getGeneration();
-		panel->getFilter().setModified(LLClipboard::instance().isCutMode() 
-										? LLInventoryFilter::FILTER_MORE_RESTRICTIVE 
-										: LLInventoryFilter::FILTER_LESS_RESTRICTIVE);
+		if (LLClipboard::instance().isCutMode())
+		{
+			LLDynamicArray<LLUUID> objects;
+			LLClipboard::instance().pasteFromClipboard(objects);
+
+			for (LLDynamicArray<LLUUID>::iterator it = objects.begin(), end_it = objects.end();
+				it != end_it;
+				++it)
+			{
+				LLFolderViewItem* item = panel->getItemByID(*it);
+				if (item)
+				{
+					item->getViewModelItem()->dirtyFilter();
+				}
+			}
+			/*panel->getFilter().setModified(LLClipboard::instance().isCutMode() 
+			? LLInventoryFilter::FILTER_MORE_RESTRICTIVE 
+			: LLInventoryFilter::FILTER_LESS_RESTRICTIVE);*/
+		}
 	}
 
 	panel->mFolderRoot->update();
-- 
cgit v1.2.3


From 291e78732374f428e43bb6bf5967ed3a114d0f18 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 3 Aug 2012 11:56:19 -0700
Subject: CHUI-265: Problem was that the each accordian tab was using the
 llinvetorypanel object to display contents. The llinventorypanel was designed
 by default to use a scrollbar horizontally/vertically, just like in the
 inventory floater. Resolution: Now set a flag to hide the scrollbar for each
 accordian tab.

---
 indra/newview/skins/default/xui/en/panel_landmarks.xml | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index 39805637a0..ebd4c6a805 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -35,6 +35,7 @@
              left="0"
              mouse_opaque="true"
              name="favorites_list"
+             scroll.hide_scrollbar="true"
              start_folder.name="Favorites"
              width="307"/>
         </accordion_tab>
@@ -51,6 +52,7 @@
              left="0"
              mouse_opaque="true"
              name="landmarks_list"
+             scroll.hide_scrollbar="true"
              start_folder.name="Landmarks"
              width="307"/>
         </accordion_tab>
@@ -67,6 +69,7 @@
              left="0"
              mouse_opaque="true"
              name="my_inventory_list"
+             scroll.hide_scrollbar="true"
              start_folder.name="My Inventory"
              width="307"/>
           </accordion_tab>
@@ -83,6 +86,7 @@
              left="0"
              mouse_opaque="true"
              name="library_list"
+             scroll.hide_scrollbar="true"
              start_folder.name="LIBRARY"
              width="313"/>
         </accordion_tab>
-- 
cgit v1.2.3


From d6d35d970f3a7b4db7e29f7d2eddb0c078cba4a5 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 3 Aug 2012 13:54:35 -0700
Subject: CHUI-263 : Fix crash on exit. LLSingleton like LLConversationLog
 cannot be an LLFriendObserver at the same time.

---
 indra/newview/llconversationlog.cpp | 38 +++++++++++++++++++++++++++----------
 indra/newview/llconversationlog.h   |  9 +++++----
 2 files changed, 33 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index df9350407d..137b97326c 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -139,6 +139,31 @@ void LLConversation::setListenIMFloaterOpened()
 		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
 	}
 }
+/************************************************************************/
+/*             LLConversationLogFriendObserver implementation           */
+/************************************************************************/
+
+// Note : An LLSingleton like LLConversationLog cannot be an LLFriendObserver 
+// at the same time.
+// This is because avatar observers are deleted by the observed object which 
+// conflicts with the way LLSingleton are deleted.
+
+class LLConversationLogFriendObserver : public LLFriendObserver
+{
+public:
+	LLConversationLogFriendObserver() {}
+	virtual ~LLConversationLogFriendObserver() {}
+	virtual void changed(U32 mask);
+};
+
+void LLConversationLogFriendObserver::changed(U32 mask)
+{
+	if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
+	{
+		LLConversationLog::instance().notifyObservers();
+	}
+}
+
 /************************************************************************/
 /*             LLConversationLog implementation                         */
 /************************************************************************/
@@ -148,7 +173,9 @@ LLConversationLog::LLConversationLog()
 	loadFromFile(getFileName());
 
 	LLIMMgr::instance().addSessionObserver(this);
-	LLAvatarTracker::instance().addObserver(this);
+	
+	mFriendObserver = new LLConversationLogFriendObserver;
+	LLAvatarTracker::instance().addObserver(mFriendObserver);
 }
 void LLConversationLog::logConversation(const LLConversation& conversation)
 {
@@ -204,15 +231,6 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
 	}
 }
 
-// LLFriendObserver
-void LLConversationLog::changed(U32 mask)
-{
-	if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
-	{
-		notifyObservers();
-	}
-}
-
 void LLConversationLog::cache()
 {
 	saveToFile(getFileName());
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 18865bb80e..a7457d55e3 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -99,7 +99,7 @@ private:
  * To distinguish two conversations with the same sessionID it's also needed to compare their creation date.
  */
 
-class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver, LLFriendObserver
+class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver
 {
 	friend class LLSingleton<LLConversationLog>;
 public:
@@ -126,8 +126,8 @@ public:
 	virtual void sessionRemoved(const LLUUID& session_id){}										// Stub
 	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){}	// Stub
 
-	// LLFriendObserver trigger
-	virtual void changed(U32 mask);
+	// Triggered by LLFriendObserver change
+	void notifyObservers();
 
 	/**
 	 * public method which is called on viewer exit to save conversation log
@@ -137,7 +137,6 @@ public:
 private:
 
 	LLConversationLog();
-	void notifyObservers();
 
 	/**
 	 * constructs file name in which conversations log will be saved
@@ -152,6 +151,8 @@ private:
 	typedef std::vector<LLConversation> conversations_vec_t;
 	std::vector<LLConversation>				mConversations;
 	std::set<LLConversationLogObserver*>	mObservers;
+
+	LLFriendObserver* mFriendObserver;		// Observer of the LLAvatarTracker instance
 };
 
 class LLConversationLogObserver
-- 
cgit v1.2.3


From af8d113557105075af0e010c560ba9846d812aa0 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 3 Aug 2012 15:23:08 -0700
Subject: CHUI-271 FIX Items that are cut and then removed from the clipboard
 without paste do not show in Trash until relog

---
 indra/llui/llfolderviewitem.h      | 96 ++++++++++++++++++--------------------
 indra/llui/llfolderviewmodel.cpp   | 15 ++++++
 indra/llui/llfolderviewmodel.h     |  6 +--
 indra/newview/llinventorypanel.cpp | 34 +++++++-------
 4 files changed, 80 insertions(+), 71 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index e75059bc01..6eacbe8bd0 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -46,9 +46,6 @@ class LLFolderViewModelInterface;
 class LLFolderViewItem : public LLView
 {
 public:
-	static void initClass();
-	static void cleanupClass();
-
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
 	{
 		Optional<LLUIImage*>						folder_arrow_image,
@@ -67,20 +64,17 @@ public:
 	};
 
 	// layout constants
-	static const S32 LEFT_PAD = 5;
-	// LEFT_INDENTATION is set via folder_indentation above
-	static const S32 ICON_PAD = 2;
-	static const S32 ICON_WIDTH = 16;
-	static const S32 TEXT_PAD = 1;
-	static const S32 TEXT_PAD_RIGHT = 4;
-	static const S32 ARROW_SIZE = 12;
-	static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
+	static const S32	LEFT_PAD = 5,
+						ICON_PAD = 2,
+						ICON_WIDTH = 16,
+						TEXT_PAD = 1,
+						TEXT_PAD_RIGHT = 4,
+						ARROW_SIZE = 12,
+						MAX_FOLDER_ITEM_OVERLAP = 2;
+	
 	// animation parameters
-	static const F32 FOLDER_CLOSE_TIME_CONSTANT;
-	static const F32 FOLDER_OPEN_TIME_CONSTANT;
-
-private:
-	BOOL						mIsSelected;
+	static const F32	FOLDER_CLOSE_TIME_CONSTANT,
+						FOLDER_OPEN_TIME_CONSTANT;
 
 protected:
 	friend class LLUICtrlFactory;
@@ -95,9 +89,9 @@ protected:
 	LLFolderViewModelItem*		mViewModelItem;
 	LLFontGL::StyleFlags		mLabelStyle;
 	std::string					mLabelSuffix;
-	LLUIImagePtr				mIcon;
-	LLUIImagePtr				mIconOpen;
-	LLUIImagePtr				mIconOverlay;
+	LLUIImagePtr				mIcon,
+								mIconOpen,
+								mIconOverlay;
 	S32							mIndentation;
 	S32							mItemHeight;
 	S32							mDragStartX,
@@ -105,12 +99,12 @@ protected:
 
 	F32							mControlLabelRotation;
 	LLFolderView*				mRoot;
-	bool						mHasVisibleChildren;
-	bool						mIsCurSelection;
-	bool						mDragAndDropTarget;
-	bool						mIsMouseOverTitle;
-	bool						mAllowOpen;
-	bool						mSelectPending;
+	bool						mHasVisibleChildren,
+								mIsCurSelection,
+								mDragAndDropTarget,
+								mIsMouseOverTitle,
+								mAllowOpen,
+								mSelectPending;
 
 	// this is an internal method used for adding items to folders. A
 	// no-op at this level, but reimplemented in derived classes.
@@ -119,7 +113,13 @@ protected:
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
+private:
+	BOOL						mIsSelected;
+
 public:
+	static void initClass();
+	static void cleanupClass();
+
 	BOOL postBuild();
 
 	virtual void openItem( void );
@@ -191,7 +191,6 @@ public:
 	// contents possible before the entire view has been constructed.
 	const std::string& getLabel() const { return mLabel; }
 
-
 	LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
 	const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
 
@@ -209,8 +208,7 @@ public:
 	// just rename the object.
 	void rename(const std::string& new_name);
 
-
-	// Show children (unfortunate that this is called "open")
+	// Show children
 	virtual void setOpen(BOOL open = TRUE) {};
 	virtual BOOL isOpen() const { return FALSE; }
 
@@ -238,10 +236,10 @@ public:
 	//	virtual void handleDropped();
 	virtual void draw();
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+									std::string& tooltip_msg);
 
 private:
 	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
@@ -262,7 +260,6 @@ protected:
 	friend class LLUICtrlFactory;
 
 public:
-
 	typedef std::list<LLFolderViewItem*> items_t;
 	typedef std::list<LLFolderViewFolder*> folders_t;
 
@@ -330,12 +327,6 @@ public:
 	// destroys this folder, and all children
 	virtual void destroyView();
 
-	// If this folder can be removed, remove all children that can be
-	// removed, return TRUE if this is empty after the operation and
-	// it's viewed folder object can be removed.
-	//virtual BOOL removeRecursively(BOOL single_item);
-	//virtual BOOL remove();
-
 	// extractItem() removes the specified item from the folder, but
 	// doesn't delete it.
 	virtual void extractItem( LLFolderViewItem* item );
@@ -366,16 +357,17 @@ public:
 
 	// special case if an object is dropped on the child.
 	BOOL handleDragAndDropFromChild(MASK mask,
-		BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
+									BOOL drop,
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+									std::string& tooltip_msg);
 
-	void applyFunctorRecursively(LLFolderViewFunctor& functor);
 
 	// Just apply this functor to the folder's immediate children.
 	void applyFunctorToChildren(LLFolderViewFunctor& functor);
+	// apply this functor to the folder's descendants.
+	void applyFunctorRecursively(LLFolderViewFunctor& functor);
 
 	virtual void openItem( void );
 
@@ -384,12 +376,14 @@ public:
 	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
 	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
 	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
-	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
-	BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
+	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, 
+									BOOL drop,
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+									std::string& tooltip_msg);
+	BOOL handleDragAndDropToThisFolder(MASK mask, 
+										BOOL drop,
 									   EDragAndDropType cargo_type,
 									   void* cargo_data,
 									   EAcceptance* accept,
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
index 6aa4a63edc..3593804554 100644
--- a/indra/llui/llfolderviewmodel.cpp
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -51,3 +51,18 @@ void LLFolderViewModelCommon::filter()
 	getFilter().setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
 	mFolderView->getViewModelItem()->filter(getFilter());
 }
+
+bool LLFolderViewModelItemCommon::hasFilterStringMatch()
+{
+	return mStringMatchOffsetFilter != std::string::npos;
+}
+
+std::string::size_type LLFolderViewModelItemCommon::getFilterStringOffset()
+{
+	return mStringMatchOffsetFilter;
+}
+
+std::string::size_type LLFolderViewModelItemCommon::getFilterStringSize()
+{
+	return mRootViewModel.getFilter().getFilterStringSize();
+}
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 9908e538a4..41660c6e1e 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -245,9 +245,9 @@ public:
 			mParent->dirtyFilter();
 		}	
 	}
-	bool hasFilterStringMatch() { return mStringMatchOffsetFilter != std::string::npos; }
-	std::string::size_type getFilterStringOffset() { return mStringMatchOffsetFilter; }
-	std::string::size_type getFilterStringSize() { return mStringFilterSize; }
+	bool hasFilterStringMatch();
+	std::string::size_type getFilterStringOffset();
+	std::string::size_type getFilterStringSize();
 	
 	virtual void addChild(LLFolderViewModelItem* child) 
 	{ 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index d6a685541f..49bc3aae0b 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -600,6 +600,18 @@ void LLInventoryPanel::onIdle(void *userdata)
 	}
 }
 
+struct DirtyFilterFunctor : public LLFolderViewFunctor
+{
+	/*virtual*/ void doFolder(LLFolderViewFolder* folder)
+	{
+		folder->getViewModelItem()->dirtyFilter();
+	}
+	/*virtual*/ void doItem(LLFolderViewItem* item)
+	{
+		item->getViewModelItem()->dirtyFilter();
+	}
+};
+
 void LLInventoryPanel::idle(void* user_data)
 {
 	LLInventoryPanel* panel = (LLInventoryPanel*)user_data;
@@ -607,25 +619,13 @@ void LLInventoryPanel::idle(void* user_data)
 	if (panel->mClipboardState != LLClipboard::instance().getGeneration())
 	{
 		panel->mClipboardState = LLClipboard::instance().getGeneration();
-		if (LLClipboard::instance().isCutMode())
+		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+		LLFolderViewFolder* trash_folder = panel->getFolderByID(trash_id);
+		if (trash_folder)
 		{
-			LLDynamicArray<LLUUID> objects;
-			LLClipboard::instance().pasteFromClipboard(objects);
-
-			for (LLDynamicArray<LLUUID>::iterator it = objects.begin(), end_it = objects.end();
-				it != end_it;
-				++it)
-			{
-				LLFolderViewItem* item = panel->getItemByID(*it);
-				if (item)
-				{
-					item->getViewModelItem()->dirtyFilter();
-				}
-			}
-			/*panel->getFilter().setModified(LLClipboard::instance().isCutMode() 
-			? LLInventoryFilter::FILTER_MORE_RESTRICTIVE 
-			: LLInventoryFilter::FILTER_LESS_RESTRICTIVE);*/
+			trash_folder->applyFunctorToChildren(DirtyFilterFunctor());
 		}
+
 	}
 
 	panel->mFolderRoot->update();
-- 
cgit v1.2.3


From a831cb5bee19357e4d71a7408492fcb58a9042ac Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 3 Aug 2012 15:56:12 -0700
Subject: CHUI-273 FIX Inventory filtering changes not showing when changes are
 selected

---
 indra/newview/llinventorypanel.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 49bc3aae0b..b217612ee7 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -340,6 +340,7 @@ void LLInventoryPanel::setSortOrder(U32 order)
 	if (order != getFolderViewModel()->getSorter().getSortOrder())
 	{
 		getFolderViewModel()->setSorter(sorter);
+		mFolderRoot->arrangeAll();
 		// try to keep selection onscreen, even if it wasn't to start with
 		mFolderRoot->scrollToShowSelection();
 	}
-- 
cgit v1.2.3


From 118e3b33bd417331397f89770d46b1b3eeeffc8e Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Fri, 3 Aug 2012 17:43:48 -0700
Subject: CHUI-270 FIX Progress spinner not visible in merchant outbox

---
 indra/llcommon/llinitparam.cpp |  7 ++-----
 indra/llcommon/llinitparam.h   | 10 +++++++---
 2 files changed, 9 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index 451b638a3f..89c831d296 100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -335,15 +335,12 @@ namespace LLInitParam
 		{
 			const std::string& top_name = name_stack_range.first->first;
 
-			ParamDescriptor::deserialize_func_t deserialize_func = NULL;
-			Param* paramp = NULL;
-
 			BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
 			if (found_it != block_data.mNamedParams.end())
 			{
 				// find pointer to member parameter from offset table
-				paramp = getParamFromHandle(found_it->second->mParamHandle);
-				deserialize_func = found_it->second->mDeserializeFunc;
+				Param* paramp = getParamFromHandle(found_it->second->mParamHandle);
+				ParamDescriptor::deserialize_func_t deserialize_func = found_it->second->mDeserializeFunc;
 					
 				Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);
 				++new_name_stack.first;
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 2f767c234e..14ba8e0b43 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -2194,7 +2194,7 @@ namespace LLInitParam
 				resetToDefault();
 			}
 			return mValue.deserializeBlock(p, name_stack_range, new_name);
-			}
+		}
 
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
 		{
@@ -2211,12 +2211,16 @@ namespace LLInitParam
 
 		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
 		{
-			if (overwrite)
+			if ((overwrite && source_provided) // new values coming in on top or...
+				|| (!overwrite && !dst_provided)) // values being pushed under with nothing already there
 			{
+				// clear away what is there and take the new stuff as a whole
 				resetToDefault();
 				return mValue.mergeBlock(block_data, source.getValue(), overwrite);
 			}
-			return false;
+			
+
+			return mValue.mergeBlock(block_data, source.getValue(), overwrite);
 		}
 
 		bool validateBlock(bool emit_errors = true) const
-- 
cgit v1.2.3


From 3b525b788da802c8847bb2b5881c45519109ac11 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 3 Aug 2012 18:02:28 +0300
Subject: CHUI-241 (Add drag handle in UI to resize width of conversations
 list): implemented drag handle via predefined params of layout panels

---
 .../skins/default/xui/en/floater_im_container.xml  | 12 ++++---
 .../skins/default/xui/en/floater_im_session.xml    | 39 +++++++++++-----------
 2 files changed, 28 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index e8ef3c1df9..ea6fd65b95 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -31,10 +31,12 @@
      width="680">
         <layout_panel
          auto_resize="true"
+         user_resize="true"        
          height="430"
          name="conversations_layout_panel"
          min_dim="51"
-         width="268">
+         width="268"
+         min_width="120">
             <layout_stack
              animate="false" 
              follows="left|top|right"
@@ -107,17 +109,19 @@
         </layout_panel>
         <layout_panel
          auto_resize="true"
+         user_resize="true"
          height="430"
          name="messages_layout_panel"
-         width="412">
+         width="412"
+         min_width="205">
             <panel_container
              follows="all"
              height="430"
              layout="topleft"
-             left="10"
+             left="0"
              name="im_box_tab_container"
              top="0"
-             width="402"/>
+             width="412"/>
         </layout_panel>
     </layout_stack>
 </multi_floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 675967035f..4abe4d6941 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -213,8 +213,8 @@
             </layout_panel>
             <layout_panel
              height="248"
-             width="234"
-          layout="topleft"
+             width="230"
+             layout="topleft"
              follows="all"
              left_delta="0"
              top_delta="0"
@@ -231,28 +231,29 @@
          name="chat_history"
          parse_highlights="true"
          parse_urls="true"
-        left="1"
-             		width="229">
+       	 width="230"
+       	 left="0">
         </chat_history>
             </layout_panel>
            </layout_stack>
            </panel>
             <chat_editor
-         bottom="0"
-              expand_lines_count="5"
-         follows="left|right|bottom"
-	 font="SansSerifSmall"
-              visible="true"
-         height="20"
-              is_expandable="true"
-         label="To"
-         layout="bottomleft"
-         name="chat_editor"
-              max_length="1023"
-         spellcheck="true"
-         tab_group="3"
-              width="240"
-              wrap="true">
+             bottom="0"
+             expand_lines_count="5"
+             follows="left|right|bottom"
+	         font="SansSerifSmall"
+             visible="true"
+             height="20"
+             is_expandable="true"
+             label="To"
+             layout="bottomleft"
+             name="chat_editor"
+             max_length="1023"
+             spellcheck="true"
+             tab_group="3"
+             width="220"
+             left="10"
+             wrap="true">
             </chat_editor>
     </layout_panel>
   </layout_stack>
-- 
cgit v1.2.3


From aa011b98e39d9669c0bb06a25c18b092122d9252 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 6 Aug 2012 11:59:54 -0700
Subject: CHUI-276: Problem was that the flag to use ellipses was not turned on
 for the folderview's inside the Places folder. Resolution was to turn on the
 flag inside the panel_landmarks.xml file for each folder displayed (favorites
 bar, my landmarks and etc.)

---
 indra/newview/skins/default/xui/en/panel_landmarks.xml | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index ebd4c6a805..67a09949ce 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -36,6 +36,7 @@
              mouse_opaque="true"
              name="favorites_list"
              scroll.hide_scrollbar="true"
+             folder_view.use_ellipses="true"
              start_folder.name="Favorites"
              width="307"/>
         </accordion_tab>
@@ -53,6 +54,7 @@
              mouse_opaque="true"
              name="landmarks_list"
              scroll.hide_scrollbar="true"
+             folder_view.use_ellipses="true"
              start_folder.name="Landmarks"
              width="307"/>
         </accordion_tab>
@@ -70,6 +72,7 @@
              mouse_opaque="true"
              name="my_inventory_list"
              scroll.hide_scrollbar="true"
+             folder_view.use_ellipses="true"
              start_folder.name="My Inventory"
              width="307"/>
           </accordion_tab>
@@ -87,6 +90,7 @@
              mouse_opaque="true"
              name="library_list"
              scroll.hide_scrollbar="true"
+             folder_view.use_ellipses="true"
              start_folder.name="LIBRARY"
              width="313"/>
         </accordion_tab>
-- 
cgit v1.2.3


From 02bdceb5808b670fdb16784f11488c12c09e1b4b Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 6 Aug 2012 14:08:14 -0700
Subject: Linux compiliation fix, needed to create DirtyFilterFunctor outside
 of function parameter so that it can be legally passed as a reference.

---
 indra/newview/llinventorypanel.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index b217612ee7..7fba52d47f 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -624,7 +624,8 @@ void LLInventoryPanel::idle(void* user_data)
 		LLFolderViewFolder* trash_folder = panel->getFolderByID(trash_id);
 		if (trash_folder)
 		{
-			trash_folder->applyFunctorToChildren(DirtyFilterFunctor());
+            DirtyFilterFunctor dirtyFilterFunctor;
+			trash_folder->applyFunctorToChildren(dirtyFilterFunctor);
 		}
 
 	}
-- 
cgit v1.2.3


From 25855962a86331a337c4baff2754c63850605aea Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 6 Aug 2012 18:07:56 -0700
Subject: CHUI-98 : Isolate LLConversationItem and LLConversationViewModel in
 their own file

---
 indra/newview/CMakeLists.txt           |   2 +
 indra/newview/llconversationmodel.cpp  | 106 +++++++++++++++++
 indra/newview/llconversationmodel.h    | 202 +++++++++++++++++++++++++++++++++
 indra/newview/llimfloatercontainer.cpp |  73 ------------
 indra/newview/llimfloatercontainer.h   | 164 +-------------------------
 5 files changed, 311 insertions(+), 236 deletions(-)
 create mode 100644 indra/newview/llconversationmodel.cpp
 create mode 100644 indra/newview/llconversationmodel.h

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 626fb8caa5..08325daaab 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -134,6 +134,7 @@ set(viewer_SOURCE_FILES
     llconversationlog.cpp
     llconversationloglist.cpp
     llconversationloglistitem.cpp
+    llconversationmodel.cpp
     llcurrencyuimanager.cpp
     llcylinder.cpp
     lldateutil.cpp
@@ -699,6 +700,7 @@ set(viewer_HEADER_FILES
     llconversationlog.h
     llconversationloglist.h
     llconversationloglistitem.h
+    llconversationmodel.h
     llcurrencyuimanager.h
     llcylinder.h
     lldateutil.h
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
new file mode 100644
index 0000000000..bd314588a0
--- /dev/null
+++ b/indra/newview/llconversationmodel.cpp
@@ -0,0 +1,106 @@
+/** 
+ * @file llconversationmodel.cpp
+ * @brief Implementation of conversations list
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llconversationmodel.h"
+#include "llimfloatercontainer.h"
+
+// Conversation items
+LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp) :
+	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
+	mName(name),
+	mUUID(uuid),
+    mFloater(floaterp),
+    mContainer(containerp)
+{
+}
+
+LLConversationItem::LLConversationItem(LLIMFloaterContainer* containerp) :
+	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
+	mName(""),
+	mUUID(),
+	mFloater(NULL),
+	mContainer(NULL)
+{
+}
+
+
+// Virtual action callbacks
+void LLConversationItem::selectItem(void)
+{
+	LLMultiFloater* host_floater = mFloater->getHost();
+	if (host_floater == mContainer)
+	{
+		// Always expand the message pane if the panel is hosted by the container
+		mContainer->collapseMessagesPane(false);
+		// Switch to the conversation floater that is being selected
+		mContainer->selectFloater(mFloater);
+	}
+	// Set the focus on the selected floater
+	mFloater->setFocus(TRUE);    
+}
+
+void LLConversationItem::setVisibleIfDetached(BOOL visible)
+{
+	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
+	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
+	if (!mFloater->getHost() && !mFloater->isMinimized())
+	{
+		mFloater->setVisible(visible);    
+	}
+}
+
+void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
+{
+}
+
+void LLConversationItem::openItem( void )
+{
+}
+
+void LLConversationItem::closeItem( void )
+{
+}
+
+void LLConversationItem::previewItem( void )
+{
+}
+
+void LLConversationItem::showProperties(void)
+{
+}
+
+bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
+{
+	// We compare only by name for the moment
+	// *TODO : Implement the sorting by date
+	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+	return (compare < 0);
+}
+
+// EOF
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
new file mode 100644
index 0000000000..85760eb1a8
--- /dev/null
+++ b/indra/newview/llconversationmodel.h
@@ -0,0 +1,202 @@
+/** 
+ * @file llconversationmodel.h
+ * @brief Implementation of conversations list
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCONVERSATIONMODEL_H
+#define LL_LLCONVERSATIONMODEL_H
+
+//#include <map>
+//#include <vector>
+
+#include "llfolderviewitem.h"
+#include "llfolderviewmodel.h"
+
+class LLButton;
+class LLFloater;
+class LLLayoutPanel;
+class LLLayoutStack;
+class LLTabContainer;
+class LLIMFloaterContainer;
+
+// Implementation of conversations list
+
+class LLConversationItem;
+
+typedef std::map<LLFloater*, LLConversationItem*> conversations_items_map;
+typedef std::map<LLFloater*, LLFolderViewItem*> conversations_widgets_map;
+
+// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each  
+// that we tuck into the mConversationsListPanel. 
+class LLConversationItem : public LLFolderViewModelItemCommon
+{
+public:
+	LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
+	LLConversationItem(LLIMFloaterContainer* containerp);
+	virtual ~LLConversationItem() {}
+
+	// Stub those things we won't really be using in this conversation context
+	virtual const std::string& getName() const { return mName; }
+	virtual const std::string& getDisplayName() const { return mName; }
+	virtual const std::string& getSearchableName() const { return mName; }
+	virtual const LLUUID& getUUID() const { return mUUID; }
+	virtual time_t getCreationDate() const { return 0; }
+	virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
+	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
+	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
+	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
+	virtual BOOL isItemRenameable() const { return FALSE; }
+	virtual BOOL renameItem(const std::string& new_name) { return FALSE; }
+	virtual BOOL isItemMovable( void ) const { return FALSE; }
+	virtual BOOL isItemRemovable( void ) const { return FALSE; }
+	virtual BOOL isItemInTrash( void) const { return FALSE; }
+	virtual BOOL removeItem() { return FALSE; }
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
+	virtual void move( LLFolderViewModelItem* parent_listener ) { }
+	virtual BOOL isItemCopyable() const { return FALSE; }
+	virtual BOOL copyToClipboard() const { return FALSE; }
+	virtual BOOL cutToClipboard() const { return FALSE; }
+	virtual BOOL isClipboardPasteable() const { return FALSE; }
+	virtual void pasteFromClipboard() { }
+	virtual void pasteLinkFromClipboard() { }
+	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
+	virtual BOOL isUpToDate() const { return TRUE; }
+	virtual bool hasChildren() const { return FALSE; }
+
+	virtual bool potentiallyVisible() { return true; }
+	virtual bool filter( LLFolderViewFilter& filter) { return false; }
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
+	virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { }
+	virtual bool passedFilter(S32 filter_generation = -1) { return true; }
+
+	// The action callbacks
+	virtual void performAction(LLInventoryModel* model, std::string action);
+	virtual void openItem( void );
+	virtual void closeItem( void );
+	virtual void previewItem( void );
+	virtual void selectItem(void);
+	virtual void showProperties(void);
+
+	void setVisibleIfDetached(BOOL visible);
+	
+	// This method will be called to determine if a drop can be
+	// performed, and will set drop to TRUE if a drop is
+	// requested. 
+	// Returns TRUE if a drop is possible/happened, FALSE otherwise.
+	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+							EDragAndDropType cargo_type,
+							void* cargo_data,
+							std::string& tooltip_msg) { return FALSE; }
+	
+	bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
+	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
+private:
+	std::string mName;
+	const LLUUID mUUID;
+    LLFloater* mFloater;
+    LLIMFloaterContainer* mContainer;
+};
+
+// We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
+// We just stubb everything for the moment.
+class LLConversationFilter : public LLFolderViewFilter
+{
+public:
+		
+	enum ESortOrderType
+	{
+		SO_NAME = 0,						// Sort inventory by name
+		SO_DATE = 0x1,						// Sort inventory by date
+	};
+
+	LLConversationFilter() { mEmpty = ""; }
+	~LLConversationFilter() {}
+		
+	bool 				check(const LLFolderViewModelItem* item) { return true; }
+	bool				checkFolder(const LLFolderViewModelItem* folder) const { return true; }
+	void 				setEmptyLookupMessage(const std::string& message) { }
+	std::string			getEmptyLookupMessage() const { return mEmpty; }
+	bool				showAllResults() const { return true; }
+	std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const { return std::string::npos; }
+	std::string::size_type getFilterStringSize() const { return 0; }
+		
+	bool 				isActive() const { return false; }
+	bool 				isModified() const { return false; }
+	void 				clearModified() { }
+	const std::string& 	getName() const { return mEmpty; }
+	const std::string& 	getFilterText() { return mEmpty; }
+	void 				setModified(EFilterModified behavior = FILTER_RESTART) { }
+		
+	void 				setFilterCount(S32 count) { }
+	S32 				getFilterCount() const { return 0; }
+	void 				decrementFilterCount() { }
+		
+	bool 				isDefault() const { return true; }
+	bool 				isNotDefault() const { return false; }
+	void 				markDefault() { }
+	void 				resetDefault() { }
+		
+	S32 				getCurrentGeneration() const { return 0; }
+	S32 				getFirstSuccessGeneration() const { return 0; }
+	S32 				getFirstRequiredGeneration() const { return 0; }
+private:
+	std::string mEmpty;
+};
+
+class LLConversationSort
+{
+public:
+	LLConversationSort(U32 order = 0)
+	:	mSortOrder(order),
+	mByDate(false),
+	mByName(false)
+	{
+		mByDate = (order & LLConversationFilter::SO_DATE);
+		mByName = (order & LLConversationFilter::SO_NAME);
+	}
+	
+	bool isByDate() const { return mByDate; }
+	U32 getSortOrder() const { return mSortOrder; }
+	
+	bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
+private:
+	U32  mSortOrder;
+	bool mByDate;
+	bool mByName;
+};
+
+class LLConversationViewModel
+:	public LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter>
+{
+public:
+	typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t;
+	
+	void sort(LLFolderViewFolder* folder) { } // *TODO : implement conversation sort
+	bool contentsReady() { return true; }	// *TODO : we need to check that participants names are available somewhat
+	bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items
+	
+private:
+};
+
+#endif // LL_LLCONVERSATIONMODEL_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index d618e7491a..c2c0ddddea 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -536,77 +536,4 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
 	return LLUICtrlFactory::create<LLFolderViewItem>(params);
 }
 
-// Conversation items
-LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp) :
-	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
-	mName(name),
-	mUUID(uuid),
-    mFloater(floaterp),
-    mContainer(containerp)
-{
-}
-
-LLConversationItem::LLConversationItem(LLIMFloaterContainer* containerp) :
-	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
-	mName(""),
-	mUUID(),
-	mFloater(NULL),
-	mContainer(NULL)
-{
-}
-
-
-// Virtual action callbacks
-void LLConversationItem::selectItem(void)
-{
-	LLMultiFloater* host_floater = mFloater->getHost();
-	if (host_floater == mContainer)
-	{
-		// Always expand the message pane if the panel is hosted by the container
-		mContainer->collapseMessagesPane(false);
-		// Switch to the conversation floater that is being selected
-		mContainer->selectFloater(mFloater);
-	}
-	// Set the focus on the selected floater
-	mFloater->setFocus(TRUE);    
-}
-
-void LLConversationItem::setVisibleIfDetached(BOOL visible)
-{
-	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
-	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
-	if (!mFloater->getHost() && !mFloater->isMinimized())
-	{
-		mFloater->setVisible(visible);    
-	}
-}
-
-void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
-{
-}
-
-void LLConversationItem::openItem( void )
-{
-}
-
-void LLConversationItem::closeItem( void )
-{
-}
-
-void LLConversationItem::previewItem( void )
-{
-}
-
-void LLConversationItem::showProperties(void)
-{
-}
-
-bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
-{
-	// We compare only by name for the moment
-	// *TODO : Implement the sorting by date
-	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
-	return (compare < 0);
-}
-
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 5154b02dd6..161c6d9806 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -35,9 +35,7 @@
 #include "llmultifloater.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llgroupmgr.h"
-
-#include "llfolderviewitem.h"
-#include "llfolderviewmodel.h"
+#include "llconversationmodel.h"
 
 class LLButton;
 class LLLayoutPanel;
@@ -45,166 +43,6 @@ class LLLayoutStack;
 class LLTabContainer;
 class LLIMFloaterContainer;
 
-// CHUI-137 : Temporary implementation of conversations list
-class LLConversationItem;
-
-typedef std::map<LLFloater*, LLConversationItem*> conversations_items_map;
-typedef std::map<LLFloater*, LLFolderViewItem*> conversations_widgets_map;
-
-// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each  
-// that we tuck into the mConversationsListPanel. 
-class LLConversationItem : public LLFolderViewModelItemCommon
-{
-public:
-	LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
-	LLConversationItem(LLIMFloaterContainer* containerp);
-	virtual ~LLConversationItem() {}
-
-	// Stub those things we won't really be using in this conversation context
-	virtual const std::string& getName() const { return mName; }
-	virtual const std::string& getDisplayName() const { return mName; }
-	virtual const std::string& getSearchableName() const { return mName; }
-	virtual const LLUUID& getUUID() const { return mUUID; }
-	virtual time_t getCreationDate() const { return 0; }
-	virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
-	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
-	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
-	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
-	virtual BOOL isItemRenameable() const { return FALSE; }
-	virtual BOOL renameItem(const std::string& new_name) { return FALSE; }
-	virtual BOOL isItemMovable( void ) const { return FALSE; }
-	virtual BOOL isItemRemovable( void ) const { return FALSE; }
-	virtual BOOL isItemInTrash( void) const { return FALSE; }
-	virtual BOOL removeItem() { return FALSE; }
-	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
-	virtual void move( LLFolderViewModelItem* parent_listener ) { }
-	virtual BOOL isItemCopyable() const { return FALSE; }
-	virtual BOOL copyToClipboard() const { return FALSE; }
-	virtual BOOL cutToClipboard() const { return FALSE; }
-	virtual BOOL isClipboardPasteable() const { return FALSE; }
-	virtual void pasteFromClipboard() { }
-	virtual void pasteLinkFromClipboard() { }
-	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
-	virtual BOOL isUpToDate() const { return TRUE; }
-	virtual bool hasChildren() const { return FALSE; }
-
-	virtual bool potentiallyVisible() { return true; }
-	virtual bool filter( LLFolderViewFilter& filter) { return false; }
-	virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
-	virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { }
-	virtual bool passedFilter(S32 filter_generation = -1) { return true; }
-
-	// The action callbacks
-	virtual void performAction(LLInventoryModel* model, std::string action);
-	virtual void openItem( void );
-	virtual void closeItem( void );
-	virtual void previewItem( void );
-	virtual void selectItem(void);
-	virtual void showProperties(void);
-
-	void setVisibleIfDetached(BOOL visible);
-	
-	// This method will be called to determine if a drop can be
-	// performed, and will set drop to TRUE if a drop is
-	// requested. 
-	// Returns TRUE if a drop is possible/happened, FALSE otherwise.
-	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
-							EDragAndDropType cargo_type,
-							void* cargo_data,
-							std::string& tooltip_msg) { return FALSE; }
-	
-	bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
-	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
-private:
-	std::string mName;
-	const LLUUID mUUID;
-    LLFloater* mFloater;
-    LLIMFloaterContainer* mContainer;
-};
-
-// We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
-// We just stubb everything for the moment.
-class LLConversationFilter : public LLFolderViewFilter
-{
-public:
-		
-	enum ESortOrderType
-	{
-		SO_NAME = 0,						// Sort inventory by name
-		SO_DATE = 0x1,						// Sort inventory by date
-	};
-
-	LLConversationFilter() { mEmpty = ""; }
-	~LLConversationFilter() {}
-		
-	bool 				check(const LLFolderViewModelItem* item) { return true; }
-	bool				checkFolder(const LLFolderViewModelItem* folder) const { return true; }
-	void 				setEmptyLookupMessage(const std::string& message) { }
-	std::string			getEmptyLookupMessage() const { return mEmpty; }
-	bool				showAllResults() const { return true; }
-	std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const { return std::string::npos; }
-	std::string::size_type getFilterStringSize() const { return 0; }
-		
-	bool 				isActive() const { return false; }
-	bool 				isModified() const { return false; }
-	void 				clearModified() { }
-	const std::string& 	getName() const { return mEmpty; }
-	const std::string& 	getFilterText() { return mEmpty; }
-	void 				setModified(EFilterModified behavior = FILTER_RESTART) { }
-		
-	void 				setFilterCount(S32 count) { }
-	S32 				getFilterCount() const { return 0; }
-	void 				decrementFilterCount() { }
-		
-	bool 				isDefault() const { return true; }
-	bool 				isNotDefault() const { return false; }
-	void 				markDefault() { }
-	void 				resetDefault() { }
-		
-	S32 				getCurrentGeneration() const { return 0; }
-	S32 				getFirstSuccessGeneration() const { return 0; }
-	S32 				getFirstRequiredGeneration() const { return 0; }
-private:
-	std::string mEmpty;
-};
-
-class LLConversationSort
-{
-public:
-	LLConversationSort(U32 order = 0)
-	:	mSortOrder(order),
-	mByDate(false),
-	mByName(false)
-	{
-		mByDate = (order & LLConversationFilter::SO_DATE);
-		mByName = (order & LLConversationFilter::SO_NAME);
-	}
-	
-	bool isByDate() const { return mByDate; }
-	U32 getSortOrder() const { return mSortOrder; }
-	
-	bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
-private:
-	U32  mSortOrder;
-	bool mByDate;
-	bool mByName;
-};
-
-class LLConversationViewModel
-:	public LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter>
-{
-public:
-	typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t;
-	
-	void sort(LLFolderViewFolder* folder) { } // *TODO : implement conversation sort
-	bool contentsReady() { return true; }	// *TODO : we need to check that participants names are available somewhat
-	bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items
-	
-private:
-};
-
-// CHUI-137 : End
-
 class LLIMFloaterContainer
 	: public LLMultiFloater
 	, public LLIMSessionObserver
-- 
cgit v1.2.3


From 324200dfd7d70324fe15329100140d98bb1f9b17 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 9 Aug 2012 00:00:25 +0300
Subject: CHUI-120 WIP Added notifications about newly invited chat
 participants.

---
 indra/newview/llimfloater.cpp                      | 124 ++++++++++++++++-----
 indra/newview/llimfloater.h                        |   3 +-
 .../skins/default/xui/en/floater_im_session.xml    |   6 +
 .../newview/skins/default/xui/en/notifications.xml |  14 +++
 4 files changed, 120 insertions(+), 27 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 3399a88c9e..a2989375ea 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -352,19 +352,19 @@ BOOL LLIMFloater::postBuild()
 }
 
 void LLIMFloater::onAddButtonClicked()
+{
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::onAddSessionParticipants, this, _1), TRUE, TRUE);
+	if (!picker)
 	{
-       LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::addSessionParticipants, this, _1), TRUE, TRUE);
-       if (!picker)
-       {
-               return;
+		return;
 	}
 
-       // Need to disable 'ok' button when selected users are already in conversation.
-       picker->setOkBtnEnableCb(boost::bind(&LLIMFloater::canAddSelectedToChat, this, _1));
-       LLFloater* root_floater = gFloaterView->getParentFloater(this);
-       if (root_floater)
+	// Need to disable 'ok' button when selected users are already in conversation.
+	picker->setOkBtnEnableCb(boost::bind(&LLIMFloater::canAddSelectedToChat, this, _1));
+	LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	if (root_floater)
 	{
-               root_floater->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
@@ -420,8 +420,54 @@ bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
 	return true;
 }
 
-void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids)
+void LLIMFloater::onAddSessionParticipants(const uuid_vec_t& uuids)
+{
+	LLSD payload;
+	LLSD args;
+	for (uuid_vec_t::const_iterator iter = uuids.begin(); iter != uuids.end(); ++iter)
+	{
+		payload["participant_ids"].append(*iter);
+	}
+
+	LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload,
+							 boost::bind(&LLIMFloater::addSessionParticipants, this, _1, _2));
+}
+
+void LLIMFloater::addSessionParticipants(const LLSD& notification, const LLSD& response)
+{
+	uuid_vec_t uuids;
+	LLSD::array_const_iterator list_it = notification["payload"]["participant_ids"].beginArray();
+	LLSD::array_const_iterator list_end = notification["payload"]["participant_ids"].endArray();
+	for (; list_it != list_end;	++list_it)
+	{
+		uuids.push_back(list_it->asUUID());
+	}
+
+	std::vector<LLAvatarName> avatar_names;
+	uuid_vec_t::const_iterator it = uuids.begin();
+	for (; it != uuids.end(); ++it)
 	{
+		const LLUUID& id = *it;
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(id, &av_name))
+		{
+			avatar_names.push_back(av_name);
+		}
+	}
+
+	std::string added_participants;
+
+	// We should check whether the vector is not empty to pass the assertion
+	// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
+	if (!avatar_names.empty())
+	{
+		LLAvatarActions::buildResidentsString(avatar_names, added_participants);
+	}
+
+	LLStringUtil::format_map_t args;
+	args["[NAMES]"] = added_participants;
+	std::string participants_added_notification;
+
 	if (mIsP2PChat)
 	{
 		mStartConferenceInSameFloater = true;
@@ -440,19 +486,45 @@ void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids)
 		// then we can close the current session
 		onClose(false);
 
+		participants_added_notification = getString("participants_added_new_window", args);
+		participants_added_notification = utf8str_truncate(participants_added_notification, MAX_MSG_BUF_SIZE - 1);
+
+		if (mSessionInitialized)
+		{
+				LLIMModel::sendMessage(participants_added_notification, mSessionID, mOtherParticipantUUID, mDialog);
+		}
+		else
+		{
+			//queue up the message to send once the session is initialized
+			mQueuedMsgsForInit.append(participants_added_notification);
+		}
+
 		// Start a new ad hoc voice call if we invite new participants to a P2P call,
 		// or start a text chat otherwise.
 		if (is_voice_call)
 		{
 			LLAvatarActions::startAdhocCall(temp_ids, mSessionID);
-	}
-	else
-	{
+		}
+		else
+		{
 			LLAvatarActions::startConference(temp_ids, mSessionID);
+		}
 	}
-}
 	else
 	{
+		participants_added_notification = getString("participants_added", args);
+		participants_added_notification = utf8str_truncate(participants_added_notification, MAX_MSG_BUF_SIZE - 1);
+
+		if (mSessionInitialized)
+		{
+				LLIMModel::sendMessage(participants_added_notification, mSessionID, mOtherParticipantUUID, mDialog);
+		}
+		else
+		{
+			//queue up the message to send once the session is initialized
+			mQueuedMsgsForInit.append(participants_added_notification);
+		}
+
 		inviteToSession(uuids);
 	}
 }
@@ -1115,19 +1187,19 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	if (cargo_type == DAD_PERSON)
 	{
 		if (dropPerson(static_cast<LLUUID*>(cargo_data), drop))
-	{
+		{
 			*accept = ACCEPT_YES_MULTI;
-	}
+		}
 		else
-	{
-		*accept = ACCEPT_NO;
-			}
+		{
+			*accept = ACCEPT_NO;
 		}
+	}
 	else if (mDialog == IM_NOTHING_SPECIAL)
-		{
+	{
 		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
 				cargo_type, cargo_data, accept);
-			}
+	}
 
 	return TRUE;
 }
@@ -1137,18 +1209,18 @@ bool LLIMFloater::dropPerson(LLUUID* person_id, bool drop)
 	bool res = person_id && person_id->notNull();
 	if(res)
 	{
-			uuid_vec_t ids;
+		uuid_vec_t ids;
 		ids.push_back(*person_id);
 
 		res = canAddSelectedToChat(ids);
 		if(res && drop)
-	{
-			addSessionParticipants(ids);
+		{
+			onAddSessionParticipants(ids);
+		}
 	}
-}
 
 	return res;
-		}
+}
 
 BOOL LLIMFloater::isInviteAllowed() const
 {
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 434613ff43..d98213b54c 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -160,7 +160,8 @@ private:
 	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
 	void setTyping(bool typing);
 	void onAddButtonClicked();
-	void addSessionParticipants(const uuid_vec_t& uuids);
+	void onAddSessionParticipants(const uuid_vec_t& uuids);
+	void addSessionParticipants(const LLSD& notification, const LLSD& response);
 	bool canAddSelectedToChat(const uuid_vec_t& uuids);
 
 	void onCallButtonClicked();
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 4abe4d6941..2b63430106 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -34,6 +34,12 @@
     <floater.string
      name="return_icon"
      value="Conv_toolbar_arrow_sw"/>
+    <floater.string
+     name="participants_added"
+     value="New participant(s) were invited to the conversation: [NAMES]."/>
+    <floater.string
+     name="participants_added_new_window"
+     value="New participant(s) were invited to the conversation: [NAMES]. The conversation will be started in a new window."/>
     <view
         follows="all"
         layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index e85637826d..2ffa2cfb22 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4946,6 +4946,20 @@ Go to your [http://secondlife.com/account/ Dashboard] to see your account histor
      yestext="Go to page"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="ConfirmAddingChatParticipants"
+   type="alertmodal">
+    <unique/>
+When you add a person to an existing conversation, a new conversation will be created.  All participants will receive new conversation notifications.
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm adding chat paticipants"
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="Ok"/>
+  </notification>
+ 
   <notification
    icon="alertmodal.tga"
    name="ConfirmQuit"
-- 
cgit v1.2.3


From 2b026a806617532a0b2c8a796e9530273c110cf4 Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Wed, 8 Aug 2012 18:17:01 -0700
Subject: CHUI-272: BUGFIX Correcting the inventory filtering so that a large
 number of items in the inventory are completely processed before the filter's
 modified flag is cleared.

---
 indra/llui/llfolderview.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index fedb8bc014..1a8ab63388 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1715,11 +1715,17 @@ void LLFolderView::update()
 	{
 		mNeedsAutoSelect = TRUE;
 	}
-	getFolderViewModel()->getFilter().clearModified();
 
 	// filter to determine visibility before arranging
 	filter(getFolderViewModel()->getFilter());
 
+	// Clear the modified setting on the filter only if the filter count is non-zero after running the filter process
+	// Note: if the filter count is zero, then the filter most likely halted before completing the entire set of items
+	if (getFolderViewModel()->getFilter().isModified() && (getFolderViewModel()->getFilter().getFilterCount() > 0))
+	{
+		getFolderViewModel()->getFilter().clearModified();
+	}
+
 	// automatically show matching items, and select first one if we had a selection
 	if (mNeedsAutoSelect)
 	{
-- 
cgit v1.2.3


From 6cf49a4a715c9f498d4b063f8d74e295be1f418c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 9 Aug 2012 16:48:33 +0300
Subject: CHUI-171 WIP (Conversation not automatically readded to conversation
 window listing when open) - removal of the dependence between items of the
 conversations list and conversation's floaters.

---
 indra/newview/llconversationmodel.cpp              | 22 +++++---
 indra/newview/llconversationmodel.h                |  9 ++-
 indra/newview/llimconversation.cpp                 | 15 ++++-
 indra/newview/llimconversation.h                   |  3 +
 indra/newview/llimfloater.cpp                      | 28 ++++------
 indra/newview/llimfloatercontainer.cpp             | 64 ++++++++++------------
 indra/newview/llimfloatercontainer.h               | 12 ++--
 indra/newview/llnearbychat.cpp                     |  9 +--
 indra/newview/llsyswellwindow.h                    |  2 +
 .../skins/default/xui/en/floater_im_session.xml    |  3 -
 indra/newview/skins/default/xui/en/strings.xml     |  3 +-
 11 files changed, 88 insertions(+), 82 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index bd314588a0..0c23e2654e 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -28,14 +28,14 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llconversationmodel.h"
+#include "llimconversation.h"
 #include "llimfloatercontainer.h"
 
 // Conversation items
-LLConversationItem::LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp) :
+LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLIMFloaterContainer* containerp) :
 	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
-	mName(name),
+	mName(display_name),
 	mUUID(uuid),
-    mFloater(floaterp),
     mContainer(containerp)
 {
 }
@@ -44,7 +44,6 @@ LLConversationItem::LLConversationItem(LLIMFloaterContainer* containerp) :
 	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
 	mName(""),
 	mUUID(),
-	mFloater(NULL),
 	mContainer(NULL)
 {
 }
@@ -53,25 +52,30 @@ LLConversationItem::LLConversationItem(LLIMFloaterContainer* containerp) :
 // Virtual action callbacks
 void LLConversationItem::selectItem(void)
 {
-	LLMultiFloater* host_floater = mFloater->getHost();
+	LLFloater* session_floater = LLIMConversation::getConversation(mUUID);
+	LLMultiFloater* host_floater = session_floater->getHost();
+
+//	LLIMFloater::show(mUUID);
 	if (host_floater == mContainer)
 	{
 		// Always expand the message pane if the panel is hosted by the container
 		mContainer->collapseMessagesPane(false);
 		// Switch to the conversation floater that is being selected
-		mContainer->selectFloater(mFloater);
+		mContainer->selectFloater(session_floater);
 	}
 	// Set the focus on the selected floater
-	mFloater->setFocus(TRUE);    
+	session_floater->setFocus(TRUE);
 }
 
 void LLConversationItem::setVisibleIfDetached(BOOL visible)
 {
 	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
 	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
-	if (!mFloater->getHost() && !mFloater->isMinimized())
+	LLFloater* session_floater = LLIMConversation::getConversation(mUUID);
+
+	if (session_floater && !session_floater->getHost() && !session_floater->isMinimized())
 	{
-		mFloater->setVisible(visible);    
+		session_floater->setVisible(visible);
 	}
 }
 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 85760eb1a8..56a5b73c15 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -44,15 +44,15 @@ class LLIMFloaterContainer;
 
 class LLConversationItem;
 
-typedef std::map<LLFloater*, LLConversationItem*> conversations_items_map;
-typedef std::map<LLFloater*, LLFolderViewItem*> conversations_widgets_map;
+typedef std::map<LLUUID, LLConversationItem*> conversations_items_map;
+typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
 
 // Conversation items: we hold a list of those and create an LLFolderViewItem widget for each  
 // that we tuck into the mConversationsListPanel. 
 class LLConversationItem : public LLFolderViewModelItemCommon
 {
 public:
-	LLConversationItem(std::string name, const LLUUID& uuid, LLFloater* floaterp, LLIMFloaterContainer* containerp);
+	LLConversationItem(std::string display_name, const LLUUID& uuid, LLIMFloaterContainer* containerp);
 	LLConversationItem(LLIMFloaterContainer* containerp);
 	virtual ~LLConversationItem() {}
 
@@ -109,12 +109,11 @@ public:
 							void* cargo_data,
 							std::string& tooltip_msg) { return FALSE; }
 	
-	bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
+//	bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
 	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
 private:
 	std::string mName;
 	const LLUUID mUUID;
-    LLFloater* mFloater;
     LLIMFloaterContainer* mContainer;
 };
 
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index b56f30312a..ec25583c8f 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -78,6 +78,19 @@ LLIMConversation::~LLIMConversation()
 	delete mRefreshTimer;
 }
 
+//static
+LLIMConversation* LLIMConversation::findConversation(const LLUUID& uuid)
+{
+    return LLFloaterReg::findTypedInstance<LLIMConversation>(uuid.isNull()? "chat_bar" : "impanel", LLSD(uuid));
+};
+
+//static
+LLIMConversation* LLIMConversation::getConversation(const LLUUID& uuid)
+{
+	return LLFloaterReg::getTypedInstance<LLIMConversation>(uuid.isNull()? "chat_bar" : "impanel", LLSD(uuid));
+};
+
+
 BOOL LLIMConversation::postBuild()
 {
 	BOOL result;
@@ -384,7 +397,7 @@ void LLIMConversation::onClose(bool app_quitting)
 		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
 		if (im_box)
 		{
-            im_box->removeConversationListItem(this);
+            im_box->removeConversationListItem(mKey);
         }
     }
 }
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 649c200899..94a3a7781b 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -57,6 +57,9 @@ public:
 	 */
 	static bool isChatMultiTab();
 
+    static LLIMConversation* findConversation(const LLUUID& uuid);
+    static LLIMConversation* getConversation(const LLUUID& uuid);
+
 	// show/hide the translation check box
 	void showTranslationCheckbox(const BOOL visible = FALSE);
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 3399a88c9e..6a1437f318 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -344,10 +344,6 @@ BOOL LLIMFloater::postBuild()
 
 	initIMFloater();
 
-	// Add a conversation list item in the left pane
-	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-	im_box->addConversationListItem(getTitle(), getKey(), this);
-
 	return result;
 }
 
@@ -547,7 +543,7 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 	if (!avatar_list)
 	{
 		return;
-		}
+	}
 
 	bool all_names_resolved = true;
 	std::vector<LLSD> participants_uuids;
@@ -555,12 +551,12 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 	avatar_list->getValues(participants_uuids);
 
 	// Check whether we have all participants names in LLAvatarNameCache
-	for (std::vector<LLSD>::const_iterator it = participants_uuids.begin(); it != participants_uuids.end(); ++it)
-{
+    for (std::vector<LLSD>::const_iterator it = participants_uuids.begin(); it != participants_uuids.end(); ++it)
+    {
 		const LLUUID& id = it->asUUID();
 		LLAvatarName av_name;
-		if (!LLAvatarNameCache::get(id, &av_name))
-		{
+        if (!LLAvatarNameCache::get(id, &av_name))
+        {
 			all_names_resolved = false;
 
 			// If a name is not found in cache, request it and continue the process recursively
@@ -568,8 +564,8 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 			LLAvatarNameCache::get(id,
 					boost::bind(&LLIMFloater::onParticipantsListChanged, this, avatar_list));
 			break;
-		}
-}
+        }
+    }
 
 	if (all_names_resolved)
 	{
@@ -580,20 +576,20 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 			const LLUUID& id = it->asUUID();
 			LLAvatarName av_name;
 			if (LLAvatarNameCache::get(id, &av_name))
-{
+            {
 				avatar_names.push_back(av_name);
-			}
-}
+            }
+        }
 
 		// We should check whether the vector is not empty to pass the assertion
 		// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
 		if (!avatar_names.empty())
-{
+        {
 			std::string ui_title;
 			LLAvatarActions::buildResidentsString(avatar_names, ui_title);
 			updateSessionName(ui_title, ui_title);
 		}
-}
+    }
 }
 
 //static
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c2c0ddddea..1896ed65f3 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -76,13 +76,20 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
 	LLIMFloater::show(session_id);
+	addConversationListItem(session_id);
+}
+
+void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+	removeConversationListItem(old_session_id);
+	addConversationListItem(new_session_id);
 }
 
 void LLIMFloaterContainer::sessionRemoved(const LLUUID& session_id)
 {
 	LLIMFloater* floaterp = LLIMFloater::findInstance(session_id);
 	LLFloater::onClickClose(floaterp);
-	removeConversationListItem(floaterp);
+	removeConversationListItem(session_id);
 }
 
 BOOL LLIMFloaterContainer::postBuild()
@@ -112,6 +119,10 @@ BOOL LLIMFloaterContainer::postBuild()
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
 	mConversationsListPanel->addChild(mConversationsRoot);
 
+	addConversationListItem(LLUUID()); // manually add nearby chat
+
+	addConversationListItem(LLUUID()); // manually add nearby chat
+
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
 
@@ -301,13 +312,13 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	if (visible)
 	{
 		// Make sure we have the Nearby Chat present when showing the conversation container
-		LLFloater* nearby_chat = LLFloaterReg::findInstance("chat_bar");
+		LLIMConversation* nearby_chat = LLIMConversation::getConversation(LLUUID::null);
 		if (nearby_chat == NULL)
 		{
 			// If not found, force the creation of the nearby chat conversation panel
 			// *TODO: find a way to move this to XML as a default panel or something like that
 			LLSD name("chat_bar");
-			LLFloaterReg::toggleInstanceOrBringToFront(name);
+			LLFloaterReg::toggleInstanceOrBringToFront(name, LLSD(LLUUID::null));
 		}
 	}
 
@@ -432,33 +443,29 @@ void LLIMFloaterContainer::repositioningWidgets()
 }
 
 // CHUI-137 : Temporary implementation of conversations list
-void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp)
+void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 {
+	std::string display_name = uuid.isNull()? LLTrans::getString("NearbyChatTitle") : LLIMModel::instance().getName(uuid);
+
 	// Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do)
 	// Note: this happens often, when reattaching a torn off conversation for instance
-	conversations_items_map::iterator item_it = mConversationsItems.find(floaterp);
+	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
 	if (item_it != mConversationsItems.end())
 	{
-		LLConversationItem* item = item_it->second;
-		// Check if the item has changed
-		if (item->hasSameValues(name,uuid))
-		{
-			// If it hasn't changed, nothing to do -> exit
-			return;
-		}
+		return;
 	}
-	
+
 	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
 	// and nothing wrong will happen removing it if it doesn't exist
-	removeConversationListItem(floaterp,false);
+	removeConversationListItem(uuid,false);
 
 	// Create a conversation item
-	LLConversationItem* item = new LLConversationItem(name, uuid, floaterp, this);
-	mConversationsItems[floaterp] = item;
+	LLConversationItem* item = new LLConversationItem(display_name, uuid, this);
+	mConversationsItems[uuid] = item;
 
 	// Create a widget from it
 	LLFolderViewItem* widget = createConversationItemWidget(item);
-	mConversationsWidgets[floaterp] = widget;
+	mConversationsWidgets[uuid] = widget;
 
 	// Add a new conversation widget to the root folder of a folder view.
 	widget->addToFolder(mConversationsRoot);
@@ -473,12 +480,12 @@ void LLIMFloaterContainer::addConversationListItem(std::string name, const LLUUI
 	return;
 }
 
-void LLIMFloaterContainer::removeConversationListItem(LLFloater* floaterp, bool change_focus)
+void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
 {
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(floaterp);
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(uuid);
 	if (widget_it != mConversationsWidgets.end())
 	{
 		LLFolderViewItem* widget = widget_it->second;
@@ -486,8 +493,8 @@ void LLIMFloaterContainer::removeConversationListItem(LLFloater* floaterp, bool
 	}
 	
 	// Suppress the conversation items and widgets from their respective maps
-	mConversationsItems.erase(floaterp);
-	mConversationsWidgets.erase(floaterp);
+	mConversationsItems.erase(uuid);
+	mConversationsWidgets.erase(uuid);
 
 	repositioningWidgets();
 	
@@ -505,21 +512,6 @@ void LLIMFloaterContainer::removeConversationListItem(LLFloater* floaterp, bool
 	return;
 }
 
-LLFloater* LLIMFloaterContainer::findConversationItem(LLUUID& uuid)
-{
-	LLFloater* floaterp = NULL;
-	for (conversations_items_map::iterator item_it = mConversationsItems.begin(); item_it != mConversationsItems.end(); ++item_it)
-	{
-		LLConversationItem* item = item_it->second;
-		if (item->hasSameValue(uuid))
-		{
-			floaterp = item_it->first;
-			break;
-		}
-	}
-	return floaterp;
-}
-
 LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
 {
 	LLFolderViewItem::Params params;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 161c6d9806..d6dda8ea2d 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -35,6 +35,7 @@
 #include "llmultifloater.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llgroupmgr.h"
+#include "lltrans.h"
 #include "llconversationmodel.h"
 
 class LLButton;
@@ -75,10 +76,11 @@ public:
 	
 
 	// LLIMSessionObserver observe triggers
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
-	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {};
+	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
 	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
 
 private:
@@ -107,9 +109,9 @@ private:
 	
 	// Conversation list implementation
 public:
-	void removeConversationListItem(LLFloater* floaterp, bool change_focus = true);
-	void addConversationListItem(std::string name, const LLUUID& uuid, LLFloater* floaterp);
-	LLFloater* findConversationItem(LLUUID& uuid);
+	void removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
+	void addConversationListItem(const LLUUID& uuid);
+
 private:
 	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 8f0e6b4c83..fa8e423056 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -152,7 +152,7 @@ BOOL LLNearbyChat::postBuild()
 
 	// title must be defined BEFORE call addConversationListItem() because
 	// it is used for show the item's name in the conversations list
-	setTitle(getString("NearbyChatTitle"));
+	setTitle(LLTrans::getString("NearbyChatTitle"));
 
 	addToHost();
 
@@ -177,16 +177,13 @@ BOOL LLNearbyChat::postBuild()
 		loadHistory();
 	}
 
-	// added row in the conversations list when nearby chat is tear-off
-	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-	im_box->addConversationListItem(getTitle(), LLSD(), this);
-
 	return result;
 }
 
 // virtual
 void LLNearbyChat::refresh()
 {
+	updateHeaderAndToolbar();
 	displaySpeakingIndicator();
 	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
 
@@ -386,7 +383,7 @@ void LLNearbyChat::onChatFontChange(LLFontGL* fontp)
 //static
 LLNearbyChat* LLNearbyChat::getInstance()
 {
-	return LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar");
+	return LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar", LLSD(LLUUID::null));
 }
 
 void LLNearbyChat::show()
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 8758c8c4e5..6be12711ac 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -49,6 +49,8 @@ class LLSysWellChiclet;
 class LLSysWellWindow : public LLTransientDockableFloater
 {
 public:
+	LOG_CLASS(LLSysWellWindow);
+
     LLSysWellWindow(const LLSD& key);
     ~LLSysWellWindow();
 	BOOL postBuild();
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 4abe4d6941..37aa8bb787 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -17,9 +17,6 @@
  min_width="250"
  min_height="190"
  positioning="relative">
-    <floater.string 
-     name="NearbyChatTitle"
-     value="Nearby Chat"/>
     <floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string>
     <floater.string name="call_btn_stop">Conv_toolbar_hang_up</floater.string>
     <floater.string
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 2806bcaa2e..696c282887 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -384,13 +384,14 @@ Please try logging in again in a minute.</string>
 	<string name="ST_NO_JOINT">Can't find ROOT or JOINT.</string>
 
 	<!-- Chat -->
+	<string name="NearbyChatTitle">Nearby chat</string>
 	<string name="whisper">whispers:</string>
 	<string name="shout">shouts:</string>
 	<string name="ringing">Connecting to in-world Voice Chat...</string>
 	<string name="connected">Connected</string>
 	<string name="unavailable">Voice not available at your current location</string>
 	<string name="hang_up">Disconnected from in-world Voice Chat</string>
-  <string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string>
+    <string name="reconnect_nearby">You will now be reconnected to Nearby Voice Chat</string>
 	<string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS].</string>
 	<string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS].</string>
 	<string name="AdditionalPermissionsRequestHeader">If you allow access to your account, you will also be allowing the object to:</string>
-- 
cgit v1.2.3


From f744fe8b5496e8d2d357ce88b3552eeee2125a5e Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 10 Aug 2012 02:51:56 +0300
Subject: CHUI-120 WIP Different notifications about single and multiple chat
 participants invited. The notification about starting a new conversation now
 applies only to P2P chat. Some code refactoring and clean up.

---
 indra/newview/llimfloater.cpp                      | 285 +++++++++------------
 indra/newview/llimfloater.h                        |   8 +-
 .../skins/default/xui/en/floater_im_session.xml    |  11 +-
 3 files changed, 137 insertions(+), 167 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index a2989375ea..c3c9e334f2 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -60,6 +60,10 @@
 #include "llnotificationmanager.h"
 #include "llautoreplace.h"
 
+/// Helper function to resolve resident names from given uuids
+/// and form a string of names separated by "words_separator".
+static void build_names_string(const uuid_vec_t& uuids, std::string& names_string);
+
 floater_showed_signal_t LLIMFloater::sIMFloaterShowedSignal;
 
 LLIMFloater::LLIMFloater(const LLUUID& session_id)
@@ -186,49 +190,55 @@ void LLIMFloater::onVisibilityChange(const LLSD& new_visibility)
 void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
 {
 	LLIMFloater* self = (LLIMFloater*) userdata;
-	self->sendMsg();
+	self->sendMsgFromInputEditor();
 	self->setTyping(false);
 }
 
-void LLIMFloater::sendMsg()
+void LLIMFloater::sendMsgFromInputEditor()
 {
 	if (gAgent.isGodlike()
 		|| (mDialog != IM_NOTHING_SPECIAL)
 		|| !mOtherParticipantUUID.isNull())
 	{
-	if (mInputEditor)
-	{
+		if (mInputEditor)
+		{
 			LLWString text = mInputEditor->getWText();
 			LLWStringUtil::trim(text);
 			LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
-		if(!text.empty())
-		{
-			// Truncate and convert to UTF8 for transport
-			std::string utf8_text = wstring_to_utf8str(text);
-			utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
-			
-			if (mSessionInitialized)
-			{
-					LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
-			}
-			else
+			if(!text.empty())
 			{
-				//queue up the message to send once the session is initialized
-				mQueuedMsgsForInit.append(utf8_text);
-			}
+				// Truncate and convert to UTF8 for transport
+				std::string utf8_text = wstring_to_utf8str(text);
 
-			mInputEditor->setText(LLStringUtil::null);
+				sendMsg(utf8_text);
 
-			updateMessages();
+				mInputEditor->setText(LLStringUtil::null);
+			}
 		}
 	}
-}
 	else
 	{
 		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
 	}
 }
 
+void LLIMFloater::sendMsg(const std::string& msg)
+{
+	const std::string utf8_text = utf8str_truncate(msg, MAX_MSG_BUF_SIZE - 1);
+
+	if (mSessionInitialized)
+	{
+			LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
+	}
+	else
+	{
+		//queue up the message to send once the session is initialized
+		mQueuedMsgsForInit.append(utf8_text);
+	}
+
+	updateMessages();
+}
+
 LLIMFloater::~LLIMFloater()
 {
 	mParticipantsListRefreshConnection.disconnect();
@@ -241,6 +251,7 @@ LLIMFloater::~LLIMFloater()
 	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
 }
 
+
 void LLIMFloater::initIMSession(const LLUUID& session_id)
 {
 	// Change the floater key to bind it to a new session.
@@ -353,7 +364,7 @@ BOOL LLIMFloater::postBuild()
 
 void LLIMFloater::onAddButtonClicked()
 {
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::onAddSessionParticipants, this, _1), TRUE, TRUE);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::addSessionParticipants, this, _1), TRUE, TRUE);
 	if (!picker)
 	{
 		return;
@@ -420,113 +431,65 @@ bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
 	return true;
 }
 
-void LLIMFloater::onAddSessionParticipants(const uuid_vec_t& uuids)
+void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids)
 {
-	LLSD payload;
-	LLSD args;
-	for (uuid_vec_t::const_iterator iter = uuids.begin(); iter != uuids.end(); ++iter)
+	if (mIsP2PChat)
 	{
-		payload["participant_ids"].append(*iter);
-	}
-
-	LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload,
-							 boost::bind(&LLIMFloater::addSessionParticipants, this, _1, _2));
-}
+		LLSD payload;
+		LLSD args;
 
-void LLIMFloater::addSessionParticipants(const LLSD& notification, const LLSD& response)
-{
-	uuid_vec_t uuids;
-	LLSD::array_const_iterator list_it = notification["payload"]["participant_ids"].beginArray();
-	LLSD::array_const_iterator list_end = notification["payload"]["participant_ids"].endArray();
-	for (; list_it != list_end;	++list_it)
-	{
-		uuids.push_back(list_it->asUUID());
+		LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload,
+				boost::bind(&LLIMFloater::addP2PSessionParticipants, this, uuids));
 	}
-
-	std::vector<LLAvatarName> avatar_names;
-	uuid_vec_t::const_iterator it = uuids.begin();
-	for (; it != uuids.end(); ++it)
+	else
 	{
-		const LLUUID& id = *it;
-		LLAvatarName av_name;
-		if (LLAvatarNameCache::get(id, &av_name))
-		{
-			avatar_names.push_back(av_name);
-		}
-	}
-
-	std::string added_participants;
+		sendParticipantsAddedNotification(uuids);
 
-	// We should check whether the vector is not empty to pass the assertion
-	// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
-	if (!avatar_names.empty())
-	{
-		LLAvatarActions::buildResidentsString(avatar_names, added_participants);
+		inviteToSession(uuids);
 	}
+}
 
-	LLStringUtil::format_map_t args;
-	args["[NAMES]"] = added_participants;
-	std::string participants_added_notification;
-
-	if (mIsP2PChat)
-	{
-		mStartConferenceInSameFloater = true;
+void LLIMFloater::addP2PSessionParticipants(const uuid_vec_t& uuids)
+{
+	sendParticipantsAddedNotification(uuids);
 
-		uuid_vec_t temp_ids;
+	mStartConferenceInSameFloater = true;
 
-		// Add the initial participant of a P2P session
-		temp_ids.push_back(mOtherParticipantUUID);
-		temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end());
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
 
-		LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+	// first check whether this is a voice session
+	bool is_voice_call = voice_channel != NULL && voice_channel->isActive();
 
-		// first check whether this is a voice session
-		bool is_voice_call = voice_channel != NULL && voice_channel->isActive();
+	uuid_vec_t temp_ids;
 
-		// then we can close the current session
-		onClose(false);
+	// Add the initial participant of a P2P session
+	temp_ids.push_back(mOtherParticipantUUID);
+	temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end());
 
-		participants_added_notification = getString("participants_added_new_window", args);
-		participants_added_notification = utf8str_truncate(participants_added_notification, MAX_MSG_BUF_SIZE - 1);
+	// then we can close the current session
+	onClose(false);
 
-		if (mSessionInitialized)
-		{
-				LLIMModel::sendMessage(participants_added_notification, mSessionID, mOtherParticipantUUID, mDialog);
-		}
-		else
-		{
-			//queue up the message to send once the session is initialized
-			mQueuedMsgsForInit.append(participants_added_notification);
-		}
-
-		// Start a new ad hoc voice call if we invite new participants to a P2P call,
-		// or start a text chat otherwise.
-		if (is_voice_call)
-		{
-			LLAvatarActions::startAdhocCall(temp_ids, mSessionID);
-		}
-		else
-		{
-			LLAvatarActions::startConference(temp_ids, mSessionID);
-		}
+	// Start a new ad hoc voice call if we invite new participants to a P2P call,
+	// or start a text chat otherwise.
+	if (is_voice_call)
+	{
+		LLAvatarActions::startAdhocCall(temp_ids, mSessionID);
 	}
 	else
 	{
-		participants_added_notification = getString("participants_added", args);
-		participants_added_notification = utf8str_truncate(participants_added_notification, MAX_MSG_BUF_SIZE - 1);
+		LLAvatarActions::startConference(temp_ids, mSessionID);
+	}
+}
 
-		if (mSessionInitialized)
-		{
-				LLIMModel::sendMessage(participants_added_notification, mSessionID, mOtherParticipantUUID, mDialog);
-		}
-		else
-		{
-			//queue up the message to send once the session is initialized
-			mQueuedMsgsForInit.append(participants_added_notification);
-		}
+void LLIMFloater::sendParticipantsAddedNotification(const uuid_vec_t& uuids)
+{
+	std::string names_string;
+	build_names_string(uuids, names_string);
+	LLStringUtil::format_map_t args;
+	args["[NAME]"] = names_string;
+	args["[NEW_WINDOW]"] = mIsP2PChat ? getString("new_window") : LLStringUtil::null;
 
-		inviteToSession(uuids);
-	}
+	sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args));
 }
 
 void LLIMFloater::boundVoiceChannel()
@@ -619,17 +582,19 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 	if (!avatar_list)
 	{
 		return;
-		}
+	}
 
 	bool all_names_resolved = true;
 	std::vector<LLSD> participants_uuids;
+	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
 
 	avatar_list->getValues(participants_uuids);
 
 	// Check whether we have all participants names in LLAvatarNameCache
 	for (std::vector<LLSD>::const_iterator it = participants_uuids.begin(); it != participants_uuids.end(); ++it)
-{
+	{
 		const LLUUID& id = it->asUUID();
+		temp_uuids.push_back(id);
 		LLAvatarName av_name;
 		if (!LLAvatarNameCache::get(id, &av_name))
 		{
@@ -641,31 +606,14 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 					boost::bind(&LLIMFloater::onParticipantsListChanged, this, avatar_list));
 			break;
 		}
-}
+	}
 
 	if (all_names_resolved)
 	{
-		std::vector<LLAvatarName> avatar_names;
-		std::vector<LLSD>::const_iterator it = participants_uuids.begin();
-		for (; it != participants_uuids.end(); ++it)
-		{
-			const LLUUID& id = it->asUUID();
-			LLAvatarName av_name;
-			if (LLAvatarNameCache::get(id, &av_name))
-{
-				avatar_names.push_back(av_name);
-			}
-}
-
-		// We should check whether the vector is not empty to pass the assertion
-		// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
-		if (!avatar_names.empty())
-{
-			std::string ui_title;
-			LLAvatarActions::buildResidentsString(avatar_names, ui_title);
-			updateSessionName(ui_title, ui_title);
-		}
-}
+		std::string ui_title;
+		build_names_string(temp_uuids, ui_title);
+		updateSessionName(ui_title, ui_title);
+	}
 }
 
 //static
@@ -1215,7 +1163,7 @@ bool LLIMFloater::dropPerson(LLUUID* person_id, bool drop)
 		res = canAddSelectedToChat(ids);
 		if(res && drop)
 		{
-			onAddSessionParticipants(ids);
+			addSessionParticipants(ids);
 		}
 	}
 
@@ -1254,37 +1202,32 @@ BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 
 	if (is_region_exist)
 	{
-	S32 count = ids.size();
+		S32 count = ids.size();
 
-	if( isInviteAllowed() && (count > 0) )
-	{
-		llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
-
-		std::string url = region->getCapability("ChatSessionRequest");
+		if( isInviteAllowed() && (count > 0) )
+		{
+			llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
 
-		LLSD data;
+			std::string url = region->getCapability("ChatSessionRequest");
 
-		data["params"] = LLSD::emptyArray();
-		for (int i = 0; i < count; i++)
+			LLSD data;
+			data["params"] = LLSD::emptyArray();
+			for (int i = 0; i < count; i++)
+			{
+				data["params"].append(ids[i]);
+			}
+			data["method"] = "invite";
+			data["session-id"] = mSessionID;
+			LLHTTPClient::post(url,	data,new LLSessionInviteResponder(mSessionID));
+		}
+		else
 		{
-			data["params"].append(ids[i]);
+			llinfos << "LLIMFloater::inviteToSession -"
+					<< " no need to invite agents for "
+					<< mDialog << llendl;
+			// successful add, because everyone that needed to get added
+			// was added.
 		}
-
-		data["method"] = "invite";
-		data["session-id"] = mSessionID;
-		LLHTTPClient::post(
-			url,
-			data,
-					new LLSessionInviteResponder(mSessionID));
-	}
-	else
-	{
-		llinfos << "LLIMFloater::inviteToSession -"
-				<< " no need to invite agents for "
-				<< mDialog << llendl;
-		// successful add, because everyone that needed to get added
-		// was added.
-	}
 	}
 
 	return is_region_exist;
@@ -1414,3 +1357,25 @@ boost::signals2::connection LLIMFloater::setIMFloaterShowedCallback(const floate
 {
 	return LLIMFloater::sIMFloaterShowedSignal.connect(cb);
 }
+
+// static
+void build_names_string(const uuid_vec_t& uuids, std::string& names_string)
+{
+	std::vector<LLAvatarName> avatar_names;
+	uuid_vec_t::const_iterator it = uuids.begin();
+	for (; it != uuids.end(); ++it)
+	{
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(*it, &av_name))
+		{
+			avatar_names.push_back(av_name);
+		}
+	}
+
+	// We should check whether the vector is not empty to pass the assertion
+	// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
+	if (!avatar_names.empty())
+	{
+		LLAvatarActions::buildResidentsString(avatar_names, names_string);
+	}
+}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index d98213b54c..4e09a24a09 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -89,7 +89,8 @@ public:
 	void updateMessages();
 	void reloadMessages();
 	static void onSendMsg(LLUICtrl*, void*);
-	void sendMsg();
+	void sendMsgFromInputEditor();
+	void sendMsg(const std::string& msg);
 
 	// callback for LLIMModel on new messages
 	// route to specific floater if it is visible
@@ -160,8 +161,9 @@ private:
 	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
 	void setTyping(bool typing);
 	void onAddButtonClicked();
-	void onAddSessionParticipants(const uuid_vec_t& uuids);
-	void addSessionParticipants(const LLSD& notification, const LLSD& response);
+	void addSessionParticipants(const uuid_vec_t& uuids);
+	void addP2PSessionParticipants(const uuid_vec_t& uuids);
+	void sendParticipantsAddedNotification(const uuid_vec_t& uuids);
 	bool canAddSelectedToChat(const uuid_vec_t& uuids);
 
 	void onCallButtonClicked();
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 2b63430106..de8d5f22fd 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -35,11 +35,14 @@
      name="return_icon"
      value="Conv_toolbar_arrow_sw"/>
     <floater.string
-     name="participants_added"
-     value="New participant(s) were invited to the conversation: [NAMES]."/>
+     name="participant_added"
+     value="[NAME] was invited to the conversation.[NEW_WINDOW]"/>
     <floater.string
-     name="participants_added_new_window"
-     value="New participant(s) were invited to the conversation: [NAMES]. The conversation will be started in a new window."/>
+     name="multiple_participants_added"
+     value="[NAME] were invited to the conversation.[NEW_WINDOW]"/>
+    <floater.string
+     name="new_window"
+     value=" The conversation will be started in a new window."/>
     <view
         follows="all"
         layout="topleft"
-- 
cgit v1.2.3


From a06256838cfc59c59d50bca0d75ad1b121bdd096 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 10 Aug 2012 17:13:16 +0300
Subject: build fix

---
 indra/newview/llimconversation.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 94a3a7781b..f21be94ee2 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -95,6 +95,9 @@ protected:
 	void hideOrShowTitle(); // toggle the floater's drag handle
 	void hideAllStandardButtons();
 
+	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
+	void updateHeaderAndToolbar();
+
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
 
@@ -114,8 +117,6 @@ private:
 	/// Refreshes the floater at a constant rate.
 	virtual void refresh() = 0;
 
-	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
-	void updateHeaderAndToolbar();
 
 	/**
 	 * Adjusts chat history height to fit vertically with input chat field
-- 
cgit v1.2.3


From f4c4df4cdd3dae7ce90efb8fbea8af1ba66410ff Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 10 Aug 2012 17:39:46 +0300
Subject: fix incorrect merge

---
 indra/newview/llimfloatercontainer.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 1896ed65f3..ad3b0279e5 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -73,6 +73,11 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 	}
 }
 
+void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+	addConversationListItem(session_id);
+}
+
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
 	LLIMFloater::show(session_id);
-- 
cgit v1.2.3


From 09c890db98bb0996058e9faf1f867650707e3e31 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 10 Aug 2012 19:03:37 +0300
Subject: fixed merge issue. Done.

---
 indra/newview/llimfloatercontainer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index ad3b0279e5..38b5768a60 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -317,7 +317,7 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	if (visible)
 	{
 		// Make sure we have the Nearby Chat present when showing the conversation container
-		LLIMConversation* nearby_chat = LLIMConversation::getConversation(LLUUID::null);
+		LLIMConversation* nearby_chat = LLIMConversation::findConversation(LLUUID::null);
 		if (nearby_chat == NULL)
 		{
 			// If not found, force the creation of the nearby chat conversation panel
-- 
cgit v1.2.3


From 52814c4e99f62815af85d1270f3268ef37adcb49 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 10 Aug 2012 17:09:14 -0700
Subject: CHUI-273: Problem was that after renaming the item, the item was not
 triggering a sort. Resolution: Once the name of the item is set, trigger a
 sorting of the parent.

---
 indra/llui/llfolderviewitem.cpp     |  5 -----
 indra/newview/llinventorybridge.cpp | 12 ++++++++++++
 2 files changed, 12 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 68b442dd9a..1c33c4489b 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -415,11 +415,6 @@ void LLFolderViewItem::rename(const std::string& new_name)
 	if( !new_name.empty() )
 	{
 		getViewModelItem()->renameItem(new_name);
-
-		//if(mParentFolder)
-		//{
-		//	mParentFolder->requestSort();
-		//}
 	}
 }
 
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 43c4ce1278..6c3aaf5eec 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1553,6 +1553,12 @@ void LLItemBridge::buildDisplayName() const
 	mSearchableName.assign(mDisplayName);
 	mSearchableName.append(getLabelSuffix());
 	LLStringUtil::toUpper(mSearchableName);
+
+    //Name set, so trigger a sort
+    if(mParent)
+    {
+        mParent->requestSort();
+    }
 }
 
 LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
@@ -1859,6 +1865,12 @@ void LLFolderBridge::buildDisplayName() const
 	mSearchableName.assign(mDisplayName);
 	mSearchableName.append(getLabelSuffix());
 	LLStringUtil::toUpper(mSearchableName);
+
+    //Name set, so trigger a sort
+    if(mParent)
+    {
+        mParent->requestSort();
+    }
 }
 
 
-- 
cgit v1.2.3


From c01254daf16adb3d91ad8990ba5c66d2b51eae45 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 14 Aug 2012 16:05:47 +0300
Subject: CHUI-171, CHUI-272 conversation is added as docked in conversation
 floater when session started (without click on an conv. list's item)

---
 indra/newview/llimfloatercontainer.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 38b5768a60..fe47e03beb 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -75,6 +75,7 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
+	LLIMFloater::show(session_id);
 	addConversationListItem(session_id);
 }
 
-- 
cgit v1.2.3


From 039cc929d09828b449d3d9ec29c9ea297af56088 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Wed, 15 Aug 2012 15:03:19 +0300
Subject: CHUI-257 FIXED (Using clear cache option in preferences clears call
 log also)

- Changed location where call log file is saved. Now it's saved with other user settings files under each avatar's directory in the user settings directory.
---
 indra/newview/llconversationlog.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 137b97326c..b6713465f3 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -241,7 +241,7 @@ std::string LLConversationLog::getFileName()
 	std::string agent_id_string;
 	gAgent.getID().toString(agent_id_string);
 
-	return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, agent_id_string) + ".call_log";
+	return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, agent_id_string) + ".call_log";
 }
 
 bool LLConversationLog::saveToFile(const std::string& filename)
-- 
cgit v1.2.3


From c234ef4b3a1ab22132512958c324e5f796912144 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Wed, 15 Aug 2012 15:06:25 +0300
Subject: CHUI-235 FIXED (Create icons for new conversation log list items)

- Replaced old icons with new ones
---
 .../skins/default/textures/icons/Conv_log_inbox.png       | Bin 0 -> 556 bytes
 indra/newview/skins/default/textures/textures.xml         |   1 +
 .../default/xui/en/panel_conversation_log_list_item.xml   |   9 ++++-----
 3 files changed, 5 insertions(+), 5 deletions(-)
 create mode 100644 indra/newview/skins/default/textures/icons/Conv_log_inbox.png

(limited to 'indra')

diff --git a/indra/newview/skins/default/textures/icons/Conv_log_inbox.png b/indra/newview/skins/default/textures/icons/Conv_log_inbox.png
new file mode 100644
index 0000000000..bb6ca28147
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_log_inbox.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 212f05d284..47b0c12fa0 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -176,6 +176,7 @@ with the same filename but different name
   <texture name="Conv_toolbar_open_call" file_name="icons/Conv_toolbar_open_call.png" preload="false" />
   <texture name="Conv_toolbar_plus" file_name="icons/Conv_toolbar_plus.png" preload="false" />
   <texture name="Conv_toolbar_sort" file_name="icons/Conv_toolbar_sort.png" preload="false" />
+  <texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
 
   <texture name="Copy" file_name="icons/Copy.png" preload="false" />
   
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
index 3c98e32e7d..cee7d8581a 100644
--- a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
@@ -33,19 +33,18 @@
      height="20"
      layout="topleft"
      left="5"
-     image_name="Audio_Press"
+     image_name="Conv_toolbar_open_call"
      mouse_opaque="true"
      name="voice_session_icon"
      top="2"
      visible="false"
      width="20" />
     <icon
-     default_icon_name="incoming_unread_im_icon"
      follows="top|left"
      height="20"
      layout="topleft"
      left="5"
-     image_name="Movement_Backward_Off"
+     image_name="Conv_log_inbox"
      mouse_opaque="false"
      name="unread_ims_icon"
      top="2"
@@ -98,8 +97,8 @@
      name="delete_btn"
      layout="topleft"
      follows="top|right"
-     image_unselected="Toast_CloseBtn"
-     image_selected="Toast_CloseBtn"
+     image_unselected="Conv_toolbar_close"
+     image_selected="Conv_toolbar_close"
      top="5"
      left_pad="0"
      height="14"
-- 
cgit v1.2.3


From 3a21eb59f1cf0b7672e2beb671e1dbc717e28b3f Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 15 Aug 2012 20:10:00 +0300
Subject: CHUI-286 (Conversations floater opened by default when a new IM
 session is started (no IM toast shown): now floater silently adds itself to
 the container

---
 indra/newview/llimconversation.cpp     |  3 +-
 indra/newview/llimfloater.cpp          | 91 +++++++++++++++++-----------------
 indra/newview/llimfloater.h            |  1 +
 indra/newview/llimfloatercontainer.cpp |  6 +--
 indra/newview/llnearbychat.cpp         |  1 -
 5 files changed, 50 insertions(+), 52 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index ec25583c8f..4ca9476458 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -153,6 +153,7 @@ void LLIMConversation::draw()
 		}
 
 		refresh();
+		updateHeaderAndToolbar();
 
 		// Restart the refresh timer
 		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
@@ -265,7 +266,7 @@ void LLIMConversation::hideAllStandardButtons()
 
 void LLIMConversation::updateHeaderAndToolbar()
 {
-	bool is_torn_off = isTornOff();
+	bool is_torn_off = !getHost();
 	if (!is_torn_off)
 	{
 		hideAllStandardButtons();
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 6a1437f318..cdd5ba6889 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -128,7 +128,7 @@ void LLIMFloater::onClickCloseBtn()
 
 	if (session == NULL)
 	{
-		llwarns << "Empty session." << llendl;
+		llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl;
 		return;
 }
 
@@ -250,7 +250,7 @@ void LLIMFloater::initIMSession(const LLUUID& session_id)
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
 	if (mSession)
-{
+    {
 		mIsP2PChat = mSession->isP2PSessionType();
 		mSessionInitialized = mSession->mSessionInitialized;
 
@@ -593,38 +593,19 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 }
 
 //static
-LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
+LLIMFloater* LLIMFloater::addToIMContainer(const LLUUID& session_id)
 {
-	closeHiddenIMToasts();
-
 	if (!gIMMgr->hasSession(session_id))
 		return NULL;
 
-	if(!isChatMultiTab())
-	{
-		//hide all
-		LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
-		for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
-			 iter != inst_list.end(); ++iter)
-		{
-			LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
-			if (floater && floater->isDocked())
-			{
-				floater->setVisible(false);
-			}
-		}
-	}
-
 	// Test the existence of the floater before we try to create it
 	bool exist = findInstance(session_id);
 
 	// Get the floater: this will create the instance if it didn't exist
 	LLIMFloater* floater = getInstance(session_id);
-	if (!floater)
-		return NULL;
-
-	if(isChatMultiTab())
+	if (floater)
 	{
+
 		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
 
 		// Do not add again existing floaters
@@ -639,33 +620,51 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 			}
 		}
 
-		floater->openFloater(floater->getKey());
+		if (floater_container && floater_container->getVisible())
+		{
+			floater->openFloater(floater->getKey());
+			floater->setVisible(TRUE);
+		}
+		else
+		{
+			floater->setVisible(FALSE);
+		}
 	}
-	else
-	{
-		// Docking may move chat window, hide it before moving, or user will see how window "jumps"
-		floater->setVisible(false);
+	return floater;
+}
 
-		if (floater->getDockControl() == NULL)
-		{
-			LLChiclet* chiclet =
-					LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(
-							session_id);
-			if (chiclet == NULL)
-			{
-				llerror("Dock chiclet for LLIMFloater doesn't exists", 0);
-			}
-			else
-			{
-				LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet);
-			}
+//static
+LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
+{
+	closeHiddenIMToasts();
 
-			floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
-					LLDockControl::BOTTOM));
-		}
+	if (!gIMMgr->hasSession(session_id))
+		return NULL;
 
-		// window is positioned, now we can show it.
+	// Test the existence of the floater before we try to create it
+	bool exist = findInstance(session_id);
+
+	// Get the floater: this will create the instance if it didn't exist
+	LLIMFloater* floater = getInstance(session_id);
+	if (!floater)
+		return NULL;
+
+	LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
+
+	// Do not add again existing floaters
+	if (!exist)
+	{
+		//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
+		// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
+		LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
+		if (floater_container)
+		{
+			floater_container->addFloater(floater, TRUE, i_pt);
+		}
 	}
+
+	floater->openFloater(floater->getKey());
+
 	floater->setVisible(TRUE);
 
 	return floater;
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 434613ff43..d528c77e8d 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -78,6 +78,7 @@ public:
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
 	// Make IM conversion visible and update the message history
 	static LLIMFloater* show(const LLUUID& session_id);
+	static LLIMFloater* addToIMContainer(const LLUUID& session_id);
 
 	// Toggle panel specified by session_id
 	// Returns true iff panel became visible
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index fe47e03beb..bcad7adcce 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -75,13 +75,13 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	LLIMFloater::show(session_id);
+	LLIMFloater::addToIMContainer(session_id);
 	addConversationListItem(session_id);
 }
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	LLIMFloater::show(session_id);
+	LLIMFloater::addToIMContainer(session_id);
 	addConversationListItem(session_id);
 }
 
@@ -93,8 +93,6 @@ void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const
 
 void LLIMFloaterContainer::sessionRemoved(const LLUUID& session_id)
 {
-	LLIMFloater* floaterp = LLIMFloater::findInstance(session_id);
-	LLFloater::onClickClose(floaterp);
 	removeConversationListItem(session_id);
 }
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index fa8e423056..e1454fb5dc 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -183,7 +183,6 @@ BOOL LLNearbyChat::postBuild()
 // virtual
 void LLNearbyChat::refresh()
 {
-	updateHeaderAndToolbar();
 	displaySpeakingIndicator();
 	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
 
-- 
cgit v1.2.3


From effccb94489d41a533e76f5f5834d52e3e817cbd Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 16 Aug 2012 04:55:48 +0300
Subject: CHUI-120 WIP Notifications about added chat participants should be
 sent to the conference when those participants actually join. - Removed
 notifying existing P2P participants about ad hoc conference staring in a new
 window. Now the notifications should arrive in that new window. - Fixed
 "Cancel" button which had no effect in adding P2P participants notification.

---
 indra/newview/llimfloater.cpp                      | 131 ++++++++++++++-------
 indra/newview/llimfloater.h                        |   4 +-
 .../skins/default/xui/en/floater_im_session.xml    |   7 +-
 3 files changed, 94 insertions(+), 48 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index c3c9e334f2..0f0048b0d0 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -127,14 +127,13 @@ void LLIMFloater::refresh()
 // virtual
 void LLIMFloater::onClickCloseBtn()
 {
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				mSessionID);
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
 
 	if (session == NULL)
 	{
 		llwarns << "Empty session." << llendl;
 		return;
-}
+	}
 
 	bool is_call_with_chat = session->isGroupSessionType()
 			|| session->isAdHocSessionType() || session->isP2PSessionType();
@@ -228,7 +227,7 @@ void LLIMFloater::sendMsg(const std::string& msg)
 
 	if (mSessionInitialized)
 	{
-			LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
+		LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
 	}
 	else
 	{
@@ -261,7 +260,7 @@ void LLIMFloater::initIMSession(const LLUUID& session_id)
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
 	if (mSession)
-{
+	{
 		mIsP2PChat = mSession->isP2PSessionType();
 		mSessionInitialized = mSession->mSessionInitialized;
 
@@ -411,7 +410,7 @@ bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
 		if (speaker_mgr)
 		{
 			speaker_mgr->getSpeakerList(&speaker_list, true);
-	}
+		}
 	
 		for (uuid_vec_t::const_iterator id = uuids.begin();
 				id != uuids.end(); ++id)
@@ -439,19 +438,24 @@ void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids)
 		LLSD args;
 
 		LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload,
-				boost::bind(&LLIMFloater::addP2PSessionParticipants, this, uuids));
+				boost::bind(&LLIMFloater::addP2PSessionParticipants, this, _1, _2, uuids));
 	}
 	else
 	{
-		sendParticipantsAddedNotification(uuids);
-
+		// remember whom we have invited, to notify others later, when the invited ones actually join
+		mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+		
 		inviteToSession(uuids);
 	}
 }
 
-void LLIMFloater::addP2PSessionParticipants(const uuid_vec_t& uuids)
+void LLIMFloater::addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids)
 {
-	sendParticipantsAddedNotification(uuids);
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (option != 0)
+	{
+		return;
+	}
 
 	mStartConferenceInSameFloater = true;
 
@@ -469,6 +473,12 @@ void LLIMFloater::addP2PSessionParticipants(const uuid_vec_t& uuids)
 	// then we can close the current session
 	onClose(false);
 
+	// we start a new session so reset the initialization flag
+	mSessionInitialized = false;
+
+	// remember whom we have invited, to notify others later, when the invited ones actually join
+	mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+
 	// Start a new ad hoc voice call if we invite new participants to a P2P call,
 	// or start a text chat otherwise.
 	if (is_voice_call)
@@ -487,7 +497,6 @@ void LLIMFloater::sendParticipantsAddedNotification(const uuid_vec_t& uuids)
 	build_names_string(uuids, names_string);
 	LLStringUtil::format_map_t args;
 	args["[NAME]"] = names_string;
-	args["[NEW_WINDOW]"] = mIsP2PChat ? getString("new_window") : LLStringUtil::null;
 
 	sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args));
 }
@@ -865,18 +874,20 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
 
-	//need to send delayed messaged collected while waiting for session initialization
+	//need to send delayed messages collected while waiting for session initialization
 	if (mQueuedMsgsForInit.size())
 	{
-	LLSD::array_iterator iter;
-	for ( iter = mQueuedMsgsForInit.beginArray();
-				iter != mQueuedMsgsForInit.endArray(); ++iter)
-	{
-		LLIMModel::sendMessage(iter->asString(), mSessionID,
-			mOtherParticipantUUID, mDialog);
+		LLSD::array_iterator iter;
+		for ( iter = mQueuedMsgsForInit.beginArray();
+					iter != mQueuedMsgsForInit.endArray(); ++iter)
+		{
+			LLIMModel::sendMessage(iter->asString(), mSessionID,
+				mOtherParticipantUUID, mDialog);
+		}
+
+		mQueuedMsgsForInit.clear();
 	}
 }
-}
 
 void LLIMFloater::appendMessage(const LLChat& chat, const LLSD &args)
 {
@@ -1044,19 +1055,18 @@ void LLIMFloater::setTyping(bool typing)
 		{
 			LLIMModel::instance().sendTypingState(mSessionID,
 					mOtherParticipantUUID, mMeTyping);
-				mShouldSendTypingState = false;
-
-			}
+					mShouldSendTypingState = false;
 		}
+	}
 
 	if (!mIsNearbyChat)
+	{
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if (speaker_mgr)
 		{
-	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-	if (speaker_mgr)
-		{
-		speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
+			speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
 		}
-}
+	}
 }
 
 void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
@@ -1075,29 +1085,66 @@ void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
 
 void LLIMFloater::processAgentListUpdates(const LLSD& body)
 {
+	uuid_vec_t joined_uuids;
+
 	if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap())
 	{
-		LLSD agent_data = body["agent_updates"].get(gAgentID.asString());
-		if (agent_data.isMap() && agent_data.has("info"))
+		LLSD::map_const_iterator update_it;
+		for(update_it = body["agent_updates"].beginMap();
+			update_it != body["agent_updates"].endMap();
+			++update_it)
 		{
-			LLSD agent_info = agent_data["info"];
+			LLUUID agent_id(update_it->first);
+			LLSD agent_data = update_it->second;
 
-			if (agent_info.has("mutes"))
+			if (agent_data.isMap())
 			{
-				BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean(); 
-				mInputEditor->setEnabled(!moderator_muted_text);
-				std::string label;
-				if (moderator_muted_text)
-					label = LLTrans::getString("IM_muted_text_label");
-				else
-					label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
-				mInputEditor->setLabel(label);
+				// store the new participants in joined_uuids
+				if (agent_data.has("transition") && agent_data["transition"].asString() == "ENTER")
+				{
+					joined_uuids.push_back(agent_id);
+				}
 
-				if (moderator_muted_text)
-					LLNotificationsUtil::add("TextChatIsMutedByModerator");
+				// process the moderator mutes
+				if (agent_id == gAgentID && agent_data.has("info") && agent_data["info"].has("mutes"))
+				{
+					BOOL moderator_muted_text = agent_data["info"]["mutes"]["text"].asBoolean();
+					mInputEditor->setEnabled(!moderator_muted_text);
+					std::string label;
+					if (moderator_muted_text)
+						label = LLTrans::getString("IM_muted_text_label");
+					else
+						label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
+					mInputEditor->setLabel(label);
+
+					if (moderator_muted_text)
+						LLNotificationsUtil::add("TextChatIsMutedByModerator");
+				}
 			}
 		}
 	}
+
+	// the vectors need to be sorted for computing the intersection and difference
+	std::sort(mInvitedParticipants.begin(), mInvitedParticipants.end());
+    std::sort(joined_uuids.begin(), joined_uuids.end());
+
+    uuid_vec_t intersection; // uuids of invited residents who have joined the conversation
+	std::set_intersection(mInvitedParticipants.begin(), mInvitedParticipants.end(),
+						  joined_uuids.begin(), joined_uuids.end(),
+						  std::back_inserter(intersection));
+
+	if (intersection.size() > 0)
+	{
+		sendParticipantsAddedNotification(intersection);
+	}
+
+	// Remove all joined participants from invited array.
+	// The difference between the two vectors (the elements in mInvitedParticipants which are not in joined_uuids)
+	// is placed at the beginning of mInvitedParticipants, then all other elements are erased.
+	mInvitedParticipants.erase(std::set_difference(mInvitedParticipants.begin(), mInvitedParticipants.end(),
+												   joined_uuids.begin(), joined_uuids.end(),
+												   mInvitedParticipants.begin()),
+							   mInvitedParticipants.end());
 }
 
 void LLIMFloater::processSessionUpdate(const LLSD& session_update)
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 4e09a24a09..f78fa46b6e 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -162,7 +162,7 @@ private:
 	void setTyping(bool typing);
 	void onAddButtonClicked();
 	void addSessionParticipants(const uuid_vec_t& uuids);
-	void addP2PSessionParticipants(const uuid_vec_t& uuids);
+	void addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids);
 	void sendParticipantsAddedNotification(const uuid_vec_t& uuids);
 	bool canAddSelectedToChat(const uuid_vec_t& uuids);
 
@@ -204,6 +204,8 @@ private:
 
 	bool mStartConferenceInSameFloater;
 
+	uuid_vec_t mInvitedParticipants;
+
 	// connection to voice channel state change signal
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index de8d5f22fd..15d3dc30ae 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -36,13 +36,10 @@
      value="Conv_toolbar_arrow_sw"/>
     <floater.string
      name="participant_added"
-     value="[NAME] was invited to the conversation.[NEW_WINDOW]"/>
+     value="[NAME] was invited to the conversation."/>
     <floater.string
      name="multiple_participants_added"
-     value="[NAME] were invited to the conversation.[NEW_WINDOW]"/>
-    <floater.string
-     name="new_window"
-     value=" The conversation will be started in a new window."/>
+     value="[NAME] were invited to the conversation."/>
     <view
         follows="all"
         layout="topleft"
-- 
cgit v1.2.3


From bec60ef80e72ab6df8ae0bf6b7a7824e8504426a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 20 Aug 2012 16:11:03 -0700
Subject: CHUI-295: Problem: The places panel implemention was incomplete and
 trying to make use of a class that was not fully implemented
 (placesfolderview). Resoltuion: Upon creation of the places panel,
 placesfolderview is created which contains the proper overloaded functions to
 show the correct menu when right clicking.

---
 indra/newview/CMakeLists.txt             |  2 +
 indra/newview/llinventorypanel.cpp       | 48 +++++++++---------
 indra/newview/llinventorypanel.h         |  1 +
 indra/newview/llpanellandmarks.cpp       |  1 +
 indra/newview/llplacesfolderview.cpp     | 74 +++++++++++++++++++++++++++
 indra/newview/llplacesfolderview.h       | 72 ++++++++++++++++++++++++++
 indra/newview/llplacesinventorypanel.cpp | 86 +++++++++++---------------------
 indra/newview/llplacesinventorypanel.h   | 33 +-----------
 8 files changed, 206 insertions(+), 111 deletions(-)
 create mode 100644 indra/newview/llplacesfolderview.cpp
 create mode 100644 indra/newview/llplacesfolderview.h

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 70493b1214..9553476aaf 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -445,6 +445,7 @@ set(viewer_SOURCE_FILES
     llphysicsshapebuilderutil.cpp
     llplacesinventorybridge.cpp
     llplacesinventorypanel.cpp
+    llplacesfolderview.cpp
     llpopupview.cpp
     llpolymesh.cpp
     llpolymorph.cpp
@@ -1015,6 +1016,7 @@ set(viewer_HEADER_FILES
     llphysicsshapebuilderutil.h
     llplacesinventorybridge.h
     llplacesinventorypanel.h
+    llplacesfolderview.h
     llpolymesh.h
     llpolymorph.h
     llpopupview.h
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 22e6943f50..03dfada77c 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -151,6 +151,30 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 
 }
 
+LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
+{
+    LLFolderView::Params p(mParams.folder_view);
+    p.name = getName();
+    p.title = getLabel();
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = this;
+    p.tool_tip = p.name;
+    p.listener = mInvFVBridgeBuilder->createBridge(	LLAssetType::AT_CATEGORY,
+        LLAssetType::AT_CATEGORY,
+        LLInventoryType::IT_CATEGORY,
+        this,
+        &mInventoryViewModel,
+        NULL,
+        root_id);
+    p.view_model = &mInventoryViewModel;
+    p.use_label_suffix = mParams.use_label_suffix;
+    p.allow_multiselect = mAllowMultiSelect;
+    p.show_empty_message = mShowEmptyMessage;
+    p.show_item_link_overlays = mShowItemLinkOverlays;
+    p.root = NULL;
+
+    return LLUICtrlFactory::create<LLFolderView>(p);
+}
 	
 void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	{
@@ -172,29 +196,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	{
 		// Determine the root folder in case specified, and
 		// build the views starting with that folder.
-	
-
-		LLFolderView::Params p(mParams.folder_view);
-		p.name = getName();
-		p.title = getLabel();
-		p.rect = LLRect(0, 0, getRect().getWidth(), 0);
-		p.parent_panel = this;
-		p.tool_tip = p.name;
-		p.listener = mInvFVBridgeBuilder->createBridge(	LLAssetType::AT_CATEGORY,
-																	LLAssetType::AT_CATEGORY,
-																	LLInventoryType::IT_CATEGORY,
-																	this,
-														&mInventoryViewModel,
-																	NULL,
-																	root_id);
-		p.view_model = &mInventoryViewModel;
-		p.use_label_suffix = mParams.use_label_suffix;
-		p.allow_multiselect = mAllowMultiSelect;
-		p.show_empty_message = mShowEmptyMessage;
-		p.show_item_link_overlays = mShowItemLinkOverlays;
-		p.root = NULL;
-
-		mFolderRoot = LLUICtrlFactory::create<LLFolderView>(p);
+		mFolderRoot = createFolderRoot(root_id);
 	
 		addItemID(root_id, mFolderRoot);
 }
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index e9bfcb0ccf..c4f3c1b47d 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -278,6 +278,7 @@ protected:
 	LLFolderViewItem*	buildNewViews(const LLUUID& id);
 	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const;
 	
+    virtual LLFolderView * createFolderRoot(LLUUID root_id );
 	virtual LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge);
 	virtual LLFolderViewItem*	createFolderViewItem(LLInvFVBridge * bridge);
 private:
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 9225ea3d53..469656c33f 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -52,6 +52,7 @@
 #include "llmenubutton.h"
 #include "llplacesinventorybridge.h"
 #include "llplacesinventorypanel.h"
+#include "llplacesfolderview.h"
 #include "lltoggleablemenu.h"
 #include "llviewermenu.h"
 #include "llviewerregion.h"
diff --git a/indra/newview/llplacesfolderview.cpp b/indra/newview/llplacesfolderview.cpp
new file mode 100644
index 0000000000..3caa93ae71
--- /dev/null
+++ b/indra/newview/llplacesfolderview.cpp
@@ -0,0 +1,74 @@
+/** 
+* @file llplacesfolderview.cpp
+* @brief llplacesfolderview used within llplacesinventorypanel
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llplacesfolderview.h"
+
+#include "llplacesinventorypanel.h"
+#include "llpanellandmarks.h"
+
+LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p)
+    : LLFolderView(p)
+{
+    // we do not need auto select functionality in places landmarks, so override default behavior.
+    // this disables applying of the LLSelectFirstFilteredItem in LLFolderView::doIdle.
+    // Fixed issues: EXT-1631, EXT-4994.
+    mAutoSelectOverride = TRUE;
+}
+
+BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+    // let children to change selection first
+    childrenHandleRightMouseDown(x, y, mask);
+    mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel());
+
+    // then determine its type and set necessary menu handle
+    if (getCurSelectedItem())
+    {
+        LLInventoryType::EType inventory_type = static_cast<LLFolderViewModelItemInventory*>(getCurSelectedItem()->getViewModelItem())->getInventoryType();
+        inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
+
+        if (it_handle != mMenuHandlesByInventoryType.end())
+        {
+            mPopupMenuHandle = (*it_handle).second;
+        }
+        else
+        {
+            llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl;
+        }
+
+    }
+
+    return LLFolderView::handleRightMouseDown(x, y, mask);
+}
+
+void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle)
+{
+    mMenuHandlesByInventoryType[asset_type] = menu_handle;
+}
+
diff --git a/indra/newview/llplacesfolderview.h b/indra/newview/llplacesfolderview.h
new file mode 100644
index 0000000000..8c5be39b5e
--- /dev/null
+++ b/indra/newview/llplacesfolderview.h
@@ -0,0 +1,72 @@
+/** 
+* @file   llplacesfolderview.h
+* @brief  llplacesfolderview used within llplacesinventorypanel
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLPLACESFOLDERVIEW_H
+#define LL_LLPLACESFOLDERVIEW_H
+
+#include "llfolderview.h"
+#include "llinventorypanel.h"
+
+class LLLandmarksPanel;
+
+class LLPlacesFolderView : public LLFolderView
+{
+public:
+
+    struct Params : public LLInitParam::Block<Params, LLFolderView::Params>
+    {
+        Params()
+		{}
+    };
+
+	LLPlacesFolderView(const LLFolderView::Params& p);
+	/**
+	 *	Handles right mouse down
+	 *
+	 * Contains workaround for EXT-2786: sets current selected list for landmark
+	 * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel
+	 */
+	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+
+	void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle);
+
+	void setParentLandmarksPanel(LLLandmarksPanel* panel)
+	{
+		mParentLandmarksPanel = panel;
+	}
+
+private:
+	/**
+	 * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown
+	 */
+	LLLandmarksPanel* mParentLandmarksPanel;
+	typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t;
+	inventory_type_menu_handle_t mMenuHandlesByInventoryType;
+
+};
+
+#endif // LL_LLPLACESFOLDERVIEW_H
+
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index db3f245389..01586a4d91 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -31,7 +31,7 @@
 #include "llplacesinventorypanel.h"
 
 #include "llfolderviewmodel.h"
-#include "llfolderview.h"
+#include "llplacesfolderview.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 #include "llpanellandmarks.h"
@@ -58,6 +58,34 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()
 	delete mSavedFolderState;
 }
 
+
+LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )
+{
+    LLPlacesFolderView::Params p;
+    
+    p.name = getName();
+    p.title = getLabel();
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = this;
+    p.tool_tip = p.name;
+    p.listener = mInvFVBridgeBuilder->createBridge(	LLAssetType::AT_CATEGORY,
+        LLAssetType::AT_CATEGORY,
+        LLInventoryType::IT_CATEGORY,
+        this,
+        &mInventoryViewModel,
+        NULL,
+        root_id);
+    p.view_model = &mInventoryViewModel;
+    p.use_label_suffix = mParams.use_label_suffix;
+    p.allow_multiselect = mAllowMultiSelect;
+    p.show_empty_message = mShowEmptyMessage;
+    p.show_item_link_overlays = mShowItemLinkOverlays;
+    p.root = NULL;
+    p.use_ellipses = mParams.folder_view.use_ellipses;
+
+    return LLUICtrlFactory::create<LLPlacesFolderView>(p);
+}
+
 // save current folder open state
 void LLPlacesInventoryPanel::saveFolderState()
 {
@@ -91,59 +119,3 @@ S32	LLPlacesInventoryPanel::notify(const LLSD& info)
 	}
 	return 0;
 }
-
-/************************************************************************/
-/* PROTECTED METHODS                                                    */
-/************************************************************************/
-
-
-
-/************************************************************************/
-/*              LLPlacesFolderView implementation                       */
-/************************************************************************/
-
-//////////////////////////////////////////////////////////////////////////
-//  PUBLIC METHODS
-//////////////////////////////////////////////////////////////////////////
-
-LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p)
-: LLFolderView(p)
-{
-	// we do not need auto select functionality in places landmarks, so override default behavior.
-	// this disables applying of the LLSelectFirstFilteredItem in LLFolderView::doIdle.
-	// Fixed issues: EXT-1631, EXT-4994.
-	mAutoSelectOverride = TRUE;
-}
-
-BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-	// let children to change selection first
-	childrenHandleRightMouseDown(x, y, mask);
-	mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel());
-
-	// then determine its type and set necessary menu handle
-	if (getCurSelectedItem())
-	{
-		LLInventoryType::EType inventory_type = static_cast<LLFolderViewModelItemInventory*>(getCurSelectedItem()->getViewModelItem())->getInventoryType();
-		inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
-
-		if (it_handle != mMenuHandlesByInventoryType.end())
-		{
-			mPopupMenuHandle = (*it_handle).second;
-		}
-		else
-		{
-			llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl;
-		}
-
-	}
-
-	return LLFolderView::handleRightMouseDown(x, y, mask);
-}
-
-void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle)
-{
-	mMenuHandlesByInventoryType[asset_type] = menu_handle;
-}
-
-// EOF
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index 1544b51aed..2805fc4257 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -29,9 +29,9 @@
 
 #include "llfloaterinventory.h"
 #include "llinventorypanel.h"
-#include "llfolderview.h"
 
 class LLLandmarksPanel;
+class LLFolderView;
 
 class LLPlacesInventoryPanel : public LLInventoryPanel
 {
@@ -46,6 +46,7 @@ public:
 	LLPlacesInventoryPanel(const Params& p);
 	~LLPlacesInventoryPanel();
 
+    LLFolderView * createFolderRoot(LLUUID root_id );
 	void saveFolderState();
 	void restoreFolderState();
 
@@ -55,34 +56,4 @@ private:
 	LLSaveFolderState*			mSavedFolderState;
 };
 
-//TODO RN: this class is currently unused, make sure that behavior remains
-class LLPlacesFolderView : public LLFolderView
-{
-public:
-	LLPlacesFolderView(const LLFolderView::Params& p);
-	/**
-	 *	Handles right mouse down
-	 *
-	 * Contains workaround for EXT-2786: sets current selected list for landmark
-	 * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel
-	 */
-	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
-
-	void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle);
-
-	void setParentLandmarksPanel(LLLandmarksPanel* panel)
-	{
-		mParentLandmarksPanel = panel;
-	}
-
-private:
-	/**
-	 * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown
-	 */
-	LLLandmarksPanel* mParentLandmarksPanel;
-	typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t;
-	inventory_type_menu_handle_t mMenuHandlesByInventoryType;
-
-};
-
 #endif //LL_LLINVENTORYSUBTREEPANEL_H
-- 
cgit v1.2.3


From 0fc67126fe1c082caf640cba6b63ce9a0438cc23 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 20 Aug 2012 18:38:55 +0300
Subject: CHUI-290 FIXED (User cannot collapse names in ad hoc conversation
 when changed from p2p to ad hoc in torn off state): detect new collapse
 button state after rebuild of a participant list

---
 indra/newview/llimconversation.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 4ca9476458..ee7f58b01f 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -177,6 +177,7 @@ void LLIMConversation::buildParticipantList()
 			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);
 		}
 	}
+	updateHeaderAndToolbar();
 }
 
 void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
-- 
cgit v1.2.3


From 2097e61dcb6865ad4c5b6667c9032f2cef658bd6 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 20 Aug 2012 17:54:33 +0300
Subject: CHUI-302 FIXED (User can resize conversation list too small with
 message panel collapsed) set floater's resize limits from a left panel's
 limits

---
 indra/newview/llimfloatercontainer.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 450717e624..6b7912205e 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -402,6 +402,14 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 
 	setCanResize(is_left_pane_expanded || is_right_pane_expanded);
 	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
+
+    // restore floater's resize limits (prevent collapse when left panel is expanded)
+	if (is_left_pane_expanded && !is_right_pane_expanded)
+	{
+		S32 expanded_min_size = mConversationsPane->getExpandedMinDim();
+        setResizeLimits(expanded_min_size, expanded_min_size);
+	}
+
 }
 
 void LLIMFloaterContainer::onAddButtonClicked()
-- 
cgit v1.2.3


From 3d2045877c07810188ecbd4aac14befea57ddfb3 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 17 Aug 2012 19:33:24 +0300
Subject: CHUI-286 ADD. FIX (Conversations floater opened by default when a new
 IM session is started (no IM toast shown)): repair toast's system - suppress
 toasts only if corresponding floater is visible

---
 indra/newview/llimfloater.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index cdd5ba6889..2efe5d94e2 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -97,12 +97,12 @@ void LLIMFloater::onFocusLost()
 
 void LLIMFloater::onFocusReceived()
 {
-	LLIMModel::getInstance()->setActiveSessionID(mSessionID);
-
 	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, true);
 
 	if (getVisible())
 	{
+		// suppress corresponding toast only if this floater is visible and have focus
+		LLIMModel::getInstance()->setActiveSessionID(mSessionID);
 		LLIMModel::instance().sendNoUnreadMessages(mSessionID);
 	}
 }
@@ -726,6 +726,7 @@ void LLIMFloater::setVisible(BOOL visible)
 	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
 		(LLNotificationsUI::LLChannelManager::getInstance()->
 											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
 	LLTransientDockableFloater::setVisible(visible);
 
 	// update notification channel state
-- 
cgit v1.2.3


From 9a49dbcc456e1313750d5f8b127f29945f8d7ba9 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 16 Aug 2012 13:47:46 +0300
Subject: CHUI-299 (User can start IM session with themselves) FIXED: agent was
 excluded from the search results

---
 indra/newview/llfloateravatarpicker.cpp | 147 +++++++++++++++++---------------
 indra/newview/llfloateravatarpicker.h   |   7 +-
 indra/newview/llimfloatercontainer.cpp  |   2 +-
 3 files changed, 85 insertions(+), 71 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 0290e7cdf0..47acdf7057 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -58,7 +58,8 @@ static std::map<LLUUID, LLAvatarName> sAvatarNameMap;
 
 LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
 												   BOOL allow_multiple,
-												   BOOL closeOnSelect)
+												   BOOL closeOnSelect,
+												   BOOL skip_agent)
 {
 	// *TODO: Use a key to allow this not to be an effective singleton
 	LLFloaterAvatarPicker* floater = 
@@ -73,6 +74,7 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
 	floater->setAllowMultiple(allow_multiple);
 	floater->mNearMeListComplete = FALSE;
 	floater->mCloseOnSelect = closeOnSelect;
+	floater->mExcludeAgentFromSearchResults = skip_agent;
 	
 	if (!closeOnSelect)
 	{
@@ -581,35 +583,38 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
 		msg->getUUIDFast(  _PREHASH_Data,_PREHASH_AvatarID,	avatar_id, i);
 		msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, first_name, i);
 		msg->getStringFast(_PREHASH_Data,_PREHASH_LastName,	last_name, i);
-	
-		std::string avatar_name;
-		if (avatar_id.isNull())
-		{
-			LLStringUtil::format_map_t map;
-			map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString();
-			avatar_name = floater->getString("not_found", map);
-			search_results->setEnabled(FALSE);
-			floater->getChildView("ok_btn")->setEnabled(FALSE);
-		}
-		else
+
+		if (avatar_id != agent_id || !floater->isExcludeAgentFromSearchResults()) // exclude agent from search results?
 		{
-			avatar_name = LLCacheName::buildFullName(first_name, last_name);
-			search_results->setEnabled(TRUE);
-			found_one = TRUE;
+			std::string avatar_name;
+			if (avatar_id.isNull())
+			{
+				LLStringUtil::format_map_t map;
+				map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString();
+				avatar_name = floater->getString("not_found", map);
+				search_results->setEnabled(FALSE);
+				floater->getChildView("ok_btn")->setEnabled(FALSE);
+			}
+			else
+			{
+				avatar_name = LLCacheName::buildFullName(first_name, last_name);
+				search_results->setEnabled(TRUE);
+				found_one = TRUE;
 
-			LLAvatarName av_name;
-			av_name.mLegacyFirstName = first_name;
-			av_name.mLegacyLastName = last_name;
-			av_name.mDisplayName = avatar_name;
-			const LLUUID& agent_id = avatar_id;
-			sAvatarNameMap[agent_id] = av_name;
+				LLAvatarName av_name;
+				av_name.mLegacyFirstName = first_name;
+				av_name.mLegacyLastName = last_name;
+				av_name.mDisplayName = avatar_name;
+				const LLUUID& agent_id = avatar_id;
+				sAvatarNameMap[agent_id] = av_name;
 
+			}
+			LLSD element;
+			element["id"] = avatar_id; // value
+			element["columns"][0]["column"] = "name";
+			element["columns"][0]["value"] = avatar_name;
+			search_results->addElement(element);
 		}
-		LLSD element;
-		element["id"] = avatar_id; // value
-		element["columns"][0]["column"] = "name";
-		element["columns"][0]["value"] = avatar_name;
-		search_results->addElement(element);
 	}
 
 	if (found_one)
@@ -624,52 +629,58 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
 void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& content)
 {
 	// Check for out-of-date query
-	if (query_id != mQueryID) return;
+	if (query_id == mQueryID)
+	{
+		LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");
 
-	LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");
+		LLSD agents = content["agents"];
+
+		// clear "Searching" label on first results
+		search_results->deleteAllItems();
 
-	LLSD agents = content["agents"];
-	if (agents.size() == 0)
-	{
-		LLStringUtil::format_map_t map;
-		map["[TEXT]"] = childGetText("Edit");
 		LLSD item;
-		item["id"] = LLUUID::null;
-		item["columns"][0]["column"] = "name";
-		item["columns"][0]["value"] = getString("not_found", map);
-		search_results->addElement(item);
-		search_results->setEnabled(false);
-		getChildView("ok_btn")->setEnabled(false);
-		return;
-	}
+		LLSD::array_const_iterator it = agents.beginArray();
+		for ( ; it != agents.endArray(); ++it)
+		{
+			const LLSD& row = *it;
+			if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults)
+			{
+				item["id"] = row["id"];
+				LLSD& columns = item["columns"];
+				columns[0]["column"] = "name";
+				columns[0]["value"] = row["display_name"];
+				columns[1]["column"] = "username";
+				columns[1]["value"] = row["username"];
+				search_results->addElement(item);
+
+				// add the avatar name to our list
+				LLAvatarName avatar_name;
+				avatar_name.fromLLSD(row);
+				sAvatarNameMap[row["id"].asUUID()] = avatar_name;
+			}
+		}
 
-	// clear "Searching" label on first results
-	search_results->deleteAllItems();
-
-	LLSD item;
-	LLSD::array_const_iterator it = agents.beginArray();
-	for ( ; it != agents.endArray(); ++it)
-	{
-		const LLSD& row = *it;
-		item["id"] = row["id"];
-		LLSD& columns = item["columns"];
-		columns[0]["column"] = "name";
-		columns[0]["value"] = row["display_name"];
-		columns[1]["column"] = "username";
-		columns[1]["value"] = row["username"];
-		search_results->addElement(item);
-
-		// add the avatar name to our list
-		LLAvatarName avatar_name;
-		avatar_name.fromLLSD(row);
-		sAvatarNameMap[row["id"].asUUID()] = avatar_name;
-	}
-
-	getChildView("ok_btn")->setEnabled(true);
-	search_results->setEnabled(true);
-	search_results->selectFirstItem();
-	onList();
-	search_results->setFocus(TRUE);
+		if (search_results->isEmpty())
+		{
+			LLStringUtil::format_map_t map;
+			map["[TEXT]"] = childGetText("Edit");
+			LLSD item;
+			item["id"] = LLUUID::null;
+			item["columns"][0]["column"] = "name";
+			item["columns"][0]["value"] = getString("not_found", map);
+			search_results->addElement(item);
+			search_results->setEnabled(false);
+			getChildView("ok_btn")->setEnabled(false);
+		}
+		else
+		{
+			getChildView("ok_btn")->setEnabled(true);
+			search_results->setEnabled(true);
+			search_results->selectFirstItem();
+			onList();
+			search_results->setFocus(TRUE);
+		}
+	}
 }
 
 //static
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index 96c039443a..7067cd7b3e 100644
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -45,7 +45,8 @@ public:
 	// Call this to select an avatar.	
 	static LLFloaterAvatarPicker* show(select_callback_t callback, 
 									   BOOL allow_multiple = FALSE,
-									   BOOL closeOnSelect = FALSE);
+									   BOOL closeOnSelect = FALSE,
+									   BOOL skip_agent = FALSE);
 
 	LLFloaterAvatarPicker(const LLSD& key);
 	virtual ~LLFloaterAvatarPicker();
@@ -63,6 +64,7 @@ public:
 						   std::string& tooltip_msg);
 
 	void openFriendsTab();
+	BOOL isExcludeAgentFromSearchResults() {return mExcludeAgentFromSearchResults;}
 
 private:
 	void editKeystroke(class LLLineEditor* caller, void* user_data);
@@ -88,9 +90,10 @@ private:
 	virtual BOOL handleKeyHere(KEY key, MASK mask);
 
 	LLUUID				mQueryID;
-	int				mNumResultsReturned;
+	int				    mNumResultsReturned;
 	BOOL				mNearMeListComplete;
 	BOOL				mCloseOnSelect;
+	BOOL                mExcludeAgentFromSearchResults;
 
 	validate_signal_t mOkButtonValidateSignal;
 	select_callback_t mSelectionCallback;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 6b7912205e..1e136b721c 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -414,7 +414,7 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 
 void LLIMFloaterContainer::onAddButtonClicked()
 {
-    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloaterContainer::onAvatarPicked, this, _1), TRUE, TRUE);
+    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloaterContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE);
     LLFloater* root_floater = gFloaterView->getParentFloater(this);
     if (picker && root_floater)
     {
-- 
cgit v1.2.3


From 7f26bbac80669ecd15b666cc6c5ffec77945438b Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 16 Aug 2012 17:37:26 +0300
Subject: CHUI-278, CHUI-288 FIXED Panels in conversations floater does not
 fully collapse: changed parameter min_width -> expanded_min_dim

---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index ea6fd65b95..e439fc9005 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -34,9 +34,9 @@
          user_resize="true"        
          height="430"
          name="conversations_layout_panel"
-         min_dim="51"
+         min_dim="38"
          width="268"
-         min_width="120">
+         expanded_min_dim="120">
             <layout_stack
              animate="false" 
              follows="left|top|right"
@@ -113,7 +113,7 @@
          height="430"
          name="messages_layout_panel"
          width="412"
-         min_width="205">
+         expanded_min_dim="205">
             <panel_container
              follows="all"
              height="430"
-- 
cgit v1.2.3


From 41cba389f89ff16c0e574ea26d6a1ceb60133ef7 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 16 Aug 2012 12:14:25 -0700
Subject: CHUI-269: Problem: When an item was purchased and delivered into the
 'Received Items' panel, the badge icon and new item count would not show.
 This was due to the creation date of the folders not being set when a new
 item was added. Resolution: Now when an item is added into the 'Received
 Items' panel, the folder hierachy is updated, triggering the badge icon and
 new item count to show.

---
 indra/llui/llfolderviewitem.cpp                    | 17 ----------
 indra/newview/llinventorybridge.cpp                | 13 ++++++++
 indra/newview/llinventorybridge.h                  |  1 +
 indra/newview/llinventorypanel.cpp                 | 11 +++---
 indra/newview/llpanelmarketplaceinbox.cpp          |  8 -----
 indra/newview/llpanelmarketplaceinboxinventory.cpp | 39 ++++++++++------------
 indra/newview/llpanelmarketplaceinboxinventory.h   |  2 +-
 7 files changed, 39 insertions(+), 52 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 1c33c4489b..b172359851 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1487,26 +1487,9 @@ void LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	
 	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
 	item->setVisible(FALSE);
-	
-
-	// TODO RN - port creation date management to new code location
-#if 0
-	// Update the folder creation date if the child is newer than our current date
-	setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
-#endif
 
 	addChild(item);
 	getViewModelItem()->addChild(item->getViewModelItem());
-	// TODO RN - port creation date management to new code location
-#if 0
-	// Traverse parent folders and update creation date and resort, if necessary
-	LLFolderViewFolder* parentp = getParentFolder();
-	while (parentp)
-	{
-		// Update the folder creation date if the child is newer than our current date
-		parentp->setCreationDate(llmax<time_t>(parentp->mCreationDate, item->getCreationDate()));
-	}
-#endif
 
 	//TODO RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
 	//// Traverse parent folders and update creation date and resort, if necessary
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 6c3aaf5eec..215a08b34a 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3098,6 +3098,19 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re
 	return FALSE;
 }
 
+//Recursively update the folder's creation date
+void LLFolderBridge::updateHierarchyCreationDate(time_t date)
+{
+    if(getCreationDate() < date)
+    {
+        setCreationDate(date);
+        if(mParent)
+        {
+            static_cast<LLFolderBridge *>(mParent)->updateHierarchyCreationDate(date);
+        }
+    }
+}
+
 void LLFolderBridge::pasteFromClipboard()
 {
 	LLInventoryModel* model = getInventoryModel();
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index fc0b15acad..6beccf19ae 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -274,6 +274,7 @@ public:
 	virtual BOOL removeItem();
 	BOOL removeSystemFolder();
 	bool removeItemResponse(const LLSD& notification, const LLSD& response);
+    void updateHierarchyCreationDate(time_t date);
 
 	virtual void pasteFromClipboard();
 	virtual void pasteLinkFromClipboard();
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 82cb268e9e..22e6943f50 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -774,12 +774,13 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   				}
   			}
  
-  		if (folder_view_item)
-  			{
-  			folder_view_item->addToFolder(parent_folder);
+  	    if (folder_view_item)
+  		{
+            llassert(parent_folder != NULL);
+            folder_view_item->addToFolder(parent_folder);
 			addItemID(id, folder_view_item);
-   			}
-		}
+   		}
+	}
 
 	// If this is a folder, add the children of the folder and recursively add any 
 	// child folders.
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index ea0521e3a7..4a63585ed5 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -128,7 +128,6 @@ BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL dr
 
 U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	
 	//
 	// NOTE: When turning this on, be sure to test the no inbox/outbox case because this code probably
@@ -174,9 +173,6 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 	}
 
 	return fresh_item_count;
-#else
-	return getTotalItemCount();
-#endif
 }
 
 U32 LLPanelMarketplaceInbox::getTotalItemCount() const
@@ -231,7 +227,6 @@ void LLPanelMarketplaceInbox::draw()
 		args["[NUM]"] = item_count_str;
 		mInboxButton->setLabel(getString("InboxLabelWithArg", args));
 
-#if SUPPORTING_FRESH_ITEM_COUNT
 		// set green text to fresh item count
 		U32 fresh_item_count = getFreshItemCount();
 		mFreshCountCtrl->setVisible((fresh_item_count > 0));
@@ -240,9 +235,6 @@ void LLPanelMarketplaceInbox::draw()
 		{
 			mFreshCountCtrl->setTextArg("[NUM]", llformat("%d", fresh_item_count));
 		}
-#else
-		mFreshCountCtrl->setVisible(FALSE);
-#endif
 	}
 	else
 	{
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 0d3fbe66d7..68aefa7fb7 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -95,22 +95,36 @@ LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p)
 	LLBadgeOwner(getHandle()),
 	mFresh(false)
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	initBadgeParams(p.new_badge());
-#endif
+}
+
+void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item)
+{
+    LLFolderViewFolder::addItem(item);
+
+    if(item)
+    {
+        LLInvFVBridge* itemBridge = static_cast<LLInvFVBridge*>(item->getViewModelItem());
+        LLFolderBridge * bridge = static_cast<LLFolderBridge *>(getViewModelItem());
+        bridge->updateHierarchyCreationDate(itemBridge->getCreationDate());
+    }
+
+    // Compute freshness if our parent is the root folder for the inbox
+    if (mParentFolder == mRoot)
+    {
+        computeFreshness();
+    }
 }
 
 // virtual
 void LLInboxFolderViewFolder::draw()
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	if (!badgeHasParent())
 	{
 		addBadgeToParentPanel();
 	}
 	
 	setBadgeVisibility(mFresh);
-#endif
 
 	LLFolderViewFolder::draw();
 }
@@ -157,17 +171,6 @@ void LLInboxFolderViewFolder::deFreshify()
 	gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
 }
 
-// TODO RN: move this behavior to modelview?
-//void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc)
-//{ 
-//	mCreationDate = creation_date_utc; 
-//
-//	if (LLFolderViewItem::mParentFolder == mRoot)
-//	{
-//		computeFreshness();
-//	}
-//}
-
 //
 // LLInboxFolderViewItem Implementation
 //
@@ -177,22 +180,18 @@ LLInboxFolderViewItem::LLInboxFolderViewItem(const Params& p)
 	, LLBadgeOwner(getHandle())
 	, mFresh(false)
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	initBadgeParams(p.new_badge());
-#endif
 }
 
 void LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 {
 	LLFolderViewItem::addToFolder(folder);
 
-#if SUPPORTING_FRESH_ITEM_COUNT
 	// Compute freshness if our parent is the root folder for the inbox
 	if (mParentFolder == mRoot)
 	{
 		computeFreshness();
 	}
-#endif
 }
 
 BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -205,14 +204,12 @@ BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
 // virtual
 void LLInboxFolderViewItem::draw()
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	if (!badgeHasParent())
 	{
 		addBadgeToParentPanel();
 	}
 
 	setBadgeVisibility(mFresh);
-#endif
 
 	LLFolderViewItem::draw();
 }
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index 098969aca6..c05e18c300 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -33,7 +33,6 @@
 #include "llfolderviewitem.h"
 
 
-#define SUPPORTING_FRESH_ITEM_COUNT	1
 
 
 
@@ -66,6 +65,7 @@ public:
 	
 	LLInboxFolderViewFolder(const Params& p);
 	
+    void addItem(LLFolderViewItem* item);
 	void draw();
 	
 	void selectItem();
-- 
cgit v1.2.3


From d2b813fd79e4cf60d1670472c5a5f09ee9a2eed7 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 17 Aug 2012 20:08:01 +0300
Subject: Remove typo

---
 indra/newview/llimfloatercontainer.cpp | 2 --
 1 file changed, 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index bcad7adcce..450717e624 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -125,8 +125,6 @@ BOOL LLIMFloaterContainer::postBuild()
 
 	addConversationListItem(LLUUID()); // manually add nearby chat
 
-	addConversationListItem(LLUUID()); // manually add nearby chat
-
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
 
-- 
cgit v1.2.3


From 8922dec40039a10e770243f3047793f8501fe43a Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Tue, 21 Aug 2012 19:51:41 +0300
Subject: CHUI-293 CHUI-294 FIXED displaying Group Invite and Transfer Object
 as notifications, instead of displaying as messages from an object. Restored
 the exception in handling "LoadWebPage", "ScriptDialog" and
 "ScriptDialogGroup" notifications, that caused only those notifications to be
 shown as messages from an object.

---
 indra/newview/llnotificationscripthandler.cpp      | 42 +++++++++++-----------
 .../newview/skins/default/xui/en/notifications.xml |  3 ++
 2 files changed, 24 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 7e9c0d4f4b..5dcd84b400 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -78,33 +78,33 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 	}
 	
 	if (notification->canLogToIM())
-		{
-			LLHandlerUtil::logToIMP2P(notification);
-		}
+	{
+		LLHandlerUtil::logToIMP2P(notification);
+	}
 
-	if(notification->hasFormElements())
+	if(notification->hasFormElements() && !notification->canShowToast())
+	{
+		LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
+	}
+	else
+	{
+		LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
+
+		LLToast::Params p;
+		p.notif_id = notification->getID();
+		p.notification = notification;
+		p.panel = notify_box;
+		p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+		if(channel)
 		{
-			LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
+			channel->addToast(p);
 		}
-		else
-		{
-			LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
-
-			LLToast::Params p;
-			p.notif_id = notification->getID();
-			p.notification = notification;
-			p.panel = notify_box;	
-			p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
-
-			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-			if(channel)
-			{
-				channel->addToast(p);
-			}
 	}
 
 	return false;
-		}
+}
 
 
 void LLScriptHandler::onDelete( LLNotificationPtr notification )
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 64db7cd969..933135954f 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6742,6 +6742,7 @@ If you stay in this region you will be logged out.
   <notification
    icon="notify.tga"
    name="LoadWebPage"
+   show_toast="false"
    type="notify">
 Load web page [URL]?
 
@@ -6844,6 +6845,7 @@ It is rare that such a request is legitimate. Do not allow access if you do not
   <notification
    icon="notify.tga"
    name="ScriptDialog"
+   show_toast="false"
    type="notify">
 [NAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
 [MESSAGE]
@@ -6862,6 +6864,7 @@ It is rare that such a request is legitimate. Do not allow access if you do not
   <notification
    icon="notify.tga"
    name="ScriptDialogGroup"
+   show_toast="false"
    type="notify">
     <tag>group</tag>
 [GROUPNAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
-- 
cgit v1.2.3


From f809409de5df3f5ddef24433a4310b18caf3cd8a Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 21 Aug 2012 20:02:29 +0300
Subject: CHUI-300 FIXED (Simplify conversation log name saved to user
 settings?)

- Changed file name agentID#.call_log to conversation.log
---
 indra/newview/llconversationlog.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index b6713465f3..486cea4064 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -238,10 +238,8 @@ void LLConversationLog::cache()
 
 std::string LLConversationLog::getFileName()
 {
-	std::string agent_id_string;
-	gAgent.getID().toString(agent_id_string);
-
-	return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, agent_id_string) + ".call_log";
+	std::string filename = "conversation";
+	return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, filename) + ".log";
 }
 
 bool LLConversationLog::saveToFile(const std::string& filename)
-- 
cgit v1.2.3


From b93e2f7c84a8e14d7ca6c58c35183216a7fbf5bb Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 21 Aug 2012 20:04:13 +0300
Subject: CHUI-297 FIXED (Double clicking line item in conversation log does
 not start IM with User)

- Added callback on double click which initiates IM session with selected conversation log list item
---
 indra/newview/llconversationloglistitem.cpp | 20 ++++++++++++++++++++
 indra/newview/llconversationloglistitem.h   |  2 ++
 2 files changed, 22 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
index fc2e757864..9f7c588989 100644
--- a/indra/newview/llconversationloglistitem.cpp
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -31,9 +31,11 @@
 #include "lltextutil.h"
 
 // newview
+#include "llavataractions.h"
 #include "llavatariconctrl.h"
 #include "llconversationlog.h"
 #include "llconversationloglistitem.h"
+#include "llgroupactions.h"
 #include "llgroupiconctrl.h"
 #include "llinventoryicon.h"
 
@@ -74,6 +76,7 @@ BOOL LLConversationLogListItem::postBuild()
 	mConversationDate->setValue(mConversation->getTimestamp());
 
 	getChild<LLButton>("delete_btn")->setClickedCallback(boost::bind(&LLConversationLogListItem::onRemoveBtnClicked, this));
+	setDoubleClickCallback(boost::bind(&LLConversationLogListItem::onDoubleClick, this));
 
 	return TRUE;
 }
@@ -155,3 +158,20 @@ void LLConversationLogListItem::highlightNameDate(const std::string& highlited_t
 	LLTextUtil::textboxSetHighlightedVal(mConversationName, params, mConversation->getConversationName(), highlited_text);
 	LLTextUtil::textboxSetHighlightedVal(mConversationDate, params, mConversation->getTimestamp(), highlited_text);
 }
+
+void LLConversationLogListItem::onDoubleClick()
+{
+	switch (mConversation->getConversationType())
+	{
+	case LLIMModel::LLIMSession::P2P_SESSION:
+		LLAvatarActions::startIM(mConversation->getParticipantID());
+		break;
+
+	case LLIMModel::LLIMSession::GROUP_SESSION:
+		LLGroupActions::startIM(mConversation->getParticipantID());
+		break;
+
+	default:
+		break;
+	}
+}
diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h
index deba7d4563..8943e11604 100644
--- a/indra/newview/llconversationloglistitem.h
+++ b/indra/newview/llconversationloglistitem.h
@@ -62,6 +62,8 @@ public:
 
 	void highlightNameDate(const std::string& highlited_text);
 
+	void onDoubleClick();
+
 private:
 
 	void initIcons();
-- 
cgit v1.2.3


From 10d2f695c8bf17357438729a1bf1a7f7bd1ee3f2 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 14 Sep 2012 13:59:32 +0300
Subject: CHUI-321 ADDITIONAL FIX (Indicate within the Call Log why there's
 nothing in it)

- Corrected grammatical error
---
 indra/newview/skins/default/xui/en/floater_conversation_log.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index df78bbccec..12d17e6b37 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -15,7 +15,7 @@
   width="450">
   
   <string name="logging_calls_disabled">
-     Conversations are not being logged. To log conversations in the future, select "Save IM logs in my computer" under Preferences > Privacy.
+     Conversations are not being logged. To log conversations in the future, select "Save IM logs on my computer" under Preferences > Privacy.
   </string>
   
 	<panel
-- 
cgit v1.2.3


From e4de40ad8e1abed99c8c8d681c1dda46e72df94f Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 14 Sep 2012 14:37:48 +0300
Subject: CHUI-119 (Add Nearby chat to Conversations floater): addit. fix: use
 LLSD(LLUUID::null) instead LLSD::null as "default" floater's key

---
 indra/llui/llfloaterreg.cpp    |  2 +-
 indra/llui/llfloaterreg.h      | 24 ++++++++++++------------
 indra/newview/llnearbychat.cpp |  4 ++--
 3 files changed, 15 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 9115eb7174..920525448c 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -318,7 +318,7 @@ void LLFloaterReg::showInitialVisibleInstances()
 			BOOL isvis = LLFloater::getControlGroup()->getBOOL(controlname);
 			if (isvis)
 			{
-				showInstance(name, LLSD()); // keyed floaters shouldn't set save_vis to true
+				showInstance(name, LLSD(LLUUID())); // keyed floaters shouldn't set save_vis to true
 			}
 		}
 	}
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index a1e1f8a988..7924b2a7b8 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -90,23 +90,23 @@ public:
 	static LLFloater* getLastFloaterCascading();
 	
 	// Find / get (create) / remove / destroy
-	static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());
-	static LLFloater* getInstance(const std::string& name, const LLSD& key = LLSD());
-	static LLFloater* removeInstance(const std::string& name, const LLSD& key = LLSD());
-	static bool destroyInstance(const std::string& name, const LLSD& key = LLSD());
+	static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
+	static LLFloater* getInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
+	static LLFloater* removeInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
+	static bool destroyInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
 	
 	// Iterators
 	static const_instance_list_t& getFloaterList(const std::string& name);
 
 	// Visibility Management
 	// return NULL if instance not found or can't create instance (no builder)
-	static LLFloater* showInstance(const std::string& name, const LLSD& key = LLSD(), BOOL focus = FALSE);
+	static LLFloater* showInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()), BOOL focus = FALSE);
 	// Close a floater (may destroy or set invisible)
 	// return false if can't find instance
-	static bool hideInstance(const std::string& name, const LLSD& key = LLSD());
+	static bool hideInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
 	// return true if instance is visible:
-	static bool toggleInstance(const std::string& name, const LLSD& key = LLSD());
-	static bool instanceVisible(const std::string& name, const LLSD& key = LLSD());
+	static bool toggleInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
+	static bool instanceVisible(const std::string& name, const LLSD& key = LLSD(LLUUID()));
 
 	static void showInitialVisibleInstances();
 	static void hideVisibleInstances(const std::set<std::string>& exceptions = std::set<std::string>());
@@ -126,23 +126,23 @@ public:
 	static void registerControlVariables();
 
 	// Callback wrappers
-	static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD());
+	static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD(LLUUID()));
 	
 	// Typed find / get / show
 	template <class T>
-	static T* findTypedInstance(const std::string& name, const LLSD& key = LLSD())
+	static T* findTypedInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()))
 	{
 		return dynamic_cast<T*>(findInstance(name, key));
 	}
 
 	template <class T>
-	static T* getTypedInstance(const std::string& name, const LLSD& key = LLSD())
+	static T* getTypedInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()))
 	{
 		return dynamic_cast<T*>(getInstance(name, key));
 	}
 
 	template <class T>
-	static T* showTypedInstance(const std::string& name, const LLSD& key = LLSD(), BOOL focus = FALSE)
+	static T* showTypedInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()), BOOL focus = FALSE)
 	{
 		return dynamic_cast<T*>(showInstance(name, key, focus));
 	}
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index ddd271e23f..a803b35aa8 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -108,7 +108,7 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
 
 
 LLNearbyChat::LLNearbyChat(const LLSD& llsd)
-:	LLIMConversation(LLSD()),
+:	LLIMConversation(llsd.asUUID()),
 	//mOutputMonitor(NULL),
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
@@ -116,7 +116,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& llsd)
     mIsP2PChat = false;
 	mIsNearbyChat = true;
 	setIsChrome(TRUE);
-	mKey = LLSD();
+	mKey = LLSD(LLUUID());
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
 	mSessionID = LLUUID();
 	setName("nearby_chat");
-- 
cgit v1.2.3


From 76827f03d429e3ce80def7a49c2657a1cb1179d4 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 22 Aug 2012 13:25:06 +0300
Subject: CHUI-289 FIXED (Newly added conversation is not selected in
 conversation list): added the "reverse" selecting - list item is selected
 when the corresponding floter gets focus.

---
 indra/newview/llconversationview.cpp   |  3 ++-
 indra/newview/llimconversation.cpp     | 10 ++++++++++
 indra/newview/llimconversation.h       |  3 +++
 indra/newview/llimfloatercontainer.cpp | 26 +++++++++++++++++++++-----
 indra/newview/llimfloatercontainer.h   |  4 +++-
 5 files changed, 39 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 208a89cc8d..d5d4fc13da 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -239,7 +239,6 @@ S32 LLConversationViewSession::arrange(S32* width, S32* height)
 
 void LLConversationViewSession::selectItem()
 {
-	LLFolderViewItem::selectItem();
 	
 	LLConversationItem* item = dynamic_cast<LLConversationItem*>(mViewModelItem);
 	LLFloater* session_floater = LLIMConversation::getConversation(item->getUUID());
@@ -255,6 +254,8 @@ void LLConversationViewSession::selectItem()
 	
 	// Set the focus on the selected floater
 	session_floater->setFocus(TRUE);
+
+	LLFolderViewItem::selectItem();
 }
 
 void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 216c5bbd70..bab588126f 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -215,11 +215,21 @@ void LLIMConversation::onFocusReceived()
 	}
 
 	LLTransientDockableFloater::onFocusReceived();
+
+    mHasFocus = mHaveFocus;
+    mHaveFocus = true;
+
+	if (! mHasFocus)
+	{
+	    LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
+	    container->setConvItemSelect(mSessionID);
+	}
 }
 
 void LLIMConversation::onFocusLost()
 {
 	setBackgroundOpaque(false);
+	mHaveFocus = false;
 	LLTransientDockableFloater::onFocusLost();
 }
 
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 41a76c206e..e09ba79a6a 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -139,6 +139,9 @@ private:
 	void reshapeChatHistory();
 
 	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
+
+	bool mHasFocus;
+	bool mHaveFocus;
 };
 
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 54a40627fb..81dddfaa70 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -183,9 +183,9 @@ void LLIMFloaterContainer::onOpen(const LLSD& key)
 }
 
 // virtual
-void LLIMFloaterContainer::addFloater(LLFloater* floaterp, 
-									BOOL select_added_floater, 
-									LLTabContainer::eInsertionPoint insertion_point)
+void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
+									  BOOL select_added_floater,
+									  LLTabContainer::eInsertionPoint insertion_point)
 {
 	if(!floaterp) return;
 
@@ -427,7 +427,10 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
 	{
 		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
-		widget->setVisibleIfDetached(visible);
+		if (widget)
+		{
+		    widget->setVisibleIfDetached(visible);
+		}
 	}
 	
 	// Now, do the normal multifloater show/hide
@@ -608,6 +611,16 @@ void LLIMFloaterContainer::repositioningWidgets()
 	}
 }
 
+void LLIMFloaterContainer::setConvItemSelect(LLUUID& session_id)
+{
+	LLFolderViewItem* widget = mConversationsWidgets[session_id];
+	if (widget && mSelectedSession != session_id)
+	{
+		mSelectedSession = session_id;
+		(widget->getRoot())->setSelection(widget, FALSE, FALSE);
+	}
+}
+
 void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 {
 	bool is_nearby_chat = uuid.isNull();
@@ -675,7 +688,10 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	if (widget_it != mConversationsWidgets.end())
 	{
 		LLFolderViewItem* widget = widget_it->second;
-		widget->destroyView();
+		if (widget)
+		{
+			widget->destroyView();
+		}
 	}
 	
 	// Suppress the conversation items and widgets from their respective maps
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 324adfcc11..f6048bed37 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -62,7 +62,7 @@ public:
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
-
+    void setConvItemSelect(LLUUID& session_id);
 	/*virtual*/ void tabClose();
 
 	static LLFloater* getCurrentVoiceFloater();
@@ -114,6 +114,8 @@ private:
 	
 	bool mInitialized;
 
+	LLUUID mSelectedSession;
+
 	// Conversation list implementation
 public:
 	void removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
-- 
cgit v1.2.3


From b2f2a8b21610ae6863b773333c60b18b818c047f Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 22 Aug 2012 14:48:44 +0300
Subject: code style fix

---
 indra/newview/llimfloatercontainer.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 1e136b721c..6127a9a19b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -519,7 +519,6 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 			item->selectItem();
 		}
 	}
-	return;
 }
 
 LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
-- 
cgit v1.2.3


From 14708a3ace184b0654ca7923732be6e06962d583 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 22 Aug 2012 18:27:29 +0300
Subject: CHUI_310 make NearbyChat a singletone

---
 indra/newview/llagent.cpp                          |  4 +-
 indra/newview/llchatitemscontainerctrl.cpp         |  4 +-
 indra/newview/llfirstuse.cpp                       |  2 +-
 indra/newview/llfloatertranslationsettings.cpp     |  2 +-
 indra/newview/llgesturemgr.cpp                     |  2 +-
 indra/newview/llimconversation.cpp                 | 32 +++++++++--
 indra/newview/llimfloatercontainer.cpp             |  6 +--
 indra/newview/llimview.cpp                         |  7 +--
 indra/newview/llnearbychat.cpp                     | 41 ++++++--------
 indra/newview/llnearbychat.h                       |  8 +--
 indra/newview/llnearbychathandler.cpp              |  6 +--
 indra/newview/llnotificationhandlerutil.cpp        |  5 +-
 indra/newview/llnotificationtiphandler.cpp         |  3 +-
 indra/newview/llstartup.cpp                        |  1 +
 indra/newview/llviewerfloaterreg.cpp               |  2 +-
 indra/newview/llviewergesture.cpp                  |  2 +-
 indra/newview/llviewerkeyboard.cpp                 |  2 +-
 indra/newview/llviewermessage.cpp                  |  9 ++--
 indra/newview/llviewerwindow.cpp                   | 62 +++++++++++-----------
 .../skins/default/xui/da/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/de/floater_chat_bar.xml      |  2 +-
 .../skins/default/xui/de/panel_nearby_chat_bar.xml |  2 +-
 indra/newview/skins/default/xui/en/menu_viewer.xml |  4 +-
 .../skins/default/xui/en/panel_bottomtray_lite.xml |  2 +-
 .../skins/default/xui/en/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/es/floater_chat_bar.xml      |  2 +-
 .../skins/default/xui/es/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/fr/floater_chat_bar.xml      |  2 +-
 .../skins/default/xui/fr/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/it/floater_chat_bar.xml      |  2 +-
 .../skins/default/xui/it/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/ja/floater_chat_bar.xml      |  2 +-
 .../skins/default/xui/ja/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/pl/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/pt/floater_chat_bar.xml      |  2 +-
 .../skins/default/xui/pt/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/ru/floater_chat_bar.xml      |  2 +-
 .../skins/default/xui/ru/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/tr/floater_chat_bar.xml      |  2 +-
 .../skins/default/xui/tr/panel_nearby_chat_bar.xml |  2 +-
 .../skins/default/xui/zh/panel_nearby_chat_bar.xml |  2 +-
 41 files changed, 125 insertions(+), 121 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f187318c0f..be6901c36a 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1911,7 +1911,7 @@ void LLAgent::startTyping()
 	{
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
 	}
-	LLNearbyChat::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+	(LLNearbyChat::instance()).sendChatFromViewer("", CHAT_TYPE_START, FALSE);
 }
 
 //-----------------------------------------------------------------------------
@@ -1923,7 +1923,7 @@ void LLAgent::stopTyping()
 	{
 		clearRenderState(AGENT_STATE_TYPING);
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
-		LLNearbyChat::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+		(LLNearbyChat::instance()).sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
 	}
 }
 
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 61772b4bb7..e6340e0fa3 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -323,12 +323,12 @@ BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
 			return TRUE;
 		else
 		{
-			LLNearbyChat::getInstance()->showHistory();
+			LLNearbyChat::instance().showHistory();
 			return FALSE;
 		}
 	}
 
-	LLNearbyChat::getInstance()->showHistory();
+	LLNearbyChat::instance().showHistory();
 	return LLPanel::handleMouseUp(x,y,mask);
 }
 
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index a9f52282a5..e2850f5181 100644
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -74,7 +74,7 @@ void LLFirstUse::resetFirstUse()
 // static
 void LLFirstUse::otherAvatarChatFirst(bool enable)
 {
-	firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "chat_bar").with("direction", "top_right").with("distance", 24));
+	firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "nearby_chat").with("direction", "top_right").with("distance", 24));
 }
 
 // static
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index bb01ce5a7e..b5b86dadc2 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -293,6 +293,6 @@ void LLFloaterTranslationSettings::onBtnOK()
 	gSavedSettings.setString("TranslationService", getSelectedService());
 	gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
 	gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
-	LLNearbyChat::getInstance()->showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+	LLNearbyChat::instance().showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 	closeFloater(false);
 }
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 26b63bdacb..0377337af6 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -997,7 +997,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
 
 			const BOOL animate = FALSE;
 
-			LLNearbyChat::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+			LLNearbyChat::instance().sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
 
 			gesture->mCurrentStep++;
 			break;
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index ee7f58b01f..2212673d3a 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -81,13 +81,35 @@ LLIMConversation::~LLIMConversation()
 //static
 LLIMConversation* LLIMConversation::findConversation(const LLUUID& uuid)
 {
-    return LLFloaterReg::findTypedInstance<LLIMConversation>(uuid.isNull()? "chat_bar" : "impanel", LLSD(uuid));
+	LLIMConversation* conv;
+
+	if (uuid.isNull())
+	{
+		conv = LLFloaterReg::findTypedInstance<LLIMConversation>("nearby_chat");
+	}
+	else
+	{
+		conv = LLFloaterReg::findTypedInstance<LLIMConversation>("impanel", LLSD(uuid));
+	}
+
+	return conv;
 };
 
 //static
 LLIMConversation* LLIMConversation::getConversation(const LLUUID& uuid)
 {
-	return LLFloaterReg::getTypedInstance<LLIMConversation>(uuid.isNull()? "chat_bar" : "impanel", LLSD(uuid));
+	LLIMConversation* conv;
+
+	if (uuid.isNull())
+	{
+		conv = LLFloaterReg::getTypedInstance<LLIMConversation>("nearby_chat");
+	}
+	else
+	{
+		conv = LLFloaterReg::getTypedInstance<LLIMConversation>("impanel", LLSD(uuid));
+	}
+
+	return conv;
 };
 
 
@@ -336,15 +358,15 @@ void LLIMConversation::processChatHistoryStyleUpdate()
 		}
 	}
 
-	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-	if (nearby_chat)
+	if (LLNearbyChat::instanceExists())
 	{
-		nearby_chat->reloadMessages();
+		LLNearbyChat::instance().reloadMessages();
 	}
 }
 
 void LLIMConversation::updateCallBtnState(bool callIsActive)
 {
+llwarns<<(this->getName())<<llendl;
 	getChild<LLButton>("voice_call_btn")->setImageOverlay(
 			callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
     enableDisableCallBtn();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4d0bd623f8..a3f5e357c9 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -315,13 +315,13 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	if (visible)
 	{
 		// Make sure we have the Nearby Chat present when showing the conversation container
-		LLIMConversation* nearby_chat = LLIMConversation::findConversation(LLUUID::null);
+		LLIMConversation* nearby_chat = LLFloaterReg::findTypedInstance<LLIMConversation>("nearby_chat");
 		if (nearby_chat == NULL)
 		{
 			// If not found, force the creation of the nearby chat conversation panel
 			// *TODO: find a way to move this to XML as a default panel or something like that
-			LLSD name("chat_bar");
-			LLFloaterReg::toggleInstanceOrBringToFront(name, LLSD(LLUUID::null));
+			LLSD name("nearby_chat");
+			LLFloaterReg::toggleInstanceOrBringToFront(name);
 		}
 	}
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d88a558125..216db15c94 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2486,12 +2486,9 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 
 		LLChat chat(message);
 		chat.mSourceType = CHAT_SOURCE_SYSTEM;
-		
-		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-
-		if(nearby_chat)
+		if (LLNearbyChat::instanceExists())
 		{
-			nearby_chat->addMessage(chat);
+			LLNearbyChat::instance().addMessage(chat);
 		}
 	}
 	else // going to IM session
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index e1454fb5dc..a723748094 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -123,8 +123,8 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
 };
 
 
-LLNearbyChat::LLNearbyChat(const LLSD& key)
-:	LLIMConversation(key),
+LLNearbyChat::LLNearbyChat(const LLSD& llsd)
+:	LLIMConversation(LLSD()),
 	//mOutputMonitor(NULL),
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
@@ -133,6 +133,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key)
 	setIsChrome(TRUE);
 	mKey = LLSD();
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
+	setName("nearby_chat");
 }
 
 //virtual
@@ -379,11 +380,6 @@ void LLNearbyChat::onChatFontChange(LLFontGL* fontp)
 	}
 }
 
-//static
-LLNearbyChat* LLNearbyChat::getInstance()
-{
-	return LLFloaterReg::getTypedInstance<LLNearbyChat>("chat_bar", LLSD(LLUUID::null));
-}
 
 void LLNearbyChat::show()
 {
@@ -646,7 +642,10 @@ void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args)
 		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
 		chat_args["show_names_for_p2p_conv"] = true;
 
-		mChatHistory->appendMessage(chat, chat_args);
+		if (mChatHistory)
+		{
+			mChatHistory->appendMessage(chat, chat_args);
+		}
 	}
 }
 
@@ -781,22 +780,20 @@ void LLNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BO
 // static 
 void LLNearbyChat::startChat(const char* line)
 {
-	LLNearbyChat* cb = LLNearbyChat::getInstance();
-
-	if (cb )
+	if (LLNearbyChat::instanceExists())
 	{
-		cb->show();
-		cb->setVisible(TRUE);
-		cb->setFocus(TRUE);
-		cb->mInputEditor->setFocus(TRUE);
+		(LLNearbyChat::instance()).show();
+		(LLNearbyChat::instance()).setVisible(TRUE);
+		(LLNearbyChat::instance()).setFocus(TRUE);
+		(LLNearbyChat::instance().mInputEditor)->setFocus(TRUE);
 
 		if (line)
 		{
 			std::string line_string(line);
-			cb->mInputEditor->setText(line_string);
+			(LLNearbyChat::instance().mInputEditor)->setText(line_string);
 		}
 
-		cb->mInputEditor->endOfDoc();
+		(LLNearbyChat::instance().mInputEditor)->endOfDoc();
 	}
 }
 
@@ -804,14 +801,10 @@ void LLNearbyChat::startChat(const char* line)
 // static
 void LLNearbyChat::stopChat()
 {
-	LLNearbyChat* cb = LLNearbyChat::getInstance();
-
-	if (cb)
+	if (LLNearbyChat::instanceExists())
 	{
-		cb->mInputEditor->setFocus(FALSE);
-
-		// stop typing animation
-		gAgent.stopTyping();
+		(LLNearbyChat::instance().mInputEditor)->setFocus(FALSE);
+	    gAgent.stopTyping();
 	}
 }
 
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 7c58e3037e..379bfbee4b 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -35,17 +35,19 @@
 #include "lloutputmonitorctrl.h"
 #include "llspeakers.h"
 #include "llscrollbar.h"
+#include "llsingleton.h"
 #include "llviewerchat.h"
 #include "llpanel.h"
 
 class LLResizeBar;
 
 class LLNearbyChat
-	:	public LLIMConversation
+	:	public LLIMConversation,
+	 	public LLSingleton<LLNearbyChat>
 {
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
-	LLNearbyChat(const LLSD& key);
+	LLNearbyChat(const LLSD& key = LLSD());
 	~LLNearbyChat() {}
 
 	/*virtual*/ BOOL postBuild();
@@ -61,8 +63,6 @@ public:
     void reloadMessages();
 	void removeScreenChat();
 
-	static LLNearbyChat* getInstance();
-
 	void addToHost();
 	void show();
 	bool isChatVisible() const;
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index c97e3585e1..37f4cc4c19 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -487,8 +487,6 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	if(chat_msg.mText.empty())
 		return;//don't process empty messages
 
-	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-
 	// Build notification data 
 	LLSD chat;
 	chat["message"] = chat_msg.mText;
@@ -539,7 +537,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 		}
 	}
 
-	nearby_chat->addMessage(chat_msg, true, args);
+	LLNearbyChat::instance().addMessage(chat_msg, true, args);
 
 	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT 
 		&& chat_msg.mFromID.notNull() 
@@ -555,7 +553,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	// Send event on to LLEventStream
 	sChatWatcher->post(chat);
 
-	if( nearby_chat->isInVisibleChain()
+	if( LLNearbyChat::instance().isInVisibleChain()
 		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") )
 		|| mChannel.isDead()
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index cba22b233b..db8e917435 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -181,14 +181,13 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
 // static
 void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
 {
-	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-	if(nearby_chat)
+	if (LLNearbyChat::instanceExists())
 	{
 		LLChat chat_msg(notification->getMessage());
 		chat_msg.mSourceType = type;
 		chat_msg.mFromName = SYSTEM_FROM;
 		chat_msg.mFromID = LLUUID::null;
-		nearby_chat->addMessage(chat_msg);
+		LLNearbyChat::instance().addMessage(chat_msg);
 	}
 }
 
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index a420c0d2ed..67fc9b27dc 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -85,8 +85,7 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 		LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
 
 		// don't show toast if Nearby Chat is opened
-		LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-		if (nearby_chat->isChatVisible())
+		if (LLNearbyChat::instance().isChatVisible())
 		{
 			return false;
 		}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ab72b4e512..c827b39d0e 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -64,6 +64,7 @@
 #include "llmessageconfig.h"
 #include "llmoveview.h"
 #include "llimfloatercontainer.h"
+#include "llnearbychat.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llteleporthistory.h"
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 50735d10bd..927ee8f380 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -192,7 +192,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
 
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
-	LLFloaterReg::add("chat_bar", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
+	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
 	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
 
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index c7d37e102e..a2dea31d9b 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -130,7 +130,7 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
 	{
 		// Don't play nodding animation, since that might not blend
 		// with the gesture animation.
-		LLNearbyChat::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+		LLNearbyChat::instance().sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
 	}
 }
 
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 385d3cd29a..7105720eb4 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -543,7 +543,7 @@ void start_gesture( EKeystate s )
 	if (KEYSTATE_UP == s &&
 		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
 	{
- 		if (LLNearbyChat::getInstance()->getCurrentChat().empty())
+ 		if (LLNearbyChat::instance().getCurrentChat().empty())
  		{
  			// No existing chat in chat editor, insert '/'
  			LLNearbyChat::startChat("/");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index b20b86a582..9abd269f0f 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2297,12 +2297,10 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m
 	// Treat like a system message and put in chat history.
 	chat.mText = av_name.getCompleteName() + ": " + message;
 
-	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-	if(nearby_chat)
+	if (LLNearbyChat::instanceExists())
 	{
-		nearby_chat->addMessage(chat);
+		LLNearbyChat::instance().addMessage(chat);
 	}
-
 }
 
 void process_improved_im(LLMessageSystem *msg, void **user_data)
@@ -2897,8 +2895,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
 			// IMs from obejcts don't open IM sessions.
-			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-			if(!chat_from_system && nearby_chat)
+			if(!chat_from_system && LLNearbyChat::instanceExists())
 			{
 				chat.mOwnerID = from_id;
 				LLSD args;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 1bcf15913f..23d2b1633d 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -198,7 +198,6 @@
 
 #include "llfloaternotificationsconsole.h"
 
-#include "llnearbychat.h"
 #include "llwindowlistener.h"
 #include "llviewerwindowlistener.h"
 #include "llpaneltopinfobar.h"
@@ -2497,43 +2496,42 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	// Traverses up the hierarchy
 	if( keyboard_focus )
 	{
-		LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("chat_bar");
-
-		if (nearby_chat)
+		if (LLNearbyChat::instanceExists())
 		{
-			LLChatEntry* chat_editor = nearby_chat->getChatBox();
-		
-		// arrow keys move avatar while chatting hack
-		if (chat_editor && chat_editor->hasFocus())
-		{
-			// If text field is empty, there's no point in trying to move
-			// cursor with arrow keys, so allow movement
-			if (chat_editor->getText().empty() 
-				|| gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
+			LLChatEntry* chat_editor = LLNearbyChat::instance().getChatBox();
+
+			// arrow keys move avatar while chatting hack
+			if (chat_editor && chat_editor->hasFocus())
 			{
-				// let Control-Up and Control-Down through for chat line history,
-				if (!(key == KEY_UP && mask == MASK_CONTROL)
-					&& !(key == KEY_DOWN && mask == MASK_CONTROL))
+				// If text field is empty, there's no point in trying to move
+				// cursor with arrow keys, so allow movement
+				if (chat_editor->getText().empty()
+					|| gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
 				{
-					switch(key)
+					// let Control-Up and Control-Down through for chat line history,
+					if (!(key == KEY_UP && mask == MASK_CONTROL)
+						&& !(key == KEY_DOWN && mask == MASK_CONTROL))
 					{
-					case KEY_LEFT:
-					case KEY_RIGHT:
-					case KEY_UP:
-					case KEY_DOWN:
-					case KEY_PAGE_UP:
-					case KEY_PAGE_DOWN:
-					case KEY_HOME:
-						// when chatbar is empty or ArrowKeysAlwaysMove set,
-						// pass arrow keys on to avatar...
-						return FALSE;
-					default:
-						break;
+						switch(key)
+						{
+						case KEY_LEFT:
+						case KEY_RIGHT:
+						case KEY_UP:
+						case KEY_DOWN:
+						case KEY_PAGE_UP:
+						case KEY_PAGE_DOWN:
+						case KEY_HOME:
+							// when chatbar is empty or ArrowKeysAlwaysMove set,
+							// pass arrow keys on to avatar...
+							return FALSE;
+						default:
+							break;
+						}
 					}
 				}
 			}
 		}
-		}
+
 		if (keyboard_focus->handleKey(key, mask, FALSE))
 		{
 			return TRUE;
@@ -2564,11 +2562,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
-		LLChatEntry* chat_editor = LLNearbyChat::getInstance()->getChatBox();
+		LLChatEntry* chat_editor = LLNearbyChat::instance().getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
-			LLNearbyChat::getInstance()->startChat(NULL);
+			LLNearbyChat::instance().startChat(NULL);
 			return TRUE;
 		}
 	}
diff --git a/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
index 949cbcbd7b..eb104201f8 100644
--- a/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Klik her for at chatte." name="chat_box" tool_tip="Tryk på enter for at tale, Ctrl-Enter for at råbe."/>
 	<button name="show_nearby_chat" tool_tip="Viser/skjuler log for chat nærved"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/de/floater_chat_bar.xml b/indra/newview/skins/default/xui/de/floater_chat_bar.xml
index 2464a55665..ab77d4dae5 100644
--- a/indra/newview/skins/default/xui/de/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/de/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT IN DER NÄHE">
+<floater name="nearby_chat" title="CHAT IN DER NÄHE">
 	<panel name="bottom_panel">
 		<line_editor label="Zum Chatten hier klicken." name="chat_box" tool_tip="Eingabetaste zum Sprechen, Strg+Eingabe zum Rufen"/>
 		<button name="show_nearby_chat" tool_tip="Chatprotokoll in der Nähe ein-/ausblenden"/>
diff --git a/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
index 08cc0b0ec8..69cf6d98de 100644
--- a/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Zum Chatten hier klicken." name="chat_box" tool_tip="Eingabe drücken, um zu sprechen, Strg-Eingabe drücken, um zu Rufen."/>
 	<button name="show_nearby_chat" tool_tip="Protokoll des Chats in der Nähe anzeigen/ausblenden"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 1aa55acf2d..aa131035ed 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -225,10 +225,10 @@
          use_mac_ctrl="true">
             <menu_item_check.on_check
              function="Floater.Visible"
-             parameter="chat_bar" />
+             parameter="nearby_chat" />
             <menu_item_check.on_click
              function="Floater.Toggle"
-             parameter="chat_bar" />
+             parameter="nearby_chat" />
         </menu_item_check>
         <menu_item_check
          label="Speak"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
index f4722b05d6..27a27473d8 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
@@ -46,7 +46,7 @@
             follows="left|right"
             top="4"
             width="310"
-            name="chat_bar"
+            name="nearby_chat"
             mouse_opaque="false"/>
         </layout_panel>
         <layout_panel
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 6bc9c48729..19143cef89 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -5,7 +5,7 @@
  height="25"
  layout="topleft"
  left="0"
- name="chat_bar"
+ name="nearby_chat"
  top="21"
  width="308">
     <line_editor
diff --git a/indra/newview/skins/default/xui/es/floater_chat_bar.xml b/indra/newview/skins/default/xui/es/floater_chat_bar.xml
index 2e94805057..02369c9a43 100644
--- a/indra/newview/skins/default/xui/es/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/es/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT">
+<floater name="nearby_chat" title="CHAT">
 	<panel name="bottom_panel">
 		<line_editor label="Pulsa aquí para chatear." name="chat_box" tool_tip="Pulsa Enter para decirlo o Ctrl+Enter para gritarlo"/>
 		<button name="show_nearby_chat" tool_tip="Muestra o esconde el registro del chat"/>
diff --git a/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
index af2b6e920b..e6ca59f912 100644
--- a/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Pulsa aquí para chatear." name="chat_box" tool_tip="Pulsa Enter para decirlo o Ctrl+Enter para gritarlo"/>
 	<button name="show_nearby_chat" tool_tip="Muestra o esconde el registro del chat"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
index 890411d091..7dcb9a280d 100644
--- a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT PRÈS DE MOI">
+<floater name="nearby_chat" title="CHAT PRÈS DE MOI">
 	<panel name="bottom_panel">
 		<line_editor label="Cliquer ici pour chatter." name="chat_box" tool_tip="Appuyer sur Entrée pour dire, Ctrl+Entrée pour crier"/>
 		<button name="show_nearby_chat" tool_tip="Afficher/masquer le journal de chat près de vous."/>
diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
index 82cdf292ab..762dee01bb 100644
--- a/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Cliquer ici pour chatter." name="chat_box" tool_tip="Appuyer sur Entrée pour dire, Ctrl-Entrée pour crier"/>
 	<button name="show_nearby_chat" tool_tip="Affiche/Masque le journal de chats près de vous"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/it/floater_chat_bar.xml b/indra/newview/skins/default/xui/it/floater_chat_bar.xml
index 94c85b50c8..b47e32ce90 100644
--- a/indra/newview/skins/default/xui/it/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/it/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT NEI DINTORNI">
+<floater name="nearby_chat" title="CHAT NEI DINTORNI">
 	<panel name="bottom_panel">
 		<line_editor label="Clicca qui per la chat." name="chat_box" tool_tip="Premi Invio per parlare, Ctrl+Invio per gridare"/>
 		<button name="show_nearby_chat" tool_tip="Mostra/Nasconde il registro della chat nei dintorni"/>
diff --git a/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
index 6317d3192e..1fef88870a 100644
--- a/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<string name="min_width">
 		192
 	</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
index 11f223ade6..9f5df6fb85 100644
--- a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="近くのチャット">
+<floater name="nearby_chat" title="近くのチャット">
 	<panel name="bottom_panel">
 		<line_editor label="ここをクリックしてチャットを開始します。" name="chat_box" tool_tip="Enter キーを押して話し、Ctrl + Enter キーで叫びます。"/>
 		<button name="show_nearby_chat" tool_tip="近くのチャットログを表示/非表示"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
index 5998206f27..201fb0a376 100644
--- a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="ここをクリックしてチャットを開始します。" name="chat_box" tool_tip="Enter キーを押して発言し、Ctrl + Enter キーで叫びます。"/>
 	<button name="show_nearby_chat" tool_tip="近くのチャットログを表示・非表示"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
index 63cf96b571..4ed3ff669b 100644
--- a/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<string name="min_width">
 		192
 	</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_chat_bar.xml b/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
index 72016c6b40..2eb2c94940 100644
--- a/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="BATE-PAPO LOCAL">
+<floater name="nearby_chat" title="BATE-PAPO LOCAL">
 	<panel name="bottom_panel">
 		<line_editor label="Clique aqui para bater papo." name="chat_box" tool_tip="Tecle Enter para falar, Ctrl+Enter para gritar"/>
 		<button name="show_nearby_chat" tool_tip="Mostra/oculta o histórico do bate-papo local"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
index 9b993488be..5628a87109 100644
--- a/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Clique aqui para bater papo." name="chat_box" tool_tip="Tecle Enter para falar, Ctrl+Enter para gritar"/>
 	<button name="show_nearby_chat" tool_tip="Mostra/oculta o histórico do bate-papo local"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/ru/floater_chat_bar.xml b/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
index 79b7b033fb..f6b2fc81e1 100644
--- a/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="ЛОКАЛЬНЫЙ ЧАТ">
+<floater name="nearby_chat" title="ЛОКАЛЬНЫЙ ЧАТ">
 	<panel name="bottom_panel">
 		<line_editor label="Щелкните здесь для общения." name="chat_box" tool_tip="Нажмите Enter, чтобы сказать, Ctrl+Enter, чтобы прокричать"/>
 		<button name="show_nearby_chat" tool_tip="Показать/скрыть лог локального чата"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
index 804ba7def7..395c643b0b 100644
--- a/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Щелкните здесь для общения" name="chat_box" tool_tip="Нажмите Enter, чтобы сказать, Ctrl+Enter, чтобы прокричать"/>
 	<button name="show_nearby_chat" tool_tip="Показать/скрыть лог локального чата"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
index 988c845982..cd999b4b7a 100644
--- a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="YAKINDAKİ SOHBET">
+<floater name="nearby_chat" title="YAKINDAKİ SOHBET">
 	<panel name="bottom_panel">
 		<line_editor label="Sohbet etmek için buraya tıklayın." name="chat_box" tool_tip="Söylemek için Enter, bağırmak için Ctrl+Enter yapın"/>
 		<button name="show_nearby_chat" tool_tip="Yakın sohbet günlüğünü gösterir/gizler"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
index fd954475ac..7d191191c4 100644
--- a/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Sohbet etmek için buraya tıklayın." name="chat_box" tool_tip="Söylemek için Enter, bağırmak için Ctrl+Enter yapın"/>
 	<button name="show_nearby_chat" tool_tip="yakın sohbet günlüğünü gösterir/gizler"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
index 3cabfcfaba..f27f205c44 100644
--- a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="點擊此處開始聊天。" name="chat_box" tool_tip="按下 Enter 鍵來說或按下 Ctrl+Enter 來喊叫"/>
 	<button name="show_nearby_chat" tool_tip="顯示 / 隱藏 附近的聊天紀錄"/>
 </panel>
-- 
cgit v1.2.3


From 2cf5307c9211b813689f0e441b9f56bc21f63348 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 22 Aug 2012 19:29:22 -0700
Subject: CHUI-282 : WIP : Isolated llconversationview classes and suppressed
 the dependency of model to widgets

---
 indra/newview/CMakeLists.txt           |  2 ++
 indra/newview/llconversationmodel.cpp  | 31 ++++------------
 indra/newview/llconversationmodel.h    |  7 ++--
 indra/newview/llconversationview.cpp   | 64 ++++++++++++++++++++++++++++++++++
 indra/newview/llconversationview.h     | 63 +++++++++++++++++++++++++++++++++
 indra/newview/llimfloatercontainer.cpp | 10 +++---
 6 files changed, 144 insertions(+), 33 deletions(-)
 create mode 100644 indra/newview/llconversationview.cpp
 create mode 100644 indra/newview/llconversationview.h

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 9553476aaf..c49c625dbd 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -138,6 +138,7 @@ set(viewer_SOURCE_FILES
     llconversationloglist.cpp
     llconversationloglistitem.cpp
     llconversationmodel.cpp
+    llconversationview.cpp
     llcurrencyuimanager.cpp
     llcylinder.cpp
     lldateutil.cpp
@@ -721,6 +722,7 @@ set(viewer_HEADER_FILES
     llconversationloglist.h
     llconversationloglistitem.h
     llconversationmodel.h
+    llconversationview.h
     llcurrencyuimanager.h
     llcylinder.h
     lldateutil.h
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 0c23e2654e..923bc7a3a1 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -32,41 +32,22 @@
 #include "llimfloatercontainer.h"
 
 // Conversation items
-LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLIMFloaterContainer* containerp) :
-	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
+LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLFolderViewModelItemCommon(root_view_model),
 	mName(display_name),
-	mUUID(uuid),
-    mContainer(containerp)
+	mUUID(uuid)
 {
 }
 
-LLConversationItem::LLConversationItem(LLIMFloaterContainer* containerp) :
-	LLFolderViewModelItemCommon(containerp->getRootViewModel()),
+LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_model) :
+	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
-	mUUID(),
-	mContainer(NULL)
+	mUUID()
 {
 }
 
 
 // Virtual action callbacks
-void LLConversationItem::selectItem(void)
-{
-	LLFloater* session_floater = LLIMConversation::getConversation(mUUID);
-	LLMultiFloater* host_floater = session_floater->getHost();
-
-//	LLIMFloater::show(mUUID);
-	if (host_floater == mContainer)
-	{
-		// Always expand the message pane if the panel is hosted by the container
-		mContainer->collapseMessagesPane(false);
-		// Switch to the conversation floater that is being selected
-		mContainer->selectFloater(session_floater);
-	}
-	// Set the focus on the selected floater
-	session_floater->setFocus(TRUE);
-}
-
 void LLConversationItem::setVisibleIfDetached(BOOL visible)
 {
 	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 56a5b73c15..2f7124aec5 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -52,8 +52,8 @@ typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
 class LLConversationItem : public LLFolderViewModelItemCommon
 {
 public:
-	LLConversationItem(std::string display_name, const LLUUID& uuid, LLIMFloaterContainer* containerp);
-	LLConversationItem(LLIMFloaterContainer* containerp);
+	LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	LLConversationItem(LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItem() {}
 
 	// Stub those things we won't really be using in this conversation context
@@ -95,7 +95,7 @@ public:
 	virtual void openItem( void );
 	virtual void closeItem( void );
 	virtual void previewItem( void );
-	virtual void selectItem(void);
+	virtual void selectItem(void) { } 
 	virtual void showProperties(void);
 
 	void setVisibleIfDetached(BOOL visible);
@@ -114,7 +114,6 @@ public:
 private:
 	std::string mName;
 	const LLUUID mUUID;
-    LLIMFloaterContainer* mContainer;
 };
 
 // We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
new file mode 100644
index 0000000000..7d90a154e5
--- /dev/null
+++ b/indra/newview/llconversationview.cpp
@@ -0,0 +1,64 @@
+/** 
+ * @file llconversationview.cpp
+ * @brief Implementation of conversations list widgets and views
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llconversationview.h"
+#include "llimconversation.h"
+#include "llimfloatercontainer.h"
+
+LLConversationViewSession::Params::Params() :	
+	container()
+{}
+
+LLConversationViewSession::LLConversationViewSession( const LLConversationViewSession::Params& p ):
+	LLFolderViewFolder(p),
+	mContainer(p.container)
+{
+}
+
+void LLConversationViewSession::selectItem()
+{
+	LLFolderViewItem::selectItem();
+	
+	LLConversationItem* item = dynamic_cast<LLConversationItem*>(mViewModelItem);
+	LLFloater* session_floater = LLIMConversation::getConversation(item->getUUID());
+	LLMultiFloater* host_floater = session_floater->getHost();
+	
+	if (host_floater == mContainer)
+	{
+		// Always expand the message pane if the panel is hosted by the container
+		mContainer->collapseMessagesPane(false);
+		// Switch to the conversation floater that is being selected
+		mContainer->selectFloater(session_floater);
+	}
+	
+	// Set the focus on the selected floater
+	session_floater->setFocus(TRUE);
+}
+
+// EOF
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
new file mode 100644
index 0000000000..08f2343aca
--- /dev/null
+++ b/indra/newview/llconversationview.h
@@ -0,0 +1,63 @@
+/** 
+ * @file llconversationview.h
+ * @brief Implementation of conversations list widgets and views
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCONVERSATIONVIEW_H
+#define LL_LLCONVERSATIONVIEW_H
+
+#include "llfolderviewitem.h"
+#include "llfolderviewmodel.h"
+
+class LLButton;
+class LLFloater;
+class LLLayoutPanel;
+class LLLayoutStack;
+class LLTabContainer;
+class LLIMFloaterContainer;
+
+// Implementation of conversations list widgets
+
+class LLConversationViewSession : public LLFolderViewFolder
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
+	{
+		Optional<LLIMFloaterContainer*>			container;
+
+		Params();
+	};
+		
+protected:
+	friend class LLUICtrlFactory;
+	LLConversationViewSession( const Params& p );
+	
+	LLIMFloaterContainer* mContainer;
+	
+public:
+	virtual ~LLConversationViewSession( void ) { }
+	virtual void selectItem();	
+};
+
+#endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 1e136b721c..29878cfc9e 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -43,6 +43,7 @@
 #include "llimview.h"
 #include "lltransientfloatermgr.h"
 #include "llviewercontrol.h"
+#include "llconversationview.h"
 
 //
 // LLIMFloaterContainer
@@ -111,7 +112,7 @@ BOOL LLIMFloaterContainer::postBuild()
 	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
 	// CHUI-98 : View Model for conversations
-	LLConversationItem* base_item = new LLConversationItem(this);
+	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
 	LLFolderView::Params p;
 	p.view_model = &mConversationViewModel;
 	p.parent_panel = mConversationsListPanel;
@@ -470,7 +471,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	removeConversationListItem(uuid,false);
 
 	// Create a conversation item
-	LLConversationItem* item = new LLConversationItem(display_name, uuid, this);
+	LLConversationItem* item = new LLConversationItem(display_name, uuid, getRootViewModel());
 	mConversationsItems[uuid] = item;
 
 	// Create a widget from it
@@ -524,7 +525,7 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 
 LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
 {
-	LLFolderViewItem::Params params;
+	LLConversationViewSession::Params params;
 	
 	params.name = item->getDisplayName();
 	//params.icon = bridge->getIcon();
@@ -534,8 +535,9 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
 	params.listener = item;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
+	params.container = this;
 	
-	return LLUICtrlFactory::create<LLFolderViewItem>(params);
+	return LLUICtrlFactory::create<LLConversationViewSession>(params);
 }
 
 // EOF
-- 
cgit v1.2.3


From 679d0f78f9a4a83e5eb2ec857ceb2d9b8c6f4d91 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 22 Aug 2012 23:14:01 -0700
Subject: CHUI-282 : WIP, Clean up dependencies

---
 indra/newview/llconversationmodel.cpp |  1 -
 indra/newview/llconversationmodel.h   | 10 ----------
 indra/newview/llconversationview.cpp  |  1 +
 indra/newview/llconversationview.h    |  6 ------
 4 files changed, 1 insertion(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 923bc7a3a1..42ed7603d1 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -29,7 +29,6 @@
 
 #include "llconversationmodel.h"
 #include "llimconversation.h"
-#include "llimfloatercontainer.h"
 
 // Conversation items
 LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 2f7124aec5..1ce70d754b 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -27,19 +27,9 @@
 #ifndef LL_LLCONVERSATIONMODEL_H
 #define LL_LLCONVERSATIONMODEL_H
 
-//#include <map>
-//#include <vector>
-
 #include "llfolderviewitem.h"
 #include "llfolderviewmodel.h"
 
-class LLButton;
-class LLFloater;
-class LLLayoutPanel;
-class LLLayoutStack;
-class LLTabContainer;
-class LLIMFloaterContainer;
-
 // Implementation of conversations list
 
 class LLConversationItem;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 7d90a154e5..464d061a82 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -28,6 +28,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llconversationview.h"
+#include "llconversationmodel.h"
 #include "llimconversation.h"
 #include "llimfloatercontainer.h"
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 08f2343aca..743efb6384 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -28,13 +28,7 @@
 #define LL_LLCONVERSATIONVIEW_H
 
 #include "llfolderviewitem.h"
-#include "llfolderviewmodel.h"
 
-class LLButton;
-class LLFloater;
-class LLLayoutPanel;
-class LLLayoutStack;
-class LLTabContainer;
 class LLIMFloaterContainer;
 
 // Implementation of conversations list widgets
-- 
cgit v1.2.3


From 41c85d357c8793f5119246b79441dd1dad9aa563 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 23 Aug 2012 18:07:35 +0300
Subject: CHUI-296 FIXED (Unread IM messages icon not showing in conversation
 log)

- Sometimes IM floater with offline unread messages is visible but not in visible chain and the flag of offline unread messages is erroneously reset.
So made condition of whether floater is visible more strict.
---
 indra/newview/llimfloater.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 5780ac52a5..1c6445610f 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -789,7 +789,7 @@ void LLIMFloater::setVisible(BOOL visible)
 		}
 	}
 
-	if (visible)
+	if (visible && isInVisibleChain())
 	{
 		sIMFloaterShowedSignal(mSessionID);
 	}
-- 
cgit v1.2.3


From 02e4068baaa7bcc49186e9a02a022f3d6cb087ac Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 23 Aug 2012 18:19:13 +0300
Subject: CHUI-306 FIXED (Selecting IM option for Group in conversation log
 does not start an IM if you did not initiate the conversation)

- To start group call or group chat, group_id should be passed as an argument to LLGrupActions, not participant_id.
---
 indra/newview/llconversationloglist.cpp     | 6 +++---
 indra/newview/llconversationloglistitem.cpp | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 0433719a89..257ec082a5 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -193,7 +193,7 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
 			break;
 
 		case LLIMModel::LLIMSession::GROUP_SESSION:
-			LLGroupActions::startIM(selected_id);
+			LLGroupActions::startIM(getSelectedConversation()->getSessionID());
 			break;
 
 		default:
@@ -209,7 +209,7 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
 			break;
 
 		case LLIMModel::LLIMSession::GROUP_SESSION:
-			LLGroupActions::startCall(selected_id);
+			LLGroupActions::startCall(getSelectedConversation()->getSessionID());
 			break;
 
 		default:
@@ -225,7 +225,7 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
 			break;
 
 		case LLIMModel::LLIMSession::GROUP_SESSION:
-			LLGroupActions::show(selected_id);
+			LLGroupActions::show(getSelectedConversation()->getSessionID());
 			break;
 
 		default:
diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
index 9f7c588989..dddf216592 100644
--- a/indra/newview/llconversationloglistitem.cpp
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -168,7 +168,7 @@ void LLConversationLogListItem::onDoubleClick()
 		break;
 
 	case LLIMModel::LLIMSession::GROUP_SESSION:
-		LLGroupActions::startIM(mConversation->getParticipantID());
+		LLGroupActions::startIM(mConversation->getSessionID());
 		break;
 
 	default:
-- 
cgit v1.2.3


From 4ea73df484d22815026367771f9d728d755f6274 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 23 Aug 2012 11:32:20 -0700
Subject: CHUI-282 : WIP : Further separate view from model for llconversation
 items

---
 indra/newview/llconversationmodel.cpp  | 14 --------------
 indra/newview/llconversationmodel.h    |  2 --
 indra/newview/llconversationview.cpp   | 13 +++++++++++++
 indra/newview/llconversationview.h     |  1 +
 indra/newview/llimfloatercontainer.cpp |  6 +++---
 5 files changed, 17 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 42ed7603d1..832dc3c3e4 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -28,7 +28,6 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llconversationmodel.h"
-#include "llimconversation.h"
 
 // Conversation items
 LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
@@ -45,20 +44,7 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 {
 }
 
-
 // Virtual action callbacks
-void LLConversationItem::setVisibleIfDetached(BOOL visible)
-{
-	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
-	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
-	LLFloater* session_floater = LLIMConversation::getConversation(mUUID);
-
-	if (session_floater && !session_floater->getHost() && !session_floater->isMinimized())
-	{
-		session_floater->setVisible(visible);
-	}
-}
-
 void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
 {
 }
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 1ce70d754b..cb03128cac 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -88,8 +88,6 @@ public:
 	virtual void selectItem(void) { } 
 	virtual void showProperties(void);
 
-	void setVisibleIfDetached(BOOL visible);
-	
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
 	// requested. 
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 464d061a82..6cc911ecef 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -62,4 +62,17 @@ void LLConversationViewSession::selectItem()
 	session_floater->setFocus(TRUE);
 }
 
+void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
+{
+	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
+	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
+	LLConversationItem* item = dynamic_cast<LLConversationItem*>(mViewModelItem);
+	LLFloater* session_floater = LLIMConversation::getConversation(item->getUUID());
+	
+	if (session_floater && !session_floater->getHost() && !session_floater->isMinimized())
+	{
+		session_floater->setVisible(visible);
+	}
+}
+
 // EOF
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 743efb6384..6a51e719c8 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -52,6 +52,7 @@ protected:
 public:
 	virtual ~LLConversationViewSession( void ) { }
 	virtual void selectItem();	
+	void setVisibleIfDetached(BOOL visible);
 };
 
 #endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 29878cfc9e..38ac3eb9e4 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -328,10 +328,10 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	// We need to show/hide all the associated conversations that have been torn off
 	// (and therefore, are not longer managed by the multifloater),
 	// so that they show/hide with the conversations manager.
-	conversations_items_map::iterator item_it = mConversationsItems.begin();
-	for (;item_it != mConversationsItems.end(); ++item_it)
+	conversations_widgets_map::iterator item_it = mConversationsWidgets.begin();
+	for (;item_it != mConversationsWidgets.end(); ++item_it)
 	{
-		LLConversationItem* item = item_it->second;
+		LLConversationViewSession* item = dynamic_cast<LLConversationViewSession*>(item_it->second);
 		item->setVisibleIfDetached(visible);
 	}
 	
-- 
cgit v1.2.3


From 42701ad3233bfeddf42fb1163f2b83d810b27131 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 23 Aug 2012 15:14:04 -0700
Subject: CHUI-303: Problem: When pasting the item, the item's filtering flag
 was not updated. The filtering flag determines visibility. Resolution: Upon
 pasting the item to the folder from the clipboard, update the filtering flag
 so that visibility can properly be determined.

---
 indra/newview/llinventorybridge.cpp | 11 +++++++++++
 1 file changed, 11 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 215a08b34a..ac9f087d11 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3194,6 +3194,16 @@ void LLFolderBridge::pasteFromClipboard()
 						llassert(vicat);
 						if (vicat)
 						{
+                            //Set the pasted folder to dirty, could do this in changeCategoryParent() but only need to set dirty
+                            //when pasting from the clipboard. Setting dirty allows updating the filter state, which determines
+                            //visibility in the new pasted location.
+                            
+                            LLFolderViewFolder * folderViewItem = mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(item_id) : NULL;
+                            if(folderViewItem && folderViewItem->getViewModelItem())
+                            {
+                                folderViewItem->getViewModelItem()->dirtyFilter();
+                            }
+                         
 							changeCategoryParent(model, vicat, parent_id, FALSE);
 						}
 					}
@@ -3203,6 +3213,7 @@ void LLFolderBridge::pasteFromClipboard()
 					llassert(viitem);
 					if (viitem)
 					{
+                        //changeItemParent() implicity calls dirtyFilter
 						changeItemParent(model, viitem, parent_id, FALSE);
 					}
 				}
-- 
cgit v1.2.3


From 15d957616ebac22a9f4633b6d806f8519423593b Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 23 Aug 2012 16:11:08 -0700
Subject: CHUI-282 : Use views for UI manipulation, not models

---
 indra/newview/llimfloatercontainer.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 35b9f404c3..32ef292763 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -328,11 +328,11 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	// We need to show/hide all the associated conversations that have been torn off
 	// (and therefore, are not longer managed by the multifloater),
 	// so that they show/hide with the conversations manager.
-	conversations_widgets_map::iterator item_it = mConversationsWidgets.begin();
-	for (;item_it != mConversationsWidgets.end(); ++item_it)
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
 	{
-		LLConversationViewSession* item = dynamic_cast<LLConversationViewSession*>(item_it->second);
-		item->setVisibleIfDetached(visible);
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		widget->setVisibleIfDetached(visible);
 	}
 	
 	// Now, do the normal multifloater show/hide
@@ -513,11 +513,11 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	if (change_focus)
 	{
 		setFocus(TRUE);
-		conversations_items_map::iterator item_it = mConversationsItems.begin();
-		if (item_it != mConversationsItems.end())
+		conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+		if (widget_it != mConversationsWidgets.end())
 		{
-			LLConversationItem* item = item_it->second;
-			item->selectItem();
+			LLFolderViewItem* widget = widget_it->second;
+			widget->selectItem();
 		}
 	}
 }
-- 
cgit v1.2.3


From e537d6477dfa1eea86dc16c767b793fb530d1ebc Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 23 Aug 2012 19:44:10 -0700
Subject: CHUI-98 : Defining the various llconversation sub classes in their
 respective file

---
 indra/newview/llconversationmodel.cpp  | 33 ++++++++++++++++++++++++++++++++-
 indra/newview/llconversationmodel.h    | 16 ++++++++++++++++
 indra/newview/llconversationview.cpp   | 13 +++++++++++++
 indra/newview/llconversationview.h     | 14 +++++++++++++-
 indra/newview/llimfloatercontainer.cpp |  2 +-
 5 files changed, 75 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 832dc3c3e4..f54e6d2d48 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -29,7 +29,10 @@
 
 #include "llconversationmodel.h"
 
-// Conversation items
+//
+// Conversation items : common behaviors
+//
+
 LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(display_name),
@@ -73,4 +76,32 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 	return (compare < 0);
 }
 
+//
+// LLConversationItemSession
+// 
+
+LLConversationItemSession::LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(display_name,uuid,root_view_model)
+{
+}
+
+LLConversationItemSession::LLConversationItemSession(LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(root_view_model)
+{
+}
+
+//
+// LLConversationItemParticipant
+// 
+
+LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(display_name,uuid,root_view_model)
+{
+}
+
+LLConversationItemParticipant::LLConversationItemParticipant(LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(root_view_model)
+{
+}
+
 // EOF
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index cb03128cac..fc2c600364 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -104,6 +104,22 @@ private:
 	const LLUUID mUUID;
 };
 
+class LLConversationItemSession : public LLConversationItem
+{
+public:
+	LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	LLConversationItemSession(LLFolderViewModelInterface& root_view_model);
+	virtual ~LLConversationItemSession() {}
+};
+
+class LLConversationItemParticipant : public LLConversationItem
+{
+public:
+	LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	LLConversationItemParticipant(LLFolderViewModelInterface& root_view_model);
+	virtual ~LLConversationItemParticipant() {}
+};
+
 // We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
 // We just stubb everything for the moment.
 class LLConversationFilter : public LLFolderViewFilter
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 6cc911ecef..fefb7e9cac 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -32,6 +32,10 @@
 #include "llimconversation.h"
 #include "llimfloatercontainer.h"
 
+//
+// Implementation of conversations list session widgets
+//
+
 LLConversationViewSession::Params::Params() :	
 	container()
 {}
@@ -75,4 +79,13 @@ void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
 	}
 }
 
+//
+// Implementation of conversations list participant (avatar) widgets
+//
+
+LLConversationViewParticipant::LLConversationViewParticipant( const LLFolderViewItem::Params& p ):
+	LLFolderViewItem(p)
+{
+}
+
 // EOF
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 6a51e719c8..5695925f43 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -31,7 +31,7 @@
 
 class LLIMFloaterContainer;
 
-// Implementation of conversations list widgets
+// Implementation of conversations list session widgets
 
 class LLConversationViewSession : public LLFolderViewFolder
 {
@@ -55,4 +55,16 @@ public:
 	void setVisibleIfDetached(BOOL visible);
 };
 
+// Implementation of conversations list participant (avatar) widgets
+
+class LLConversationViewParticipant : public LLFolderViewItem
+{
+protected:
+	friend class LLUICtrlFactory;
+	LLConversationViewParticipant( const LLFolderViewItem::Params& p );
+	
+public:
+	virtual ~LLConversationViewParticipant( void ) { }
+};
+
 #endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 32ef292763..4d0bd623f8 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -471,7 +471,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	removeConversationListItem(uuid,false);
 
 	// Create a conversation item
-	LLConversationItem* item = new LLConversationItem(display_name, uuid, getRootViewModel());
+	LLConversationItem* item = new LLConversationItemSession(display_name, uuid, getRootViewModel());
 	mConversationsItems[uuid] = item;
 
 	// Create a widget from it
-- 
cgit v1.2.3


From 6e92b96e88401aaca203b627e84ce311b7f75e4a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 24 Aug 2012 13:53:17 -0700
Subject: kicking off another build (whitespace change)

---
 indra/newview/llinventorybridge.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index ac9f087d11..91798e0f10 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3197,7 +3197,6 @@ void LLFolderBridge::pasteFromClipboard()
                             //Set the pasted folder to dirty, could do this in changeCategoryParent() but only need to set dirty
                             //when pasting from the clipboard. Setting dirty allows updating the filter state, which determines
                             //visibility in the new pasted location.
-                            
                             LLFolderViewFolder * folderViewItem = mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(item_id) : NULL;
                             if(folderViewItem && folderViewItem->getViewModelItem())
                             {
-- 
cgit v1.2.3


From fd62242dd6e5fa464db07e0b8ebf3ab54a6067a2 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 24 Aug 2012 17:31:12 -0700
Subject: CHUI-280 : Make LLParticipantList derives from
 LLConversationItemSession

---
 indra/newview/llcallfloater.cpp       |  2 +-
 indra/newview/llcallfloater.h         |  2 ++
 indra/newview/llconversationmodel.cpp | 15 +++++++++++----
 indra/newview/llconversationmodel.h   |  5 +++--
 indra/newview/llimconversation.cpp    |  4 ++--
 indra/newview/llimconversation.h      |  2 ++
 indra/newview/llparticipantlist.cpp   |  2 ++
 indra/newview/llparticipantlist.h     |  4 +++-
 8 files changed, 26 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index f2375bfa4f..38b755004c 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -334,7 +334,7 @@ void LLCallFloater::refreshParticipantList()
 	if (!non_avatar_caller)
 	{
 		llassert(mParticipants == NULL); // check for possible memory leak
-		mParticipants = new LLParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT, false);
+		mParticipants = new LLParticipantList(mSpeakerManager, mAvatarList, mConversationViewModel, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT, false);
 		mParticipants->setValidateSpeakerCallback(boost::bind(&LLCallFloater::validateSpeaker, this, _1));
 		const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
 		mParticipants->setSortOrder(LLParticipantList::EParticipantSortOrder(speaker_sort_order));
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
index 00a3f76e56..181c92276d 100644
--- a/indra/newview/llcallfloater.h
+++ b/indra/newview/llcallfloater.h
@@ -31,6 +31,7 @@
 #include "lltransientdockablefloater.h"
 #include "llvoicechannel.h"
 #include "llvoiceclient.h"
+#include "llconversationmodel.h"
 
 class LLAvatarList;
 class LLAvatarListItem;
@@ -228,6 +229,7 @@ private:
 	LLSpeakerMgr* mSpeakerManager;
 	LLParticipantList* mParticipants;
 	LLAvatarList* mAvatarList;
+	LLConversationViewModel mConversationViewModel;
 	LLNonAvatarCaller* mNonAvatarCaller;
 	EVoiceControls mVoiceType;
 	LLPanel* mAgentPanel;
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index f54e6d2d48..a5c0244bd4 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -40,6 +40,13 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u
 {
 }
 
+LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLFolderViewModelItemCommon(root_view_model),
+	mName(""),
+	mUUID(uuid)
+{
+}
+
 LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
@@ -85,8 +92,8 @@ LLConversationItemSession::LLConversationItemSession(std::string display_name, c
 {
 }
 
-LLConversationItemSession::LLConversationItemSession(LLFolderViewModelInterface& root_view_model) :
-	LLConversationItem(root_view_model)
+LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(uuid,root_view_model)
 {
 }
 
@@ -99,8 +106,8 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 {
 }
 
-LLConversationItemParticipant::LLConversationItemParticipant(LLFolderViewModelInterface& root_view_model) :
-	LLConversationItem(root_view_model)
+LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(uuid,root_view_model)
 {
 }
 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index fc2c600364..1a63230e41 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -43,6 +43,7 @@ class LLConversationItem : public LLFolderViewModelItemCommon
 {
 public:
 	LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItem(LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItem() {}
 
@@ -108,7 +109,7 @@ class LLConversationItemSession : public LLConversationItem
 {
 public:
 	LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
-	LLConversationItemSession(LLFolderViewModelInterface& root_view_model);
+	LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItemSession() {}
 };
 
@@ -116,7 +117,7 @@ class LLConversationItemParticipant : public LLConversationItem
 {
 public:
 	LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
-	LLConversationItemParticipant(LLFolderViewModelInterface& root_view_model);
+	LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItemParticipant() {}
 };
 
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index ee7f58b01f..f214003947 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -165,7 +165,7 @@ void LLIMConversation::buildParticipantList()
 	if (mIsNearbyChat)
 	{
 		LLLocalSpeakerMgr* speaker_manager = LLLocalSpeakerMgr::getInstance();
-		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);
+		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), mConversationViewModel, true, false);
 	}
 	else
 	{
@@ -174,7 +174,7 @@ void LLIMConversation::buildParticipantList()
 		if(!mIsP2PChat && mSessionID.notNull() && speaker_manager)
 		{
 			delete mParticipantList; // remove the old list and create a new one if the session id has changed
-			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true, false);
+			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), mConversationViewModel, true, false);
 		}
 	}
 	updateHeaderAndToolbar();
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index f21be94ee2..26151ad1be 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -33,6 +33,7 @@
 #include "lltransientdockablefloater.h"
 #include "llviewercontrol.h"
 #include "lleventtimer.h"
+#include "llconversationmodel.h"
 
 class LLPanelChatControlPanel;
 class LLChatEntry;
@@ -104,6 +105,7 @@ protected:
 	LLLayoutPanel* mParticipantListPanel;
 	LLParticipantList* mParticipantList;
 	LLUUID mSessionID;
+	LLConversationViewModel mConversationViewModel;
 
 	LLChatHistory* mChatHistory;
 	LLChatEntry* mInputEditor;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 47518a365f..552ae196dd 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -200,9 +200,11 @@ private:
 
 LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 									 LLAvatarList* avatar_list,
+									 LLFolderViewModelInterface& root_view_model,
 									 bool use_context_menu/* = true*/,
 									 bool exclude_agent /*= true*/,
 									 bool can_toggle_icons /*= true*/) :
+	LLConversationItemSession(data_source->getSessionID(), root_view_model),
 	mSpeakerMgr(data_source),
 	mAvatarList(avatar_list),
 	mParticipantListMenu(NULL),
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 53966c15fe..f8165aa292 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -31,13 +31,14 @@
 #include "llevent.h"
 #include "llavatarlist.h" // for LLAvatarItemRecentSpeakerComparator
 #include "lllistcontextmenu.h"
+#include "llconversationmodel.h"
 
 class LLSpeakerMgr;
 class LLAvatarList;
 class LLUICtrl;
 class LLAvalineUpdater;
 
-class LLParticipantList
+class LLParticipantList : public LLConversationItemSession
 {
 	LOG_CLASS(LLParticipantList);
 public:
@@ -46,6 +47,7 @@ public:
 
 	LLParticipantList(LLSpeakerMgr* data_source, 
 					  LLAvatarList* avatar_list, 
+					  LLFolderViewModelInterface& root_view_model,
 					  bool use_context_menu = true, 
 					  bool exclude_agent = true, 
 					  bool can_toggle_icons = true);
-- 
cgit v1.2.3


From 0804ecb3551514d3321dfd4e3b17c3dab9693444 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 27 Aug 2012 17:41:37 +0300
Subject: removed debug messages

---
 indra/newview/llimconversation.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 2212673d3a..1f4522a96c 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -366,7 +366,6 @@ void LLIMConversation::processChatHistoryStyleUpdate()
 
 void LLIMConversation::updateCallBtnState(bool callIsActive)
 {
-llwarns<<(this->getName())<<llendl;
 	getChild<LLButton>("voice_call_btn")->setImageOverlay(
 			callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
     enableDisableCallBtn();
-- 
cgit v1.2.3


From a1a1410d25c3e4ff87e33344b416b7a827cdb1c2 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Mon, 27 Aug 2012 18:16:47 -0700
Subject: Skipping the realloc alignment test on Linux as the
 ll_aligned_malloc_16() function is not implemented to ensure alignment on
 Linux.

---
 indra/llcommon/llmemory.h             | 2 ++
 indra/llmath/tests/alignment_test.cpp | 4 ++++
 2 files changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 9dd776ff57..08e2a2caa6 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -65,6 +65,8 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size) // returned hunk MUST
 #elif defined(LL_DARWIN)
 	return realloc(ptr,size); // default osx malloc is 16 byte aligned.
 #else
+	// The realloc alignment test is skipped on Linux because the ll_aligned_realloc_16()
+	// function is not implemented to ensure alignment (see alignment_test.cpp)
 	return realloc(ptr,size); // FIXME not guaranteed to be aligned.
 #endif
 }
diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp
index ac0c45ae6f..49c668d737 100644
--- a/indra/llmath/tests/alignment_test.cpp
+++ b/indra/llmath/tests/alignment_test.cpp
@@ -78,8 +78,12 @@ void alignment_test_object_t::test<1>()
 		align_ptr = ll_aligned_malloc_16(sizeof(MyVector4a));
 		ensure("ll_aligned_malloc_16 failed", is_aligned(align_ptr,16));
 
+#if !LL_LINUX
+		// Skipping realloc alignment test on Linux because the ll_aligned_realloc_16()
+		// function is not implemented to ensure alignment on Linux (see llmemory.h)
 		align_ptr = ll_aligned_realloc_16(align_ptr,2*sizeof(MyVector4a));
 		ensure("ll_aligned_realloc_16 failed", is_aligned(align_ptr,16));
+#endif // LL_LINUX
 
 		ll_aligned_free_16(align_ptr);
 
-- 
cgit v1.2.3


From d4ee17e533d652e90989e60bcbc097c81e73d081 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 28 Aug 2012 14:48:32 +0300
Subject: CHUI-275 FIXED (Chat history viewer does not show entire user.txt IM
 log file)

- Renamed LLLogChat::loadAllHistory to LLLogChat::loadChatHistory because it doesn't actually loads all history. Also added parameter to the function which is a flag whether to load all file's content or not.
- Implemented displaying history by pages (as was decided on meeting page): Added showHistory() method to the LLFloaterConversationPreview which shows the chat history page by page starting from the last conversation (or may say starting from the last page). One page contains 100 entries. Added "More history..." button to display next page of history.
---
 indra/newview/app_settings/settings.xml            | 11 +++
 indra/newview/llfloaterconversationpreview.cpp     | 90 +++++++++++++---------
 indra/newview/llfloaterconversationpreview.h       |  7 +-
 indra/newview/llimview.cpp                         |  2 +-
 indra/newview/lllogchat.cpp                        |  6 +-
 indra/newview/lllogchat.h                          |  4 +-
 indra/newview/llnearbychat.cpp                     |  2 +-
 .../xui/en/floater_conversation_preview.xml        | 12 ++-
 8 files changed, 88 insertions(+), 46 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 61bc58b1df..ab1ea6bdbc 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1639,6 +1639,17 @@
       <key>Value</key>
       <string />
     </map>
+    <key>ConversationHistoryPageSize</key>
+    <map>
+      <key>Comment</key>
+      <string>Chat history of conversation opened from call log is displayed by pages. So this is number of entries per page.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>100</integer>
+    </map>
     <key>NearbyChatIsNotTornOff</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index e8554bb066..2c34029c5c 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -33,12 +33,15 @@
 LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
 :	LLFloater(session_id),
 	mChatHistory(NULL),
-	mSessionID(session_id.asUUID())
+	mSessionID(session_id.asUUID()),
+	mCurrentPage(0),
+	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize"))
 {}
 
 BOOL LLFloaterConversationPreview::postBuild()
 {
 	mChatHistory = getChild<LLChatHistory>("chat_history");
+	getChild<LLUICtrl>("more_history")->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this));
 
 	const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID);
 	if (conv)
@@ -52,6 +55,11 @@ BOOL LLFloaterConversationPreview::postBuild()
 		getChild<LLLineEditor>("description")->setValue(name);
 	}
 
+	std::string file = conv->getHistoryFileName();
+	LLLogChat::loadChatHistory(file, mMessages, true);
+
+	mCurrentPage = mMessages.size() / mPageSize;
+
 	return LLFloater::postBuild();
 }
 
@@ -62,51 +70,59 @@ void LLFloaterConversationPreview::draw()
 
 void LLFloaterConversationPreview::onOpen(const LLSD& session_id)
 {
-	const LLConversation* conv = LLConversationLog::instance().getConversation(session_id);
-	if (!conv)
+	showHistory();
+}
+
+void LLFloaterConversationPreview::showHistory()
+{
+	if (!mMessages.size())
 	{
 		return;
 	}
-	std::list<LLSD> messages;
-	std::string file = conv->getHistoryFileName();
-	LLLogChat::loadAllHistory(file, messages);
 
-	if (messages.size())
+	mChatHistory->clear();
+
+	std::ostringstream message;
+	std::list<LLSD>::const_iterator iter = mMessages.begin();
+
+	int delta = 0;
+	if (mCurrentPage)
 	{
-		std::ostringstream message;
-		std::list<LLSD>::const_iterator iter = messages.begin();
-		for (; iter != messages.end(); ++iter)
-		{
-			LLSD msg = *iter;
-
-			std::string time	= msg["time"].asString();
-			LLUUID from_id		= msg["from_id"].asUUID();
-			std::string from	= msg["from"].asString();
-			std::string message	= msg["message"].asString();
-			bool is_history	= msg["is_history"].asBoolean();
-
-			LLChat chat;
-			chat.mFromID = from_id;
-			chat.mSessionID = session_id;
-			chat.mFromName = from;
-			chat.mTimeStr = time;
-			chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
-			chat.mText = message;
-
-			appendMessage(chat);
-		}
+		double num_of_pages = (double)mMessages.size() / mPageSize;
+		delta = (ceil(num_of_pages) - num_of_pages) * mPageSize;
 	}
-}
 
-void LLFloaterConversationPreview::appendMessage(const LLChat& chat)
-{
-	if (!chat.mMuted)
+	std::advance(iter, (mCurrentPage * mPageSize) - delta);
+
+	for (int msg_num = 0; (iter != mMessages.end() && msg_num < mPageSize); ++iter, ++msg_num)
 	{
-		LLSD args;
-		args["use_plain_text_chat_history"] = true;
-		args["show_time"] = true;
-		args["show_names_for_p2p_conv"] = true;
+		LLSD msg = *iter;
+
+		std::string time	= msg["time"].asString();
+		LLUUID from_id		= msg["from_id"].asUUID();
+		std::string from	= msg["from"].asString();
+		std::string message	= msg["message"].asString();
+		bool is_history		= msg["is_history"].asBoolean();
+
+		LLChat chat;
+		chat.mFromID = from_id;
+		chat.mSessionID = mSessionID;
+		chat.mFromName = from;
+		chat.mTimeStr = time;
+		chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
+		chat.mText = message;
 
 		mChatHistory->appendMessage(chat);
 	}
+
+}
+
+void LLFloaterConversationPreview::onMoreHistoryBtnClick()
+{
+	if (--mCurrentPage < 0)
+	{
+		return;
+	}
+
+	showHistory();
 }
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index cfc7c34485..5105ef3702 100644
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -42,10 +42,15 @@ public:
 	virtual void onOpen(const LLSD& session_id);
 
 private:
-	void appendMessage(const LLChat& chat);
+	void onMoreHistoryBtnClick();
+	void showHistory();
 
 	LLChatHistory*	mChatHistory;
 	LLUUID			mSessionID;
+	int				mCurrentPage;
+	int				mPageSize;
+
+	std::list<LLSD> mMessages;
 };
 
 #endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 216db15c94..effcc9a826 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -263,7 +263,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 		std::list<LLSD> chat_history;
 
 		//involves parsing of a chat history
-		LLLogChat::loadAllHistory(mHistoryFileName, chat_history);
+		LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
 		addMessagesFromHistory(chat_history);
 	}
 
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index ebb5912ace..073f5f00c5 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -387,7 +387,7 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
 }
 
 // static
-void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages)
+void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, bool load_all_history/*= false*/)
 {
 	if (file_name.empty())
 	{
@@ -412,8 +412,8 @@ void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& me
 	S32 len;
 	bool firstline = TRUE;
 
-	if (fseek(fptr, (LOG_RECALL_SIZE - 1) * -1  , SEEK_END))
-	{	//File is smaller than recall size.  Get it all.
+	if (load_all_history || fseek(fptr, (LOG_RECALL_SIZE - 1) * -1  , SEEK_END))
+	{	//We need to load the whole historyFile or it's smaller than recall size, so get it all.
 		firstline = FALSE;
 		if (fseek(fptr, 0, SEEK_SET))
 		{
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 27752452c9..95f83e64e5 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -50,12 +50,12 @@ public:
 				const LLUUID& from_id,
 				const std::string& line);
 
-	/** @deprecated @see loadAllHistory() */
+	/** @deprecated @see loadChatHistory() */
 	static void loadHistory(const std::string& filename, 
 		                    void (*callback)(ELogLineType, const LLSD&, void*), 
 							void* userdata);
 
-	static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages);
+	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, bool load_all_history = false);
 private:
 	static std::string cleanFileName(std::string filename);
 };
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a723748094..f1518fe825 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -262,7 +262,7 @@ void LLNearbyChat::loadHistory()
 	do_not_log["do_not_log"] = true;
 
 	std::list<LLSD> history;
-	LLLogChat::loadAllHistory("chat", history);
+	LLLogChat::loadChatHistory("chat", history);
 
 	std::list<LLSD>::const_iterator it = history.begin();
 	while (it != history.end())
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 27b744aefb..c837a0ee57 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -3,7 +3,7 @@
  legacy_header_height="18"
  can_resize="true"
  default_tab_group="1"
- height="361"
+ height="391"
  layout="topleft"
  min_height="243"
  min_width="234"
@@ -50,4 +50,14 @@
      left="5"
      width="390">
     </chat_history>
+    <button
+     follows="bottom|right"
+     height="22"
+     layout="topleft"
+     name="more_history"
+     label="More history..."
+     right="-15"
+     top_pad="5"
+     width="100">
+    </button>
 </floater>
-- 
cgit v1.2.3


From 11e9f66e6217c22373f5d47518f6d1f9885f1793 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 28 Aug 2012 12:41:57 -0700
Subject: BUILDFIX: Correcting a linux build error.

---
 indra/newview/llfloaterconversationpreview.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 2c34029c5c..ae6f1441eb 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -88,8 +88,13 @@ void LLFloaterConversationPreview::showHistory()
 	int delta = 0;
 	if (mCurrentPage)
 	{
-		double num_of_pages = (double)mMessages.size() / mPageSize;
-		delta = (ceil(num_of_pages) - num_of_pages) * mPageSize;
+		// stinson 08/28/2012 : This operation could be simplified using integer math with the mod (%) operator.
+		//                      e.g. The following code should give the same output.
+		//                           int remainder = mMessages.size() % mPageSize;
+		//                           delta = (remainder == 0) ? 0 : (mPageSize - remainder);
+		//                      Though without examining further, the remainder might be a more appropriate value.
+		double num_of_pages = static_cast<double>(mMessages.size()) / static_cast<double>(mPageSize);
+		delta = static_cast<int>((ceil(num_of_pages) - num_of_pages) * static_cast<double>(mPageSize));
 	}
 
 	std::advance(iter, (mCurrentPage * mPageSize) - delta);
-- 
cgit v1.2.3


From 051bc99573d7c571cea0e2e1df332c1e5e97ff19 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Tue, 28 Aug 2012 20:08:17 +0300
Subject: CHUI-287 FIX IM toast panel is closed upon mouse up and doesn't pass
 the mouse click that activates "click to walk".

---
 indra/newview/lltoastimpanel.cpp | 4 ++--
 indra/newview/lltoastimpanel.h   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index e0cb200ef5..75e6e3d13a 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -104,9 +104,9 @@ LLToastIMPanel::~LLToastIMPanel()
 }
 
 //virtual
-BOOL LLToastIMPanel::handleMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLToastIMPanel::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	if (LLPanel::handleMouseDown(x,y,mask) == FALSE)
+	if (LLPanel::handleMouseUp(x,y,mask) == FALSE)
 	{
 		mNotification->respond(mNotification->getResponseTemplate());
 	}
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index 279dd69bc7..3eb11fb3bc 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -52,7 +52,7 @@ public:
 
 	LLToastIMPanel(LLToastIMPanel::Params &p);
 	virtual ~LLToastIMPanel();
-	/*virtual*/ BOOL 	handleMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL 	handleMouseUp(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleToolTip(S32 x, S32 y, MASK mask);
 private:
 	void showInspector();
-- 
cgit v1.2.3


From c4638d1dca7f3292d7ce48ddb2f5598f86282c88 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 28 Aug 2012 19:09:57 -0700
Subject: CHUI-280 : WIP : Implement update of LLConversationModel in
 LLParticipantList

---
 indra/llui/llfolderviewmodel.h        |   9 +++
 indra/newview/llconversationmodel.cpp |  47 ++++++++++++-
 indra/newview/llconversationmodel.h   |  31 ++++++++-
 indra/newview/llparticipantlist.cpp   | 125 ++++++++++++++++++++++------------
 4 files changed, 163 insertions(+), 49 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 41660c6e1e..16d9c86fd7 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -262,6 +262,15 @@ public:
 		child->setParent(NULL); 
 		dirtyFilter();
 	}
+	
+	virtual void clearChildren()
+	{
+		// As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects
+		// This is different and not equivalent to calling removeChild() on each child
+		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
+		mChildren.clear();
+		dirtyFilter();
+	}
 
 	void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
 	{
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a5c0244bd4..9b353809db 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -88,7 +88,8 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 // 
 
 LLConversationItemSession::LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
-	LLConversationItem(display_name,uuid,root_view_model)
+	LLConversationItem(display_name,uuid,root_view_model),
+	mIsLoaded(false)
 {
 }
 
@@ -97,12 +98,54 @@ LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolde
 {
 }
 
+void LLConversationItemSession::addParticipant(LLConversationItemParticipant* item)
+{
+	addChild(item);
+	mIsLoaded = true;
+}
+
+void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* item)
+{
+	removeChild(item);
+}
+
+void LLConversationItemSession::clearParticipants()
+{
+	clearChildren();
+	mIsLoaded = false;
+}
+
+LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
+{
+	// This is *not* a general tree parsing algorithm. It assumes that a session contains only 
+	// items (LLConversationItemParticipant) that have themselve no children.
+	LLConversationItemParticipant* participant = NULL;
+	child_list_t::iterator iter;
+	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+	{
+		participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+		if (participant->hasSameValue(participant_id))
+		{
+			break;
+		}
+	}
+	return (iter == mChildren.end() ? NULL : participant);
+}
+
+void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_id, bool is_muted)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	participant->setIsMuted(is_muted);
+}
+
 //
 // LLConversationItemParticipant
 // 
 
 LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
-	LLConversationItem(display_name,uuid,root_view_model)
+	LLConversationItem(display_name,uuid,root_view_model),
+	mIsMuted(false),
+	mIsModerator(false)
 {
 }
 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 1a63230e41..484c0feb36 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -33,6 +33,8 @@
 // Implementation of conversations list
 
 class LLConversationItem;
+class LLConversationItemSession;
+class LLConversationItemParticipant;
 
 typedef std::map<LLUUID, LLConversationItem*> conversations_items_map;
 typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
@@ -100,9 +102,10 @@ public:
 	
 //	bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
 	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
-private:
-	std::string mName;
-	const LLUUID mUUID;
+
+protected:
+	std::string mName;	// Name of the session or the participant
+	LLUUID mUUID;		// UUID of the session or the participant
 };
 
 class LLConversationItemSession : public LLConversationItem
@@ -111,6 +114,19 @@ public:
 	LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItemSession() {}
+	
+	void setSessionID(const LLUUID& session_id) { mUUID = session_id; }
+	void addParticipant(LLConversationItemParticipant* item);
+	void removeParticipant(LLConversationItemParticipant* item);
+	void clearParticipants();
+	LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);
+
+	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
+	
+	bool isLoaded() { return mIsLoaded; }
+	
+private:
+	bool mIsLoaded;		// true if at least one participant has been added to the session, false otherwise
 };
 
 class LLConversationItemParticipant : public LLConversationItem
@@ -119,6 +135,15 @@ public:
 	LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItemParticipant() {}
+	
+	bool isMuted() { return mIsMuted; }
+	bool isModerator() {return mIsModerator; }
+	void setIsMuted(bool is_muted) { mIsMuted = is_muted; }
+	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; }
+	
+private:
+	bool mIsMuted;		// default is false
+	bool mIsModerator;	// default is false
 };
 
 // We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 552ae196dd..6511b0a1a6 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -29,6 +29,8 @@
 // common includes
 #include "lltrans.h"
 #include "llavataractions.h"
+#include "llavatarnamecache.h"
+#include "llavatarname.h"
 #include "llagent.h"
 
 #include "llimview.h"
@@ -226,29 +228,34 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 	mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
 	mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator");
 
-	mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
-	LL_DEBUGS("SpeakingIndicator") << "Set session for speaking indicators: " << mSpeakerMgr->getSessionID() << LL_ENDL;
-	mAvatarList->setSessionID(mSpeakerMgr->getSessionID());
-	mAvatarListDoubleClickConnection = mAvatarList->setItemDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, _1));
-	mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2));
-    // Set onAvatarListDoubleClicked as default on_return action.
-	mAvatarListReturnConnection = mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
-
-	if (use_context_menu)
-	{
-		//mParticipantListMenu = new LLParticipantListMenu(*this);
-		//mAvatarList->setContextMenu(mParticipantListMenu);
-		mAvatarList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
-	}
-	else
+	setSessionID(mSpeakerMgr->getSessionID());
+	
+	if (mAvatarList)
 	{
-		mAvatarList->setContextMenu(NULL);
-	}
+		mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
+		LL_DEBUGS("SpeakingIndicator") << "Set session for speaking indicators: " << mSpeakerMgr->getSessionID() << LL_ENDL;
+		mAvatarList->setSessionID(mSpeakerMgr->getSessionID());
+		mAvatarListDoubleClickConnection = mAvatarList->setItemDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, _1));
+		mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2));
+		// Set onAvatarListDoubleClicked as default on_return action.
+		mAvatarListReturnConnection = mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
+
+		if (use_context_menu)
+		{
+			//mParticipantListMenu = new LLParticipantListMenu(*this);
+			//mAvatarList->setContextMenu(mParticipantListMenu);
+			mAvatarList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
+		}
+		else
+		{
+			mAvatarList->setContextMenu(NULL);
+		}
 
-	if (use_context_menu && can_toggle_icons)
-	{
-		mAvatarList->setShowIcons("ParticipantListShowIcons");
-		mAvatarListToggleIconsConnection = gSavedSettings.getControl("ParticipantListShowIcons")->getSignal()->connect(boost::bind(&LLAvatarList::toggleIcons, mAvatarList));
+		if (use_context_menu && can_toggle_icons)
+		{
+			mAvatarList->setShowIcons("ParticipantListShowIcons");
+			mAvatarListToggleIconsConnection = gSavedSettings.getControl("ParticipantListShowIcons")->getSignal()->connect(boost::bind(&LLAvatarList::toggleIcons, mAvatarList));
+		}
 	}
 
 	//Lets fill avatarList with existing speakers
@@ -396,6 +403,7 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 
 			if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
 			{
+				setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
 				update_speaker_indicator(list, speakerp->mID, speakerp->mModeratorMutedVoice);
 			}
 		}
@@ -415,30 +423,39 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 */
 void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
 {
-	LLPanel* item = mAvatarList->getItemByValue(participant_id);
-
-	if (NULL == item)
+	if (mAvatarList)
 	{
-		LL_WARNS("Avaline") << "Something wrong. Unable to find item for: " << participant_id << LL_ENDL;
-		return;
-	}
+		LLPanel* item = mAvatarList->getItemByValue(participant_id);
 
-	if (typeid(*item) == typeid(LLAvalineListItem))
-	{
-		LL_DEBUGS("Avaline") << "Avaline caller has already correct class type for: " << participant_id << LL_ENDL;
-		// item representing an Avaline caller has a correct type already.
-		return;
-	}
+		if (NULL == item)
+		{
+			LL_WARNS("Avaline") << "Something wrong. Unable to find item for: " << participant_id << LL_ENDL;
+			return;
+		}
 
-	LL_DEBUGS("Avaline") << "remove item from the list and re-add it: " << participant_id << LL_ENDL;
+		if (typeid(*item) == typeid(LLAvalineListItem))
+		{
+			LL_DEBUGS("Avaline") << "Avaline caller has already correct class type for: " << participant_id << LL_ENDL;
+			// item representing an Avaline caller has a correct type already.
+			return;
+		}
 
-	// remove UUID from LLAvatarList::mIDs to be able add it again.
-	uuid_vec_t& ids = mAvatarList->getIDs();
-	uuid_vec_t::iterator pos = std::find(ids.begin(), ids.end(), participant_id);
-	ids.erase(pos);
+		LL_DEBUGS("Avaline") << "remove item from the list and re-add it: " << participant_id << LL_ENDL;
 
-	// remove item directly
-	mAvatarList->removeItem(item);
+		// remove UUID from LLAvatarList::mIDs to be able add it again.
+		uuid_vec_t& ids = mAvatarList->getIDs();
+		uuid_vec_t::iterator pos = std::find(ids.begin(), ids.end(), participant_id);
+		ids.erase(pos);
+
+		// remove item directly
+		mAvatarList->removeItem(item);
+	}
+	
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		removeParticipant(participant);
+	}
 
 	// re-add avaline caller with a correct class instance.
 	addAvatarIDExceptAgent(participant_id);
@@ -562,6 +579,7 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
 	// update UI on confirmation of moderator mutes
 	if (event->getValue().asString() == "voice")
 	{
+		setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
 		update_speaker_indicator(mAvatarList, speakerp->mID, speakerp->mModeratorMutedVoice);
 	}
 	return true;
@@ -601,21 +619,40 @@ void LLParticipantList::sort()
 void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 {
 	if (mExcludeAgent && gAgent.getID() == avatar_id) return;
-	if (mAvatarList->contains(avatar_id)) return;
+	if (mAvatarList && mAvatarList->contains(avatar_id)) return;
 
 	bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id);
 
+	LLConversationItemParticipant* participant = NULL;
+	
 	if (is_avatar)
 	{
-		mAvatarList->getIDs().push_back(avatar_id);
-		mAvatarList->setDirty();
+		// Create a participant view model instance and add it to the linked list
+		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)
+		{
+			mAvatarList->getIDs().push_back(avatar_id);
+			mAvatarList->setDirty();
+		}
 	}
 	else
 	{
 		std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
-		mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
+		// 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)
+		{
+			mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
+		}
 		mAvalineUpdater->watchAvalineCaller(avatar_id);
 	}
+
+	// *TODO : Merov : need to declare and bind a name update callback on that "participant" instance. See LLAvatarListItem::updateAvatarName() for pattern.
+	// For the moment, we'll get the correct name only if it's already in the name cache (see call to LLAvatarNameCache::get() here above)
+	addParticipant(participant);
+
 	adjustParticipant(avatar_id);
 }
 
-- 
cgit v1.2.3


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(-)

(limited to 'indra')

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


From ca7abc4c3be9310f4e5fec00b7d6ffadaba58ff0 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 29 Aug 2012 10:07:55 -0700
Subject: CHUI-280 : Add print out debug methods

---
 indra/newview/llconversationmodel.cpp | 16 ++++++++++++++++
 indra/newview/llconversationmodel.h   |  4 ++++
 2 files changed, 20 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index dbf5ac6e03..d7f9093a4a 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -159,6 +159,18 @@ void LLConversationItemSession::setParticipantIsModerator(const LLUUID& particip
 	}
 }
 
+void LLConversationItemSession::dumpDebugData()
+{
+	llinfos << "Merov debug : session, uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl;
+	LLConversationItemParticipant* participant = NULL;
+	child_list_t::iterator iter;
+	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+	{
+		participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+		participant->dumpDebugData();
+	}
+}
+
 //
 // LLConversationItemParticipant
 // 
@@ -175,4 +187,8 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 {
 }
 
+void LLConversationItemParticipant::dumpDebugData()
+{
+	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
+}	
 // EOF
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index aa79e5aeb0..af3756c45d 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -127,6 +127,8 @@ public:
 	
 	bool isLoaded() { return mIsLoaded; }
 	
+	void dumpDebugData();
+
 private:
 	bool mIsLoaded;		// true if at least one participant has been added to the session, false otherwise
 };
@@ -143,6 +145,8 @@ public:
 	void setIsMuted(bool is_muted) { mIsMuted = is_muted; }
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; }
 	
+	void dumpDebugData();
+
 private:
 	bool mIsMuted;		// default is false
 	bool mIsModerator;	// default is false
-- 
cgit v1.2.3


From 9ff67f4a040fae53f28aa981309bce2356df1445 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 29 Aug 2012 18:27:21 -0700
Subject: CHUI-285 : WIP : Get the conversation floater to use the same
 LLParticipantList as the IM and call dialog

---
 indra/newview/llconversationmodel.h    |  4 ++--
 indra/newview/llimfloatercontainer.cpp | 21 ++++++++++++++++++---
 2 files changed, 20 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index af3756c45d..1a2e09dfab 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -59,8 +59,8 @@ public:
 	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
 	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
-	virtual BOOL isItemRenameable() const { return FALSE; }
-	virtual BOOL renameItem(const std::string& new_name) { return FALSE; }
+	virtual BOOL isItemRenameable() const { return TRUE; }
+	virtual BOOL renameItem(const std::string& new_name) { mName = new_name; return TRUE; }
 	virtual BOOL isItemMovable( void ) const { return FALSE; }
 	virtual BOOL isItemRemovable( void ) const { return FALSE; }
 	virtual BOOL isItemInTrash( void) const { return FALSE; }
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index a3f5e357c9..55cbf0b266 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -456,7 +456,9 @@ void LLIMFloaterContainer::repositioningWidgets()
 // CHUI-137 : Temporary implementation of conversations list
 void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 {
-	std::string display_name = uuid.isNull()? LLTrans::getString("NearbyChatTitle") : LLIMModel::instance().getName(uuid);
+	bool is_nearby_chat = uuid.isNull();
+	
+	std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatTitle") : LLIMModel::instance().getName(uuid);
 
 	// Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do)
 	// Note: this happens often, when reattaching a torn off conversation for instance
@@ -470,8 +472,21 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	// and nothing wrong will happen removing it if it doesn't exist
 	removeConversationListItem(uuid,false);
 
-	// Create a conversation item
-	LLConversationItem* item = new LLConversationItemSession(display_name, uuid, getRootViewModel());
+	// Create a conversation session model
+	LLConversationItem* item = NULL;
+	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
+	if (speaker_manager)
+	{
+		item = new LLParticipantList(speaker_manager, NULL, getRootViewModel(), true, false);
+	}
+	if (!item)
+	{
+		llinfos << "Merov debug : Couldn't create conversation session item : " << display_name << llendl;
+		return;
+	}
+	// *TODO: Should we flag LLConversationItemSession with a mIsNearbyChat?
+	item->renameItem(display_name);
+	
 	mConversationsItems[uuid] = item;
 
 	// Create a widget from it
-- 
cgit v1.2.3


From be61b5be2f4089e12ca25ca1ece13bd0fdaea543 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 29 Aug 2012 19:18:25 -0700
Subject: CHUI-305: Problem: The 'resident picker' had multiple parents and due
 to the design of the resident picker it can have only one parent. Having
 multiple parents caused both parents to fight for depth ordering...which
 caused the flickering. Resolution: Now multiple 'resident pickers' can exist
 and they are coupled to the floater that spawned then. Meaning that when the
 parent floater closes, the 'resident picker' floater will also close. In
 addition, a shadow frustum eminates from the button that opened the 'resident
 picker'.

---
 indra/llui/llfloater.cpp                 |  7 +++
 indra/newview/llavataractions.cpp        | 10 +++-
 indra/newview/llavataractions.h          |  3 +-
 indra/newview/llfloateravatarpicker.cpp  | 79 ++++++++++++++++++++++++++++++--
 indra/newview/llfloateravatarpicker.h    |  9 +++-
 indra/newview/llfloatercolorpicker.cpp   |  2 +-
 indra/newview/llfloatergodtools.cpp      |  6 ++-
 indra/newview/llfloaterland.cpp          | 12 +++--
 indra/newview/llfloaterregioninfo.cpp    | 26 +++++++++--
 indra/newview/llfloaterreporter.cpp      |  7 ++-
 indra/newview/llfloatersellland.cpp      |  3 +-
 indra/newview/llimfloater.cpp            |  6 ++-
 indra/newview/llimfloatercontainer.cpp   |  4 +-
 indra/newview/llinventorypanel.cpp       |  2 +-
 indra/newview/llpanelblockedlist.cpp     | 26 +++++++++--
 indra/newview/llpanelblockedlist.h       |  2 +
 indra/newview/llpanelgroupinvite.cpp     |  6 ++-
 indra/newview/llpanelmaininventory.cpp   |  2 +-
 indra/newview/llpanelobjectinventory.cpp |  2 +-
 indra/newview/llpanelpeople.cpp          | 20 +++++++-
 indra/newview/llpanelpeople.h            |  3 ++
 indra/newview/llsidepanelinventory.cpp   |  2 +-
 22 files changed, 201 insertions(+), 38 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 8145d6d347..52812dc050 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -713,6 +713,13 @@ void LLFloater::closeFloater(bool app_quitting)
 			make_ui_sound("UISndWindowClose");
 		}
 
+        //If floater is a dependent, remove it from parent (dependee)
+        LLFloater* dependee = mDependeeHandle.get();
+        if (dependee)
+        {
+            dependee->removeDependentFloater(this);
+        }
+
 		// now close dependent floater
 		for(handle_set_iter_t dependent_it = mDependents.begin();
 			dependent_it != mDependents.end(); )
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 93e8b9ca40..9a0c517ee0 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -744,12 +744,13 @@ std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
 }
 
 //static
-void LLAvatarActions::shareWithAvatars()
+void LLAvatarActions::shareWithAvatars(LLPanel * panel)
 {
 	using namespace action_give_inventory;
 
+    LLFloater* root_floater = gFloaterView->getParentFloater(panel);
 	LLFloaterAvatarPicker* picker =
-		LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE);
+		LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE, FALSE, root_floater->getName());
 	if (!picker)
 	{
 		return;
@@ -757,6 +758,11 @@ void LLAvatarActions::shareWithAvatars()
 
 	picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
 	picker->openFriendsTab();
+    
+    if (root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
 	LLNotificationsUtil::add("ShareNotification");
 }
 
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 259e87c336..9d9ce966b5 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -37,6 +37,7 @@
 class LLAvatarName;
 class LLInventoryPanel;
 class LLFloater;
+class LLPanel;
 
 /**
  * Friend-related actions (add, remove, offer teleport, etc)
@@ -117,7 +118,7 @@ public:
 	/**
 	 * Share items with the picked avatars.
 	 */
-	static void shareWithAvatars();
+	static void shareWithAvatars(LLPanel * panel);
 
 	/**
 	 * Block/unblock the avatar.
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 47acdf7057..4ac022e350 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -49,6 +49,8 @@
 #include "llscrolllistcell.h"
 #include "lltabcontainer.h"
 #include "lluictrlfactory.h"
+#include "llfocusmgr.h"
+#include "lldraghandle.h"
 #include "message.h"
 
 //#include "llsdserialize.h"
@@ -56,14 +58,20 @@
 //put it back as a member once the legacy path is out?
 static std::map<LLUUID, LLAvatarName> sAvatarNameMap;
 
+const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
+const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
+const F32 CONTEXT_FADE_TIME = 0.08f;
+
 LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
 												   BOOL allow_multiple,
 												   BOOL closeOnSelect,
-												   BOOL skip_agent)
+												   BOOL skip_agent,
+                                                   const std::string& name,
+                                                   LLView * frustumOrigin)
 {
 	// *TODO: Use a key to allow this not to be an effective singleton
 	LLFloaterAvatarPicker* floater = 
-		LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
+		LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker", LLSD(name));
 	if (!floater)
 	{
 		llwarns << "Cannot instantiate avatar picker" << llendl;
@@ -85,6 +93,11 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
 		floater->getChild<LLButton>("cancel_btn")->setLabel(close_string);
 	}
 
+    if(frustumOrigin)
+    {
+        floater->mFrustumOrigin = frustumOrigin->getHandle();
+    }
+
 	return floater;
 }
 
@@ -93,7 +106,8 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
   : LLFloater(key),
 	mNumResultsReturned(0),
 	mNearMeListComplete(FALSE),
-	mCloseOnSelect(FALSE)
+	mCloseOnSelect(FALSE),
+    mContextConeOpacity	( 0.f )
 {
 	mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this));
 }
@@ -340,8 +354,67 @@ void LLFloaterAvatarPicker::populateFriend()
 	friends_scroller->sortByColumnIndex(0, TRUE);
 }
 
+void LLFloaterAvatarPicker::drawFrustum()
+{
+    if(mFrustumOrigin.get())
+    {
+        LLView * frustumOrigin = mFrustumOrigin.get();
+        LLRect origin_rect;
+        frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
+        // draw context cone connecting color picker with color swatch in parent floater
+        LLRect local_rect = getLocalRect();
+        if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
+        {
+            gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+            LLGLEnable(GL_CULL_FACE);
+            gGL.begin(LLRender::QUADS);
+            {
+                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+                gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
+                gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
+                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+                gGL.vertex2i(local_rect.mRight, local_rect.mTop);
+                gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
+
+                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+                gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
+                gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
+                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+                gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
+                gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
+
+                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+                gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
+                gGL.vertex2i(local_rect.mRight, local_rect.mTop);
+                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+                gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
+                gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
+
+                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+                gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
+                gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
+                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+                gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
+                gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
+            }
+            gGL.end();
+        }
+
+        if (gFocusMgr.childHasMouseCapture(getDragHandle()))
+        {
+            mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+        }
+        else
+        {
+            mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+        }
+    }
+}
+
 void LLFloaterAvatarPicker::draw()
 {
+    drawFrustum();
+
 	// sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars).
 	// lets check this via mOkButtonValidateSignal callback periodically.
 	static LLFrameTimer timer;
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index 7067cd7b3e..46b685ad02 100644
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -34,7 +34,7 @@
 class LLAvatarName;
 class LLScrollListCtrl;
 
-class LLFloaterAvatarPicker : public LLFloater
+class LLFloaterAvatarPicker :public LLFloater
 {
 public:
 	typedef boost::signals2::signal<bool(const uuid_vec_t&), boost_boolean_combiner> validate_signal_t;
@@ -46,7 +46,9 @@ public:
 	static LLFloaterAvatarPicker* show(select_callback_t callback, 
 									   BOOL allow_multiple = FALSE,
 									   BOOL closeOnSelect = FALSE,
-									   BOOL skip_agent = FALSE);
+									   BOOL skip_agent = FALSE,
+                                       const std::string& name = "",
+                                       LLView * frustumOrigin = NULL);
 
 	LLFloaterAvatarPicker(const LLSD& key);
 	virtual ~LLFloaterAvatarPicker();
@@ -86,6 +88,7 @@ private:
 	void setAllowMultiple(BOOL allow_multiple);
 	LLScrollListCtrl* getActiveList();
 
+    void drawFrustum();
 	virtual void draw();
 	virtual BOOL handleKeyHere(KEY key, MASK mask);
 
@@ -94,6 +97,8 @@ private:
 	BOOL				mNearMeListComplete;
 	BOOL				mCloseOnSelect;
 	BOOL                mExcludeAgentFromSearchResults;
+    LLHandle <LLView>   mFrustumOrigin;
+    F32		            mContextConeOpacity;
 
 	validate_signal_t mOkButtonValidateSignal;
 	select_callback_t mSelectionCallback;
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 05d73c2416..1cebdcffca 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -486,7 +486,7 @@ void LLFloaterColorPicker::draw()
 	mSwatch->localRectToOtherView(mSwatch->getLocalRect(), &swatch_rect, this);
 	// draw context cone connecting color picker with color swatch in parent floater
 	LLRect local_rect = getLocalRect();
-	if (gFocusMgr.childHasKeyboardFocus(this) && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
+	if (hasFocus() && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLGLEnable(GL_CULL_FACE);
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index fb905eae11..51745fb191 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -1123,11 +1123,13 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const
 
 void LLPanelObjectTools::onClickSet()
 {
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2));
+    LLView * button = getChildView("Set Target");
+    LLFloater * root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2), FALSE, FALSE, FALSE, root_floater->getName(), button);
 	// grandparent is a floater, which can have a dependent
 	if (picker)
 	{
-		gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 55f3d548ec..64336b5cf7 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2733,11 +2733,13 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
 
 void LLPanelLandAccess::onClickAddAccess()
 {
+    LLView * button = getChildView("add_allowed");
+    LLFloater * root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
-		boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1));
+		boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button);
 	if (picker)
 	{
-		gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
@@ -2782,11 +2784,13 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data)
 // static
 void LLPanelLandAccess::onClickAddBanned()
 {
+    LLView * button = getChildView("add_banned");
+    LLFloater * root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
-		boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1));
+		boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button);
 	if (picker)
 	{
-		gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index fe29bb38c7..4aebd9a4f4 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -648,7 +648,7 @@ void LLPanelRegionGeneralInfo::onClickKick()
 	// this depends on the grandparent view being a floater
 	// in order to set up floater dependency
 	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE);
+	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE, FALSE, parent_floater->getName());
 	if (child_floater)
 	{
 		parent_floater->addDependentFloater(child_floater);
@@ -924,7 +924,12 @@ BOOL LLPanelRegionDebugInfo::sendUpdate()
 
 void LLPanelRegionDebugInfo::onClickChooseAvatar()
 {
-	LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), FALSE, TRUE);
+    LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+	LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), FALSE, TRUE, FALSE, parent_floater->getName());
+	if (child_floater)
+	{
+		parent_floater->addDependentFloater(child_floater);
+	}
 }
 
 
@@ -1471,7 +1476,7 @@ void LLPanelEstateInfo::onClickKickUser()
 	// this depends on the grandparent view being a floater
 	// in order to set up floater dependency
 	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE);
+	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE, FALSE, parent_floater->getName());
 	if (child_floater)
 	{
 		parent_floater->addDependentFloater(child_floater);
@@ -1646,8 +1651,21 @@ bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& res
 	}
 
 	LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]);
+    //Get parent floater name
+    LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
+    LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL;
+    const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : "";
+    
 	// avatar picker yes multi-select, yes close-on-select
-	LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), TRUE, TRUE);
+	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), 
+                                                    TRUE, TRUE, FALSE, parent_floater_name);
+
+    //Allows the closed parent floater to close the child floater (avatar picker)
+    if (child_floater)
+    {
+        parent_floater->addDependentFloater(child_floater);
+    }
+
 	return false;
 }
 
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 3ec1e372eb..206bcb2c7e 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -285,10 +285,13 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
 
 void LLFloaterReporter::onClickSelectAbuser()
 {
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE );
+    LLView * button = getChildView("select_abuser", TRUE);
+
+    LLFloater * root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button);
 	if (picker)
 	{
-		gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 64c0dfa023..2ac82c553b 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -392,7 +392,8 @@ void LLFloaterSellLandUI::onChangeValue(LLUICtrl *ctrl, void *userdata)
 
 void LLFloaterSellLandUI::doSelectAgent()
 {
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE);
+    LLView * button = getChildView("sell_to_select_agent");
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE, FALSE, this->getName(), button);
 	// grandparent is a floater, in order to set up dependency
 	if (picker)
 	{
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 1c6445610f..732a204ddf 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -359,7 +359,9 @@ BOOL LLIMFloater::postBuild()
 
 void LLIMFloater::onAddButtonClicked()
 {
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::addSessionParticipants, this, _1), TRUE, TRUE);
+    LLView * button = getChildView("toolbar_panel")->getChildView("add_btn");
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::addSessionParticipants, this, _1), TRUE, TRUE, FALSE, root_floater->getName(), button);
 	if (!picker)
 	{
 		return;
@@ -367,7 +369,7 @@ void LLIMFloater::onAddButtonClicked()
 
 	// Need to disable 'ok' button when selected users are already in conversation.
 	picker->setOkBtnEnableCb(boost::bind(&LLIMFloater::canAddSelectedToChat, this, _1));
-	LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	
 	if (root_floater)
 	{
 		root_floater->addDependentFloater(picker);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4d0bd623f8..bfe4afe80b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -415,8 +415,10 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 
 void LLIMFloaterContainer::onAddButtonClicked()
 {
-    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloaterContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE);
+    LLView * button = getChildView("conversations_pane_buttons_expanded")->getChildView("add_btn");
     LLFloater* root_floater = gFloaterView->getParentFloater(this);
+    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloaterContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE, root_floater->getName(), button);
+    
     if (picker && root_floater)
     {
         root_floater->addDependentFloater(picker);
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 03dfada77c..2a84616ddf 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -147,7 +147,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2));
 	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));
 	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
-	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));
+	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars, this));
 
 }
 
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 35cda14f8d..8d03930699 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -66,10 +66,19 @@ LLPanelBlockedList::LLPanelBlockedList()
 	mEnableCallbackRegistrar.add("Block.Check",		boost::bind(&LLPanelBlockedList::isActionChecked, this, _2));
 }
 
+void LLPanelBlockedList::removePicker()
+{
+    if(mPicker.get())
+    {
+        mPicker.get()->closeFloater();
+    }
+}
+
 BOOL LLPanelBlockedList::postBuild()
 {
 	mBlockedList = getChild<LLBlockList>("blocked");
 	mBlockedList->setCommitOnSelectionChange(TRUE);
+    this->setVisibleCallback(boost::bind(&LLPanelBlockedList::removePicker, this));
 
 	switch (gSavedSettings.getU32("BlockPeopleSortOrder"))
 	{
@@ -185,11 +194,18 @@ void LLPanelBlockedList::blockResidentByName()
 {
 	const BOOL allow_multiple = FALSE;
 	const BOOL close_on_select = TRUE;
-	/*LLFloaterAvatarPicker* picker = */LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2), allow_multiple, close_on_select);
-
-	// *TODO: mantipov: should LLFloaterAvatarPicker be closed when panel is closed?
-	// old Floater dependency is not enable in panel
-	// addDependentFloater(picker);
+    
+    LLView * button = getChildView("plus_btn", TRUE);
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker * picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2), 
+                                                                                    allow_multiple, close_on_select, FALSE, root_floater->getName(), button);
+    
+    if (root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
+
+    mPicker = picker->getHandle();
 }
 
 void LLPanelBlockedList::blockObjectByName()
diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h
index 332349dfc0..07f0437656 100644
--- a/indra/newview/llpanelblockedlist.h
+++ b/indra/newview/llpanelblockedlist.h
@@ -61,6 +61,7 @@ private:
 		E_SORT_BY_TYPE = 1,
 	} ESortOrder;
 
+    void removePicker();
 	void updateButtons();
 
 	// UI callbacks
@@ -78,6 +79,7 @@ private:
 
 private:
 	LLBlockList* mBlockedList;
+    LLHandle<LLFloater> mPicker;
 };
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 00dd206571..290e38ee1f 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -301,11 +301,13 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata)
 		//Soon the avatar picker will be embedded into this panel
 		//instead of being it's own separate floater.  But that is next week.
 		//This will do for now. -jwolk May 10, 2006
+        LLView * button = panelp->getChildView("add_button");
+        LLFloater * root_floater = gFloaterView->getParentFloater(panelp);
 		LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
-			boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE);
+			boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button);
 		if (picker)
 		{
-			gFloaterView->getParentFloater(panelp)->addDependentFloater(picker);
+			root_floater->addDependentFloater(picker);
 		}
 	}
 }
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index eb3877da5a..35cb3d59c5 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -118,7 +118,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
 	mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
 	mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
 	mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
-	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));
+	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars, this));
 
 	mSavedFolderState = new LLSaveFolderState();
 	mSavedFolderState->setApply(FALSE);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 82956beb3d..de12826452 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1498,7 +1498,7 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par
 	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));
 	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));
 	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing));
-	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));
+	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars, this));
 }
 
 // Destroys the object
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 260de40eef..14045df42e 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -556,6 +556,15 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LL
 	}
 }
 
+
+void LLPanelPeople::removePicker()
+{
+    if(mPicker.get())
+    {
+        mPicker.get()->closeFloater();
+    }
+}
+
 BOOL LLPanelPeople::postBuild()
 {
 	getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
@@ -571,6 +580,7 @@ BOOL LLPanelPeople::postBuild()
 	LLPanel* friends_tab = getChild<LLPanel>(FRIENDS_TAB_NAME);
 	// updater is active only if panel is visible to user.
 	friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2));
+    friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::removePicker, this));
 	mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online");
 	mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");
 	mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
@@ -1079,8 +1089,12 @@ bool LLPanelPeople::isItemsFreeOfFriends(const uuid_vec_t& uuids)
 
 void LLPanelPeople::onAddFriendWizButtonClicked()
 {
+    LLPanel* cur_panel = mTabContainer->getCurrentPanel();
+    LLView * button = cur_panel->getChildView("friends_add_btn", TRUE);
+
 	// Show add friend wizard.
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::onAvatarPicked, _1, _2), FALSE, TRUE);
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::onAvatarPicked, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button);
 	if (!picker)
 	{
 		return;
@@ -1088,11 +1102,13 @@ void LLPanelPeople::onAddFriendWizButtonClicked()
 
 	// Need to disable 'ok' button when friend occurs in selection
 	picker->setOkBtnEnableCb(boost::bind(&LLPanelPeople::isItemsFreeOfFriends, this, _1));
-	LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	
 	if (root_floater)
 	{
 		root_floater->addDependentFloater(picker);
 	}
+
+    mPicker = picker->getHandle();
 }
 
 void LLPanelPeople::onDeleteFriendButtonClicked()
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index da27f83074..4740964dee 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -68,6 +68,8 @@ private:
 		E_SORT_BY_RECENT_SPEAKERS = 4,
 	} ESortOrder;
 
+    void				    removePicker();
+
 	// methods indirectly called by the updaters
 	void					updateFriendListHelpText();
 	void					updateFriendList();
@@ -139,6 +141,7 @@ private:
 	Updater*				mNearbyListUpdater;
 	Updater*				mRecentListUpdater;
 	Updater*				mButtonsUpdater;
+    LLHandle< LLFloater >	mPicker;
 };
 
 #endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index acb232c77f..8915bb2fef 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -448,7 +448,7 @@ void LLSidepanelInventory::onInfoButtonClicked()
 
 void LLSidepanelInventory::onShareButtonClicked()
 {
-	LLAvatarActions::shareWithAvatars();
+	LLAvatarActions::shareWithAvatars(this);
 }
 
 void LLSidepanelInventory::onShopButtonClicked()
-- 
cgit v1.2.3


From d67c295d8bb6cfd58655bf961dcf835157abb3e7 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 30 Aug 2012 16:20:27 -0700
Subject: CHUI-305: Minor changes after code review. Using templated
 findChild() instead of getChildView(). Also using settings.xml to store
 common custom variables.

---
 indra/newview/app_settings/settings.xml | 33 +++++++++++++++++++++++++++++++
 indra/newview/llavataractions.cpp       |  2 +-
 indra/newview/llavataractions.h         |  4 ++--
 indra/newview/llfloateravatarpicker.cpp | 35 ++++++++++++++++++---------------
 indra/newview/llfloateravatarpicker.h   |  3 +++
 indra/newview/llfloatercolorpicker.cpp  | 34 ++++++++++++++++++--------------
 indra/newview/llfloatercolorpicker.h    |  4 ++++
 indra/newview/llfloatergodtools.cpp     |  2 +-
 indra/newview/llfloaterland.cpp         |  4 ++--
 indra/newview/llfloaterreporter.cpp     |  2 +-
 indra/newview/llfloatersellland.cpp     |  2 +-
 indra/newview/llimfloater.cpp           |  2 +-
 indra/newview/llimfloatercontainer.cpp  |  2 +-
 indra/newview/llpanelblockedlist.cpp    |  2 +-
 indra/newview/llpanelgroupinvite.cpp    |  2 +-
 indra/newview/llpanelpeople.cpp         |  2 +-
 16 files changed, 91 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ab1ea6bdbc..b98fea7032 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1639,6 +1639,39 @@
       <key>Value</key>
       <string />
     </map>
+    <key>ContextConeInAlpha</key>
+    <map>
+      <key>Comment</key>
+      <string>Cone In Alpha</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>0.0</real>
+    </map>
+    <key>ContextConeOutAlpha</key>
+    <map>
+      <key>Comment</key>
+      <string>Cone Out Alpha</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>1.0</real>
+    </map>
+    <key>ContextConeFadeTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Cone Fade Time</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>.08</real>
+    </map>
     <key>ConversationHistoryPageSize</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 9a0c517ee0..42a0376774 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -744,7 +744,7 @@ std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
 }
 
 //static
-void LLAvatarActions::shareWithAvatars(LLPanel * panel)
+void LLAvatarActions::shareWithAvatars(LLView * panel)
 {
 	using namespace action_give_inventory;
 
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 9d9ce966b5..473b9cecc3 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -37,7 +37,7 @@
 class LLAvatarName;
 class LLInventoryPanel;
 class LLFloater;
-class LLPanel;
+class LLView;
 
 /**
  * Friend-related actions (add, remove, offer teleport, etc)
@@ -118,7 +118,7 @@ public:
 	/**
 	 * Share items with the picked avatars.
 	 */
-	static void shareWithAvatars(LLPanel * panel);
+	static void shareWithAvatars(LLView * panel);
 
 	/**
 	 * Block/unblock the avatar.
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 4ac022e350..3d6441553d 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -58,10 +58,6 @@
 //put it back as a member once the legacy path is out?
 static std::map<LLUUID, LLAvatarName> sAvatarNameMap;
 
-const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
-const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
-const F32 CONTEXT_FADE_TIME = 0.08f;
-
 LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
 												   BOOL allow_multiple,
 												   BOOL closeOnSelect,
@@ -106,10 +102,17 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
   : LLFloater(key),
 	mNumResultsReturned(0),
 	mNearMeListComplete(FALSE),
-	mCloseOnSelect(FALSE),
-    mContextConeOpacity	( 0.f )
+	mCloseOnSelect(FALSE),a
+    mContextConeOpacity	(0.f),
+    mContextConeInAlpha(0.f),
+    mContextConeOutAlpha(0.f),
+    mContextConeFadeTime(0.f)
 {
 	mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this));
+
+    mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+    mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+    mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
 }
 
 BOOL LLFloaterAvatarPicker::postBuild()
@@ -369,31 +372,31 @@ void LLFloaterAvatarPicker::drawFrustum()
             LLGLEnable(GL_CULL_FACE);
             gGL.begin(LLRender::QUADS);
             {
-                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
                 gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
                 gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
-                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
                 gGL.vertex2i(local_rect.mRight, local_rect.mTop);
                 gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
 
-                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
                 gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
                 gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
-                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
                 gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
                 gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
 
-                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
                 gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
                 gGL.vertex2i(local_rect.mRight, local_rect.mTop);
-                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
                 gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
                 gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
 
-                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
                 gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
                 gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
-                gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
                 gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
                 gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
             }
@@ -402,11 +405,11 @@ void LLFloaterAvatarPicker::drawFrustum()
 
         if (gFocusMgr.childHasMouseCapture(getDragHandle()))
         {
-            mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+            mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
         }
         else
         {
-            mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+            mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
         }
     }
 }
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index 46b685ad02..ed3e51c56f 100644
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -99,6 +99,9 @@ private:
 	BOOL                mExcludeAgentFromSearchResults;
     LLHandle <LLView>   mFrustumOrigin;
     F32		            mContextConeOpacity;
+    F32                 mContextConeInAlpha;
+    F32                 mContextConeOutAlpha;
+    F32                 mContextConeFadeTime;
 
 	validate_signal_t mOkButtonValidateSignal;
 	select_callback_t mSelectionCallback;
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 1cebdcffca..3c230bc58c 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -62,10 +62,6 @@
 #include <sstream>
 #include <iomanip>
 
-const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
-const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
-const F32 CONTEXT_FADE_TIME = 0.08f;
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // Class LLFloaterColorPicker
@@ -105,7 +101,10 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
 	  mSwatch				( swatch ),
 	  mActive				( TRUE ),
 	  mCanApplyImmediately	( show_apply_immediate ),
-	  mContextConeOpacity	( 0.f )
+	  mContextConeOpacity	( 0.f ),
+      mContextConeInAlpha   ( 0.f ),
+      mContextConeOutAlpha   ( 0.f ),
+      mContextConeFadeTime   ( 0.f )
 {
 	buildFromFile ( "floater_color_picker.xml");
 
@@ -117,6 +116,10 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
 		mApplyImmediateCheck->setEnabled(FALSE);
 		mApplyImmediateCheck->set(FALSE);
 	}
+
+    mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+    mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+    mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
 }
 
 LLFloaterColorPicker::~LLFloaterColorPicker()
@@ -492,31 +495,31 @@ void LLFloaterColorPicker::draw()
 		LLGLEnable(GL_CULL_FACE);
 		gGL.begin(LLRender::QUADS);
 		{
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
 			gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
 			gGL.vertex2i(local_rect.mRight, local_rect.mTop);
 			gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
 
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
 			gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
 			gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
 
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
 			gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
 			gGL.vertex2i(local_rect.mRight, local_rect.mTop);
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
 			gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
 
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
 			gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
 			gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
 		}
@@ -525,11 +528,12 @@ void LLFloaterColorPicker::draw()
 
 	if (gFocusMgr.childHasMouseCapture(getDragHandle()))
 	{
-		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), 
+                                        LLCriticalDamp::getInterpolant(mContextConeFadeTime));
 	}
 	else
 	{
-		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
 	}
 
 	mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 8e387c4f7c..bab0617712 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -189,6 +189,10 @@ class LLFloaterColorPicker
 		LLButton* mPipetteBtn;
 
 		F32		  mContextConeOpacity;
+        F32       mContextConeInAlpha;
+        F32       mContextConeOutAlpha;
+        F32       mContextConeFadeTime;
+
 };
 
 #endif // LL_LLFLOATERCOLORPICKER_H
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index 51745fb191..38abdcc830 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -1123,7 +1123,7 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const
 
 void LLPanelObjectTools::onClickSet()
 {
-    LLView * button = getChildView("Set Target");
+    LLView * button = findChild<LLButton>("Set Target");
     LLFloater * root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2), FALSE, FALSE, FALSE, root_floater->getName(), button);
 	// grandparent is a floater, which can have a dependent
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 64336b5cf7..4fc6684e8e 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2733,7 +2733,7 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
 
 void LLPanelLandAccess::onClickAddAccess()
 {
-    LLView * button = getChildView("add_allowed");
+    LLView * button = findChild<LLButton>("add_allowed");
     LLFloater * root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
 		boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button);
@@ -2784,7 +2784,7 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data)
 // static
 void LLPanelLandAccess::onClickAddBanned()
 {
-    LLView * button = getChildView("add_banned");
+    LLView * button = findChild<LLButton>("add_banned");
     LLFloater * root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
 		boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button);
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 206bcb2c7e..cf2481f99a 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -285,7 +285,7 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
 
 void LLFloaterReporter::onClickSelectAbuser()
 {
-    LLView * button = getChildView("select_abuser", TRUE);
+    LLView * button = findChild<LLButton>("select_abuser", TRUE);
 
     LLFloater * root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button);
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 2ac82c553b..484ecbcd04 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -392,7 +392,7 @@ void LLFloaterSellLandUI::onChangeValue(LLUICtrl *ctrl, void *userdata)
 
 void LLFloaterSellLandUI::doSelectAgent()
 {
-    LLView * button = getChildView("sell_to_select_agent");
+    LLView * button = findChild<LLView>("sell_to_select_agent");
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE, FALSE, this->getName(), button);
 	// grandparent is a floater, in order to set up dependency
 	if (picker)
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 732a204ddf..a601561c62 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -359,7 +359,7 @@ BOOL LLIMFloater::postBuild()
 
 void LLIMFloater::onAddButtonClicked()
 {
-    LLView * button = getChildView("toolbar_panel")->getChildView("add_btn");
+    LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn");
     LLFloater* root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::addSessionParticipants, this, _1), TRUE, TRUE, FALSE, root_floater->getName(), button);
 	if (!picker)
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index fe00f70a28..d382b61921 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -415,7 +415,7 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 
 void LLIMFloaterContainer::onAddButtonClicked()
 {
-    LLView * button = getChildView("conversations_pane_buttons_expanded")->getChildView("add_btn");
+    LLView * button = findChild<LLView>("conversations_pane_buttons_expanded")->findChild<LLButton>("add_btn");
     LLFloater* root_floater = gFloaterView->getParentFloater(this);
     LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloaterContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE, root_floater->getName(), button);
     
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 8d03930699..7612af8f5e 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -195,7 +195,7 @@ void LLPanelBlockedList::blockResidentByName()
 	const BOOL allow_multiple = FALSE;
 	const BOOL close_on_select = TRUE;
     
-    LLView * button = getChildView("plus_btn", TRUE);
+    LLView * button = findChild<LLButton>("plus_btn", TRUE);
     LLFloater* root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker * picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2), 
                                                                                     allow_multiple, close_on_select, FALSE, root_floater->getName(), button);
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 290e38ee1f..36bd5d9b77 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -301,7 +301,7 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata)
 		//Soon the avatar picker will be embedded into this panel
 		//instead of being it's own separate floater.  But that is next week.
 		//This will do for now. -jwolk May 10, 2006
-        LLView * button = panelp->getChildView("add_button");
+        LLView * button = panelp->findChild<LLButton>("add_button");
         LLFloater * root_floater = gFloaterView->getParentFloater(panelp);
 		LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
 			boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 14045df42e..90e857265d 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -1090,7 +1090,7 @@ bool LLPanelPeople::isItemsFreeOfFriends(const uuid_vec_t& uuids)
 void LLPanelPeople::onAddFriendWizButtonClicked()
 {
     LLPanel* cur_panel = mTabContainer->getCurrentPanel();
-    LLView * button = cur_panel->getChildView("friends_add_btn", TRUE);
+    LLView * button = cur_panel->findChild<LLButton>("friends_add_btn", TRUE);
 
 	// Show add friend wizard.
     LLFloater* root_floater = gFloaterView->getParentFloater(this);
-- 
cgit v1.2.3


From 1aadf94fe44036d6012eb7d4f8a0b9288a719f37 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 30 Aug 2012 17:24:19 -0700
Subject: CHUI-305: Now the Region/Estate floater displays the frustum shadow
 when opening the Resident Picker.

---
 indra/newview/llfloateravatarpicker.cpp |  2 +-
 indra/newview/llfloaterregioninfo.cpp   | 32 ++++++++++++++++++++++++++++----
 2 files changed, 29 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 3d6441553d..2152de1035 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -102,7 +102,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
   : LLFloater(key),
 	mNumResultsReturned(0),
 	mNearMeListComplete(FALSE),
-	mCloseOnSelect(FALSE),a
+	mCloseOnSelect(FALSE),
     mContextConeOpacity	(0.f),
     mContextConeInAlpha(0.f),
     mContextConeOutAlpha(0.f),
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 4aebd9a4f4..e6b76159a1 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -647,8 +647,10 @@ void LLPanelRegionGeneralInfo::onClickKick()
 
 	// this depends on the grandparent view being a floater
 	// in order to set up floater dependency
+    LLView * button = findChild<LLButton>("kick_btn");
 	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE, FALSE, parent_floater->getName());
+	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), 
+                                                                                FALSE, TRUE, FALSE, parent_floater->getName(), button);
 	if (child_floater)
 	{
 		parent_floater->addDependentFloater(child_floater);
@@ -924,8 +926,10 @@ BOOL LLPanelRegionDebugInfo::sendUpdate()
 
 void LLPanelRegionDebugInfo::onClickChooseAvatar()
 {
+    LLView * button = findChild<LLButton>("choose_avatar_btn");
     LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-	LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), FALSE, TRUE, FALSE, parent_floater->getName());
+	LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), 
+                                                                                    FALSE, TRUE, FALSE, parent_floater->getName(), button);
 	if (child_floater)
 	{
 		parent_floater->addDependentFloater(child_floater);
@@ -1475,8 +1479,10 @@ void LLPanelEstateInfo::onClickKickUser()
 {
 	// this depends on the grandparent view being a floater
 	// in order to set up floater dependency
+    LLView * button = findChild<LLButton>("kick_user_from_estate_btn");
 	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE, FALSE, parent_floater->getName());
+	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), 
+                                                                        FALSE, TRUE, FALSE, parent_floater->getName(), button);
 	if (child_floater)
 	{
 		parent_floater->addDependentFloater(child_floater);
@@ -1656,9 +1662,27 @@ bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& res
     LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL;
     const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : "";
     
+    //Determine the button that triggered opening of the avatar picker 
+    //(so that a shadow frustum from the button to the avatar picker can be created)
+    LLView * button = NULL;
+    switch(change_info->mOperationFlag)
+    {
+        case ESTATE_ACCESS_ALLOWED_AGENT_ADD:
+            button = panel->findChild<LLButton>("add_allowed_avatar_btn");
+            break;
+            
+        case ESTATE_ACCESS_BANNED_AGENT_ADD:
+            button = panel->findChild<LLButton>("add_banned_avatar_btn");
+            break;
+            
+        case ESTATE_ACCESS_MANAGER_ADD:
+            button = panel->findChild<LLButton>("add_estate_manager_btn");
+            break;
+    }
+
 	// avatar picker yes multi-select, yes close-on-select
 	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), 
-                                                    TRUE, TRUE, FALSE, parent_floater_name);
+                                                    TRUE, TRUE, FALSE, parent_floater_name, button);
 
     //Allows the closed parent floater to close the child floater (avatar picker)
     if (child_floater)
-- 
cgit v1.2.3


From ab37263a5cda14227724181c771ac1d3ef55f467 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 30 Aug 2012 21:34:48 -0700
Subject: CHUI-285 : LLIMFloaterContainer is now using LLParticipantList fully

---
 indra/llui/llfolderviewmodel.h         | 11 +++--
 indra/newview/llimfloatercontainer.cpp | 85 +++++++++++++++++++++++++++++++---
 indra/newview/llimfloatercontainer.h   |  4 +-
 indra/newview/llparticipantlist.cpp    | 13 ++++--
 4 files changed, 99 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 16d9c86fd7..22bfc4dfb4 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -209,6 +209,7 @@ protected:
 
 };
 
+
 class LLFolderViewModelItemCommon : public LLFolderViewModelItem
 {
 public:
@@ -249,6 +250,8 @@ public:
 	std::string::size_type getFilterStringOffset();
 	std::string::size_type getFilterStringSize();
 	
+	typedef std::list<LLFolderViewModelItem*> child_list_t;
+
 	virtual void addChild(LLFolderViewModelItem* child) 
 	{ 
 		mChildren.push_back(child); 
@@ -271,7 +274,11 @@ public:
 		mChildren.clear();
 		dirtyFilter();
 	}
-
+	
+	child_list_t::const_iterator getChildrenBegin() const { return mChildren.begin(); }
+	child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); }
+	child_list_t::size_type getChildrenCount() const { return mChildren.size(); }
+	
 	void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
 	{
 		mPassedFilter = passed;
@@ -325,8 +332,6 @@ protected:
 	S32						mLastFolderFilterGeneration;
 	S32						mMostFilteredDescendantGeneration;
 
-
-	typedef std::list<LLFolderViewModelItem*> child_list_t;
 	child_list_t			mChildren;
 	LLFolderViewModelItem*	mParent;
 	LLFolderViewModelInterface& mRootViewModel;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 55cbf0b266..aa85e5023d 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -442,14 +442,36 @@ void LLIMFloaterContainer::repositioningWidgets()
 	int index = 0;
 	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
 		 widget_it != mConversationsWidgets.end();
-		 widget_it++, ++index)
+		 widget_it++)
 	{
-		LLFolderViewItem* widget = widget_it->second;
+		LLFolderViewFolder* widget = dynamic_cast<LLFolderViewFolder*>(widget_it->second);
 		widget->setVisible(TRUE);
 		widget->setRect(LLRect(0,
 							   panel_rect.getHeight() - item_height*index,
 							   panel_rect.getWidth(),
 							   panel_rect.getHeight() - item_height*(index+1)));
+		index++;
+		// Reposition the children as well
+		// Merov : This is highly suspiscious but gets the debug hack to work. This needs to be revised though.
+		if (widget->getItemsCount() != 0)
+		{
+			BOOL is_open = widget->isOpen();
+			widget->setOpen(TRUE);
+			LLFolderViewFolder::items_t::const_iterator current = widget->getItemsBegin();
+			LLFolderViewFolder::items_t::const_iterator end = widget->getItemsEnd();
+			while (current != end)
+			{
+				LLFolderViewItem* item = (*current);
+				item->setVisible(TRUE);
+				item->setRect(LLRect(0,
+									   panel_rect.getHeight() - item_height*index,
+									   panel_rect.getWidth(),
+									   panel_rect.getHeight() - item_height*(index+1)));
+				index++;
+				current++;
+			}
+			widget->setOpen(is_open);
+		}
 	}
 }
 
@@ -490,19 +512,51 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	mConversationsItems[uuid] = item;
 
 	// Create a widget from it
-	LLFolderViewItem* widget = createConversationItemWidget(item);
+	LLConversationViewSession* widget = createConversationItemWidget(item);
 	mConversationsWidgets[uuid] = widget;
 
-	// Add a new conversation widget to the root folder of a folder view.
+	// Add a new conversation widget to the root folder of the folder view
 	widget->addToFolder(mConversationsRoot);
 
 	// Add it to the UI
+	mConversationsListPanel->addChild(widget);
 	widget->setVisible(TRUE);
+	
+	// Create the participants widgets now
+	// Note: usually, we do not get an updated avatar list at that point
+	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+	llinfos << "Merov debug : create participant, children size = " << item->getChildrenCount() << llendl;
+	while (current_participant_model != end_participant_model)
+	{
+		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+		participant_view->addToFolder(widget);
+		mConversationsListPanel->addChild(participant_view);
+		participant_view->setVisible(TRUE);
+		current_participant_model++;
+	}
+	// Debugging hack : uncomment to force the creation of a dummy participant 
+	// This hack is to be eventually deleted
+	if (item->getChildrenCount() == 0)
+	{
+		llinfos << "Merov debug : create dummy participant" << llendl;
+		// Create a dummy participant : we let that leak but that's just for debugging...
+		std::string name("Debug Test : ");
+		name += display_name;
+		LLUUID test_id;
+		test_id.generate(name);
+		LLConversationItemParticipant* participant_model = new LLConversationItemParticipant(name, test_id, getRootViewModel());
+		// Create the dummy widget
+		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+		participant_view->addToFolder(widget);
+		mConversationsListPanel->addChild(participant_view);
+		participant_view->setVisible(TRUE);
+	}
+	// End debugging hack
 
 	repositioningWidgets();
 	
-	mConversationsListPanel->addChild(widget);
-
 	return;
 }
 
@@ -537,7 +591,7 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	}
 }
 
-LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
+LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
 {
 	LLConversationViewSession::Params params;
 	
@@ -554,4 +608,21 @@ LLFolderViewItem* LLIMFloaterContainer::createConversationItemWidget(LLConversat
 	return LLUICtrlFactory::create<LLConversationViewSession>(params);
 }
 
+LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParticipant(LLConversationItem* item)
+{
+	LLConversationViewSession::Params params;
+	
+	params.name = item->getDisplayName();
+	//params.icon = bridge->getIcon();
+	//params.icon_open = bridge->getOpenIcon();
+	//params.creation_date = bridge->getCreationDate();
+	params.root = mConversationsRoot;
+	params.listener = item;
+	params.rect = LLRect (0, 0, 0, 0);
+	params.tool_tip = params.name;
+	params.container = this;
+	
+	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index d6dda8ea2d..300a820a26 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -37,6 +37,7 @@
 #include "llgroupmgr.h"
 #include "lltrans.h"
 #include "llconversationmodel.h"
+#include "llconversationview.h"
 
 class LLButton;
 class LLLayoutPanel;
@@ -113,7 +114,8 @@ public:
 	void addConversationListItem(const LLUUID& uuid);
 
 private:
-	LLFolderViewItem* createConversationItemWidget(LLConversationItem* item);
+	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
+	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
 
 	// Conversation list data
 	LLPanel* mConversationsListPanel;	// This is the main widget we add conversation widget to
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 35c1a34a26..fa3432fc89 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -648,10 +648,10 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 	
 	if (is_avatar)
 	{
-		// Create a participant view model instance and add it to the linked list
+		// Create a participant view model instance
 		LLAvatarName avatar_name;
 		bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
-		participant = new LLConversationItemParticipant(!has_name ? "Avatar" : avatar_name.mDisplayName , avatar_id, mRootViewModel);
+		participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.mDisplayName , avatar_id, mRootViewModel);
 		if (mAvatarList)
 		{
 			mAvatarList->getIDs().push_back(avatar_id);
@@ -661,7 +661,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 	else
 	{
 		std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
-		// Create a participant view model instance and add it to the linked list
+		// Create a participant view model instance
 		participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
 		if (mAvatarList)
 		{
@@ -672,6 +672,13 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 
 	// *TODO : Merov : need to declare and bind a name update callback on that "participant" instance. See LLAvatarListItem::updateAvatarName() for pattern.
 	// For the moment, we'll get the correct name only if it's already in the name cache (see call to LLAvatarNameCache::get() here above)
+
+	// *TODO : Merov : need to update the online/offline status of the participant.
+	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
+
+	llinfos << "Merov debug : added participant, name = " << participant->getName() << llendl;
+	
+	// Add the participant model to the session's children list
 	addParticipant(participant);
 
 	adjustParticipant(avatar_id);
-- 
cgit v1.2.3


From dab6788c42260135d298b619ff92a71838bba2b8 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 31 Aug 2012 11:57:36 +0300
Subject: CHUI-157 FIXED (Implement menu bar for conversation floater)

- Added View Nearby chat history option
- Also replaced menu item "Add Friend / Remove" with two separate menus: Add Friend and Remove Friend. So if user is a Friend the Remove Friend option would be shown there. If the user is not a friend, the Add Friend option would be shown.
---
 indra/newview/llconversationloglist.cpp            | 17 ++++++---
 indra/newview/llfloaterconversationlog.cpp         |  5 +++
 indra/newview/llfloaterconversationpreview.cpp     | 40 ++++++++++++----------
 indra/newview/llfloaterconversationpreview.h       |  2 +-
 .../default/xui/en/menu_conversation_log_gear.xml  | 28 +++++++++------
 .../default/xui/en/menu_conversation_log_view.xml  |  8 +++++
 6 files changed, 66 insertions(+), 34 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 257ec082a5..94be9055bd 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -241,15 +241,18 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
 	{
 		LLAvatarActions::offerTeleport(selected_id);
 	}
-	else if("add_rem_friend" == command_name)
+	else if("add_friend" == command_name)
 	{
-		if (LLAvatarActions::isFriend(selected_id))
+		if (!LLAvatarActions::isFriend(selected_id))
 		{
-			LLAvatarActions::removeFriendDialog(selected_id);
+			LLAvatarActions::requestFriendshipDialog(selected_id);
 		}
-		else
+	}
+	else if("remove_friend" == command_name)
+	{
+		if (LLAvatarActions::isFriend(selected_id))
 		{
-			LLAvatarActions::requestFriendshipDialog(selected_id);
+			LLAvatarActions::removeFriendDialog(selected_id);
 		}
 	}
 	else if ("invite_to_group" == command_name)
@@ -336,6 +339,10 @@ bool LLConversationLogList::isActionChecked(const LLSD& userdata)
 	{
 		return is_p2p && LLAvatarActions::isFriend(selected_id);
 	}
+	else if ("is_not_friend" == command_name)
+	{
+		return is_p2p && !LLAvatarActions::isFriend(selected_id);
+	}
 
 	return false;
 }
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index c77a9e74bb..4375ce5726 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -28,6 +28,7 @@
 #include "llconversationloglist.h"
 #include "llfiltereditor.h"
 #include "llfloaterconversationlog.h"
+#include "llfloaterreg.h"
 #include "llmenubutton.h"
 
 LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key)
@@ -97,6 +98,10 @@ void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
 	{
 		mConversationLogList->toggleSortFriendsOnTop();
 	}
+	else if ("view_nearby_chat_history" == command_name)
+	{
+		LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true);
+	}
 }
 
 bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata)
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index ae6f1441eb..7083fb987d 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -29,6 +29,7 @@
 #include "llfloaterconversationpreview.h"
 #include "llimview.h"
 #include "lllineeditor.h"
+#include "lltrans.h"
 
 LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
 :	LLFloater(session_id),
@@ -44,20 +45,28 @@ BOOL LLFloaterConversationPreview::postBuild()
 	getChild<LLUICtrl>("more_history")->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this));
 
 	const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID);
-	if (conv)
-	{
-		std::string name = conv->getConversationName();
-		LLStringUtil::format_map_t args;
-		args["[NAME]"] = name;
-		std::string title = getString("Title", args);
-		setTitle(title);
+	std::string name;
+	std::string file;
 
-		getChild<LLLineEditor>("description")->setValue(name);
+	if (mSessionID != LLUUID::null && conv)
+	{
+		name = conv->getConversationName();
+		file = conv->getHistoryFileName();
+	}
+	else
+	{
+		name = LLTrans::getString("NearbyChatTitle");
+		file = "chat";
 	}
 
-	std::string file = conv->getHistoryFileName();
-	LLLogChat::loadChatHistory(file, mMessages, true);
+	LLStringUtil::format_map_t args;
+	args["[NAME]"] = name;
+	std::string title = getString("Title", args);
+	setTitle(title);
+
+	getChild<LLLineEditor>("description")->setValue(name);
 
+	LLLogChat::loadChatHistory(file, mMessages, true);
 	mCurrentPage = mMessages.size() / mPageSize;
 
 	return LLFloater::postBuild();
@@ -68,7 +77,7 @@ void LLFloaterConversationPreview::draw()
 	LLFloater::draw();
 }
 
-void LLFloaterConversationPreview::onOpen(const LLSD& session_id)
+void LLFloaterConversationPreview::onOpen(const LLSD& key)
 {
 	showHistory();
 }
@@ -88,13 +97,8 @@ void LLFloaterConversationPreview::showHistory()
 	int delta = 0;
 	if (mCurrentPage)
 	{
-		// stinson 08/28/2012 : This operation could be simplified using integer math with the mod (%) operator.
-		//                      e.g. The following code should give the same output.
-		//                           int remainder = mMessages.size() % mPageSize;
-		//                           delta = (remainder == 0) ? 0 : (mPageSize - remainder);
-		//                      Though without examining further, the remainder might be a more appropriate value.
-		double num_of_pages = static_cast<double>(mMessages.size()) / static_cast<double>(mPageSize);
-		delta = static_cast<int>((ceil(num_of_pages) - num_of_pages) * static_cast<double>(mPageSize));
+		int remainder = mMessages.size() % mPageSize;
+		delta = (remainder == 0) ? 0 : (mPageSize - remainder);
 	}
 
 	std::advance(iter, (mCurrentPage * mPageSize) - delta);
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index 5105ef3702..2246a44761 100644
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -39,7 +39,7 @@ public:
 	virtual BOOL postBuild();
 
 	virtual void draw();
-	virtual void onOpen(const LLSD& session_id);
+	virtual void onOpen(const LLSD& key);
 
 private:
 	void onMoreHistoryBtnClick();
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
index b8d0eef956..8796b87955 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
@@ -57,20 +57,28 @@
       parameter="can_offer_teleport"/>
     </menu_item_call>
     <menu_item_separator />
-    <menu_item_check
-     label="Add friend/Remove friend"
+    <menu_item_call
+     label="Add Friend"
      layout="topleft"
-     name="Friend_add_remove">
-        <menu_item_check.on_click
+     name="add_friend">
+        <on_click
          function="Calllog.Action"
-         parameter="add_rem_friend" />
-        <menu_item_check.on_check
+         parameter="add_friend"/>
+        <on_visible
+         function="Calllog.Check"
+         parameter="is_not_friend" />
+    </menu_item_call>
+    <menu_item_call
+     label="Remove Friend"
+     layout="topleft"
+     name="remove_friend">
+        <on_click
+         function="Calllog.Action"
+         parameter="remove_friend"/>
+        <on_visible
          function="Calllog.Check"
          parameter="is_friend" />
-        <menu_item_check.on_enable
-         function="Calllog.Enable"
-         parameter="add_rem_friend" />
-    </menu_item_check>
+    </menu_item_call>
     <menu_item_call
      label="Invite to group..."
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
index 4ab8cb4f7d..ce65b23971 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
@@ -34,4 +34,12 @@
        function="CallLog.Check"
        parameter="sort_friends_on_top" />
   </menu_item_check>
+  <menu_item_separator />
+  <menu_item_call
+   label="View Nearby chat history..."
+   name="view_nearby_chat_history">
+      <on_click
+       function="CallLog.Action"
+       parameter="view_nearby_chat_history" />
+  </menu_item_call>
 </toggleable_menu>
-- 
cgit v1.2.3


From c2bb1a189c5f4c2367ee38e03371b28948e3ea81 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 31 Aug 2012 12:05:36 +0300
Subject: CHUI-154 FIXED (Add link to chat preferences from Conversation
 floater)

- Added link to chat preferences from Conversation floater
---
 indra/newview/llimfloatercontainer.cpp             | 22 ++++++++++++++++++++++
 indra/newview/llimfloatercontainer.h               |  2 ++
 .../skins/default/xui/en/menu_participant_view.xml |  7 +++++++
 3 files changed, 31 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index aa85e5023d..f85b60cb36 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -40,6 +40,7 @@
 #include "llavatarnamecache.h"
 #include "llgroupiconctrl.h"
 #include "llfloateravatarpicker.h"
+#include "llfloaterpreference.h"
 #include "llimview.h"
 #include "lltransientfloatermgr.h"
 #include "llviewercontrol.h"
@@ -53,6 +54,8 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 	mExpandCollapseBtn(NULL),
 	mConversationsRoot(NULL)
 {
+	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLIMFloaterContainer::onCustomAction,  this, _2));
+
 	// Firstly add our self to IMSession observers, so we catch session events
     LLIMMgr::getInstance()->addSessionObserver(this);
 
@@ -435,6 +438,25 @@ void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
     }
 }
 
+void LLIMFloaterContainer::onCustomAction(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+
+	if ("chat_preferences" == command)
+	{
+		LLFloaterPreference* floater_prefs = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+		if (floater_prefs)
+		{
+			LLTabContainer* tab_container = floater_prefs->getChild<LLTabContainer>("pref core");
+			LLPanel* chat_panel = tab_container->getPanelByName("chat");
+			if (tab_container && chat_panel)
+			{
+				tab_container->selectTabPanel(chat_panel);
+			}
+		}
+	}
+}
+
 void LLIMFloaterContainer::repositioningWidgets()
 {
 	LLRect panel_rect = mConversationsListPanel->getRect();
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 300a820a26..a72a3e2221 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -103,6 +103,8 @@ private:
 	void onAddButtonClicked();
 	void onAvatarPicked(const uuid_vec_t& ids);
 
+	void onCustomAction (const LLSD& userdata);
+
 	LLButton* mExpandCollapseBtn;
 	LLLayoutPanel* mMessagesPane;
 	LLLayoutPanel* mConversationsPane;
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index 6401b0e3b7..df2700c94c 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -2,6 +2,13 @@
 <toggleable_menu
  layout="topleft"
  name="participant_manu_view">
+    <menu_item_call
+         label="Chat preferences..."
+         name="chat_preferences">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="chat_preferences" />
+      </menu_item_call>
     <menu_item_check
          label="Open conversation log"
          name="Conversation"
-- 
cgit v1.2.3


From ae2e611dfb7b712c159ebafabb83ebbc1f7465b6 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 31 Aug 2012 16:52:50 +0300
Subject: CHUI-315 (Nearby chat messages do not appear in conversation
 floater): cancelled inheritance LLNearbyChat from LLSingleton; set
 mSingleInstance flag for it.

---
 indra/llui/llfloater.cpp                       |  7 ++++++
 indra/llui/llfloater.h                         |  1 +
 indra/newview/llagent.cpp                      |  6 +++--
 indra/newview/llchatitemscontainerctrl.cpp     |  4 ++--
 indra/newview/llfloatertranslationsettings.cpp |  3 ++-
 indra/newview/llgesturemgr.cpp                 |  4 +++-
 indra/newview/llimconversation.cpp             | 31 +++++++++++++-------------
 indra/newview/llimview.cpp                     |  6 +++--
 indra/newview/llnearbychat.cpp                 | 21 +++++++++--------
 indra/newview/llnearbychat.h                   |  4 +---
 indra/newview/llnearbychathandler.cpp          |  5 +++--
 indra/newview/llnotificationhandlerutil.cpp    |  5 +++--
 indra/newview/llnotificationtiphandler.cpp     |  3 ++-
 indra/newview/llviewergesture.cpp              |  4 +++-
 indra/newview/llviewerkeyboard.cpp             |  3 ++-
 indra/newview/llviewermessage.cpp              |  8 ++++---
 indra/newview/llviewerwindow.cpp               | 10 +++++----
 17 files changed, 76 insertions(+), 49 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 52812dc050..029c47c726 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -627,6 +627,13 @@ void LLFloater::setVisible( BOOL visible )
 	storeVisibilityControl();
 }
 
+
+void LLFloater::setIsSingleInstance(BOOL is_single_instance)
+{
+	mSingleInstance = is_single_instance;
+}
+
+
 // virtual
 void LLFloater::handleVisibilityChange ( BOOL new_visibility )
 {
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index a1cac64a4a..4b738f88ea 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -217,6 +217,7 @@ public:
 	/*virtual*/ void setFocus( BOOL b );
 	/*virtual*/ void setIsChrome(BOOL is_chrome);
 	/*virtual*/ void setRect(const LLRect &rect);
+                void setIsSingleInstance(BOOL is_single_instance);
 
 	void 			initFloater(const Params& p);
 
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index be6901c36a..bb0dbc7ff0 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1911,7 +1911,8 @@ void LLAgent::startTyping()
 	{
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
 	}
-	(LLNearbyChat::instance()).sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+	(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+			sendChatFromViewer("", CHAT_TYPE_START, FALSE);
 }
 
 //-----------------------------------------------------------------------------
@@ -1923,7 +1924,8 @@ void LLAgent::stopTyping()
 	{
 		clearRenderState(AGENT_STATE_TYPING);
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
-		(LLNearbyChat::instance()).sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+		(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+				sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
 	}
 }
 
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index e6340e0fa3..f1b5c42ef3 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -323,12 +323,12 @@ BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
 			return TRUE;
 		else
 		{
-			LLNearbyChat::instance().showHistory();
+			(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->showHistory();
 			return FALSE;
 		}
 	}
 
-	LLNearbyChat::instance().showHistory();
+	(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->showHistory();
 	return LLPanel::handleMouseUp(x,y,mask);
 }
 
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index b5b86dadc2..29d7732a68 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -293,6 +293,7 @@ void LLFloaterTranslationSettings::onBtnOK()
 	gSavedSettings.setString("TranslationService", getSelectedService());
 	gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
 	gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
-	LLNearbyChat::instance().showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+	(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+			showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 	closeFloater(false);
 }
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 0377337af6..0996af6125 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -35,6 +35,7 @@
 // library
 #include "llaudioengine.h"
 #include "lldatapacker.h"
+#include "llfloaterreg.h"
 #include "llinventory.h"
 #include "llkeyframemotion.h"
 #include "llmultigesture.h"
@@ -997,7 +998,8 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
 
 			const BOOL animate = FALSE;
 
-			LLNearbyChat::instance().sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+			(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+					sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
 
 			gesture->mCurrentStep++;
 			break;
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 7bb29be27b..5a5196fb7e 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -144,7 +144,7 @@ BOOL LLIMConversation::postBuild()
 
 	updateHeaderAndToolbar();
 
-	mSaveRect = isTornOff();
+	mSaveRect = !getHost();
 	initRectControl();
 
 	if (isChatMultiTab())
@@ -267,11 +267,11 @@ void LLIMConversation::hideOrShowTitle()
 	LLView* floater_contents = getChild<LLView>("contents_view");
 
 	LLRect floater_rect = getLocalRect();
-	S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0);
+	S32 top_border_of_contents = floater_rect.mTop - (getHost()? 0 : floater_header_size);
 	LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents);
 	LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom);
 	mDragHandle->setShape(handle_rect);
-	mDragHandle->setVisible(isTornOff());
+	mDragHandle->setVisible(!getHost());
 	floater_contents->setShape(contents_rect);
 }
 
@@ -289,8 +289,8 @@ void LLIMConversation::hideAllStandardButtons()
 
 void LLIMConversation::updateHeaderAndToolbar()
 {
-	bool is_torn_off = !getHost();
-	if (!is_torn_off)
+	bool is_hosted = !!getHost();
+	if (is_hosted)
 	{
 		hideAllStandardButtons();
 	}
@@ -299,7 +299,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 	// Participant list should be visible only in torn off floaters.
 	bool is_participant_list_visible =
-			is_torn_off
+			!is_hosted
 			&& gSavedSettings.getBOOL("IMShowControlPanel")
 			&& !mIsP2PChat;
 
@@ -307,21 +307,21 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
-	bool is_expanded = !is_torn_off || is_participant_list_visible;
+	bool is_expanded = is_hosted || is_participant_list_visible;
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
 
 	// toggle floater's drag handle and title visibility
 	if (mDragHandle)
 	{
-		mDragHandle->setTitleVisible(is_torn_off);
+		mDragHandle->setTitleVisible(!is_hosted);
 	}
 
 	// The button (>>) should be disabled for torn off P2P conversations.
-	mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat);
+	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat);
 
-	mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon"));
+	mTearOffBtn->setImageOverlay(getString(is_hosted? "tear_off_icon" : "return_icon"));
 
-	mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat);
+	mCloseBtn->setVisible(is_hosted && !mIsNearbyChat);
 
 	enableDisableCallBtn();
 
@@ -358,9 +358,10 @@ void LLIMConversation::processChatHistoryStyleUpdate()
 		}
 	}
 
-	if (LLNearbyChat::instanceExists())
+	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	if (nearby_chat)
 	{
-		LLNearbyChat::instance().reloadMessages();
+             nearby_chat->reloadMessages();
 	}
 }
 
@@ -427,8 +428,8 @@ void LLIMConversation::onClose(bool app_quitting)
 
 void LLIMConversation::onTearOffClicked()
 {
-    setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
-    mSaveRect = isTornOff();
+    setFollows(getHost()? FOLLOWS_NONE : FOLLOWS_ALL);
+    mSaveRect = !getHost();
     initRectControl();
 	LLFloater::onClickTearOff(this);
 	updateHeaderAndToolbar();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index effcc9a826..f5392b442a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2486,9 +2486,11 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 
 		LLChat chat(message);
 		chat.mSourceType = CHAT_SOURCE_SYSTEM;
-		if (LLNearbyChat::instanceExists())
+
+		LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
+		if (nearby_chat)
 		{
-			LLNearbyChat::instance().addMessage(chat);
+			nearby_chat->addMessage(chat);
 		}
 	}
 	else // going to IM session
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index f1518fe825..25bbc82fee 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -134,6 +134,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& llsd)
 	mKey = LLSD();
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
 	setName("nearby_chat");
+	setIsSingleInstance(TRUE);
 }
 
 //virtual
@@ -780,20 +781,21 @@ void LLNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BO
 // static 
 void LLNearbyChat::startChat(const char* line)
 {
-	if (LLNearbyChat::instanceExists())
+	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	if (nearby_chat)
 	{
-		(LLNearbyChat::instance()).show();
-		(LLNearbyChat::instance()).setVisible(TRUE);
-		(LLNearbyChat::instance()).setFocus(TRUE);
-		(LLNearbyChat::instance().mInputEditor)->setFocus(TRUE);
+		nearby_chat->show();
+		nearby_chat->setVisible(TRUE);
+		nearby_chat->setFocus(TRUE);
+		nearby_chat->mInputEditor->setFocus(TRUE);
 
 		if (line)
 		{
 			std::string line_string(line);
-			(LLNearbyChat::instance().mInputEditor)->setText(line_string);
+			nearby_chat->mInputEditor->setText(line_string);
 		}
 
-		(LLNearbyChat::instance().mInputEditor)->endOfDoc();
+		nearby_chat->mInputEditor->endOfDoc();
 	}
 }
 
@@ -801,9 +803,10 @@ void LLNearbyChat::startChat(const char* line)
 // static
 void LLNearbyChat::stopChat()
 {
-	if (LLNearbyChat::instanceExists())
+	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	if (nearby_chat)
 	{
-		(LLNearbyChat::instance().mInputEditor)->setFocus(FALSE);
+		nearby_chat->mInputEditor->setFocus(FALSE);
 	    gAgent.stopTyping();
 	}
 }
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 379bfbee4b..4fc5cb7f76 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -35,15 +35,13 @@
 #include "lloutputmonitorctrl.h"
 #include "llspeakers.h"
 #include "llscrollbar.h"
-#include "llsingleton.h"
 #include "llviewerchat.h"
 #include "llpanel.h"
 
 class LLResizeBar;
 
 class LLNearbyChat
-	:	public LLIMConversation,
-	 	public LLSingleton<LLNearbyChat>
+	:	public LLIMConversation
 {
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 37f4cc4c19..ca3fffeffd 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -537,7 +537,8 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 		}
 	}
 
-	LLNearbyChat::instance().addMessage(chat_msg, true, args);
+	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	nearby_chat->addMessage(chat_msg, true, args);
 
 	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT 
 		&& chat_msg.mFromID.notNull() 
@@ -553,7 +554,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	// Send event on to LLEventStream
 	sChatWatcher->post(chat);
 
-	if( LLNearbyChat::instance().isInVisibleChain()
+	if( nearby_chat->isInVisibleChain()
 		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") )
 		|| mChannel.isDead()
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index db8e917435..2484040ac4 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -181,13 +181,14 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
 // static
 void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
 {
-	if (LLNearbyChat::instanceExists())
+    LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	if (nearby_chat)
 	{
 		LLChat chat_msg(notification->getMessage());
 		chat_msg.mSourceType = type;
 		chat_msg.mFromName = SYSTEM_FROM;
 		chat_msg.mFromID = LLUUID::null;
-		LLNearbyChat::instance().addMessage(chat_msg);
+		nearby_chat->addMessage(chat_msg);
 	}
 }
 
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 67fc9b27dc..ef6668247c 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -85,7 +85,8 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 		LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
 
 		// don't show toast if Nearby Chat is opened
-		if (LLNearbyChat::instance().isChatVisible())
+		LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+		if (nearby_chat && nearby_chat->isChatVisible())
 		{
 			return false;
 		}
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index a2dea31d9b..71608b5280 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -33,6 +33,7 @@
 #include "llviewerinventory.h"
 #include "sound_ids.h"		// for testing
 
+#include "llfloaterreg.h"
 #include "llkeyboard.h"		// for key shortcuts for testing
 #include "llinventorymodel.h"
 #include "llvoavatar.h"
@@ -130,7 +131,8 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
 	{
 		// Don't play nodding animation, since that might not blend
 		// with the gesture animation.
-		LLNearbyChat::instance().sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+		(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+				sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
 	}
 }
 
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 7105720eb4..f8e988bc0c 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llappviewer.h"
+#include "llfloaterreg.h"
 #include "llviewerkeyboard.h"
 #include "llmath.h"
 #include "llagent.h"
@@ -543,7 +544,7 @@ void start_gesture( EKeystate s )
 	if (KEYSTATE_UP == s &&
 		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
 	{
- 		if (LLNearbyChat::instance().getCurrentChat().empty())
+ 		if ((LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->getCurrentChat().empty())
  		{
  			// No existing chat in chat editor, insert '/'
  			LLNearbyChat::startChat("/");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 9abd269f0f..81cbc3b6c3 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2297,9 +2297,10 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m
 	// Treat like a system message and put in chat history.
 	chat.mText = av_name.getCompleteName() + ": " + message;
 
-	if (LLNearbyChat::instanceExists())
+	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	if (nearby_chat)
 	{
-		LLNearbyChat::instance().addMessage(chat);
+		nearby_chat->addMessage(chat);
 	}
 }
 
@@ -2895,7 +2896,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
 			// IMs from obejcts don't open IM sessions.
-			if(!chat_from_system && LLNearbyChat::instanceExists())
+			LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+			if(!chat_from_system && nearby_chat)
 			{
 				chat.mOwnerID = from_id;
 				LLSD args;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 23d2b1633d..791cadaee4 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2493,12 +2493,14 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		return TRUE;
 	}
 
+	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+
 	// Traverses up the hierarchy
 	if( keyboard_focus )
 	{
-		if (LLNearbyChat::instanceExists())
+		if (nearby_chat)
 		{
-			LLChatEntry* chat_editor = LLNearbyChat::instance().getChatBox();
+			LLChatEntry* chat_editor = nearby_chat->getChatBox();
 
 			// arrow keys move avatar while chatting hack
 			if (chat_editor && chat_editor->hasFocus())
@@ -2562,11 +2564,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
-		LLChatEntry* chat_editor = LLNearbyChat::instance().getChatBox();
+		LLChatEntry* chat_editor = nearby_chat->getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
-			LLNearbyChat::instance().startChat(NULL);
+			nearby_chat->startChat(NULL);
 			return TRUE;
 		}
 	}
-- 
cgit v1.2.3


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


From eb13b2b4680ab80e8a20d341a481b8c1d62ca156 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Mon, 3 Sep 2012 17:42:20 +0300
Subject: CHUI-307 FIXED (LLInitParam::Parser::parserWarnings in log when
 adding conversations or deleting entries from conversation log )

- removed redundant incorrect attributes
---
 indra/newview/skins/default/xui/en/panel_blocked_list_item.xml         | 1 -
 .../newview/skins/default/xui/en/panel_conversation_log_list_item.xml  | 3 ---
 2 files changed, 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
index 84e7e467b1..752321b949 100644
--- a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
@@ -60,7 +60,6 @@
     <text
      follows="left|right"
      font="SansSerifSmall"
-     font.color="DkGray"
      height="15"
      layout="topleft"
      left_pad="5"
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
index cee7d8581a..8a58eb1ca6 100644
--- a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
@@ -28,7 +28,6 @@
      visible="false"
      width="380" />
     <icon
-     default_icon_name="voice_session_icon"
      follows="top|left"
      height="20"
      layout="topleft"
@@ -72,7 +71,6 @@
     <text
      follows="left|right"
      font="SansSerifSmall"
-     font.color="DkGray"
      height="15"
      layout="topleft"
      left_pad="5"
@@ -84,7 +82,6 @@
     <text
      follows="right"
      font="SansSerifSmall"
-     font.color="DkGray"
      height="15"
      layout="topleft"
      left_pad="5"
-- 
cgit v1.2.3


From 7bad109c3d7e6d70649839634586a09033cfb207 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Mon, 3 Sep 2012 17:52:54 +0300
Subject: CHUI-314 FIXED (Update Save IM logs on my computer setting to also
 control populatoin of conversation log)

- Now LLConversationLog is optionally listener of IMSession, dependently on "LogInstantMessages" per account setting, saving of call log to file also depends on this setting.
Which means that with the Save IM logs on my computer disabled: IM logs for the user will not be saved to their computer and conversations will not be logged to the conversation log.
---
 indra/newview/llappviewer.cpp       |  5 ++++-
 indra/newview/llconversationlog.cpp | 27 +++++++++++++++++++++++++--
 indra/newview/llconversationlog.h   |  2 ++
 3 files changed, 31 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 08a1a237f5..4dacde4792 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1834,7 +1834,10 @@ bool LLAppViewer::cleanup()
 	LLMuteList::getInstance()->cache(gAgent.getID());
 
 	//save call log list
-	LLConversationLog::instance().cache();
+	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	{
+		LLConversationLog::instance().cache();
+	}
 
 	if (mPurgeOnExit)
 	{
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 23ccc78a0f..7db6a93709 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -185,11 +185,34 @@ LLConversationLog::LLConversationLog()
 {
 	loadFromFile(getFileName());
 
-	LLIMMgr::instance().addSessionObserver(this);
-	
+	LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
+	if (ctrl)
+	{
+		ctrl->getSignal()->connect(boost::bind(&LLConversationLog::observeIMSession, this));
+
+		if (ctrl->getValue().asBoolean())
+		{
+			LLIMMgr::instance().addSessionObserver(this);
+		}
+	}
+
 	mFriendObserver = new LLConversationLogFriendObserver;
 	LLAvatarTracker::instance().addObserver(mFriendObserver);
+
 }
+
+void LLConversationLog::observeIMSession()
+{
+	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	{
+		LLIMMgr::instance().addSessionObserver(this);
+	}
+	else
+	{
+		LLIMMgr::instance().removeSessionObserver(this);
+	}
+}
+
 void LLConversationLog::logConversation(const LLConversation& conversation)
 {
 	mConversations.push_back(conversation);
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index f2b6a67c92..9fd54c61c9 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -145,6 +145,8 @@ private:
 
 	LLConversationLog();
 
+	void observeIMSession();
+
 	/**
 	 * constructs file name in which conversations log will be saved
 	 * file name is conversation.log
-- 
cgit v1.2.3


From 681406427fab95167cb87b54e8315600176bf218 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 4 Sep 2012 20:39:49 +0300
Subject: CHUI-311 FIXED (Make conversation list panel size persist between
 sessions): save current width in the setting_per_account.xml

---
 indra/newview/llimfloatercontainer.cpp | 23 ++++++++++++++++++++++-
 indra/newview/llimfloatercontainer.h   |  2 ++
 2 files changed, 24 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 56648d09b5..480f964939 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -52,7 +52,8 @@
 LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 :	LLMultiFloater(seed),
 	mExpandCollapseBtn(NULL),
-	mConversationsRoot(NULL)
+	mConversationsRoot(NULL),
+	mInitialized(false)
 {
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLIMFloaterContainer::onCustomAction,  this, _2));
 
@@ -139,6 +140,16 @@ BOOL LLIMFloaterContainer::postBuild()
 	LLAvatarNameCache::addUseDisplayNamesCallback(
 			boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
+	if (! mMessagesPane->isCollapsed())
+	{
+		S32 list_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
+		LLRect list_size = mConversationsPane->getRect();
+        S32 left_pad = mConversationsListPanel->getRect().mLeft;
+		list_size.mRight = list_size.mLeft + list_width - left_pad;
+
+        mConversationsPane->handleReshape(list_size, TRUE);
+	}
+	mInitialized = true;
 	return TRUE;
 }
 
@@ -514,6 +525,16 @@ void LLIMFloaterContainer::onCustomAction(const LLSD& userdata)
 
 void LLIMFloaterContainer::repositioningWidgets()
 {
+	if (!mInitialized)
+	{
+		return;
+	}
+
+	if (!mConversationsPane->isCollapsed())
+	{
+		S32 list_width = (mConversationsPane->getRect()).getWidth();
+		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", list_width);
+	}
 	LLRect panel_rect = mConversationsListPanel->getRect();
 	S32 item_height = 16;
 	int index = 0;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index a72a3e2221..53e3849600 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -110,6 +110,8 @@ private:
 	LLLayoutPanel* mConversationsPane;
 	LLLayoutStack* mConversationsStack;
 	
+	bool mInitialized;
+
 	// Conversation list implementation
 public:
 	void removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
-- 
cgit v1.2.3


From 5fbb161ba0a28e64474efc295b12bccffdcdb0e0 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 4 Sep 2012 13:34:33 -0700
Subject: CHUI-305: Now searching in the resident picker works. Problem: The
 resident picker search results were being sent to the old global resident
 picker. Now resident pickers are non-global and coupled to their parent
 floater.

---
 indra/newview/llfloateravatarpicker.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 2152de1035..6ada809cdb 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -460,8 +460,9 @@ class LLAvatarPickerResponder : public LLHTTPClient::Responder
 {
 public:
 	LLUUID mQueryID;
+    std::string mName;
 
-	LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { }
+	LLAvatarPickerResponder(const LLUUID& id, const std::string& name) : mQueryID(id), mName(name) { }
 
 	/*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content)
 	{
@@ -474,7 +475,7 @@ public:
 		if (isGoodStatus(status) || status == 400)
 		{
 			LLFloaterAvatarPicker* floater =
-				LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
+				LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", mName);
 			if (floater)
 			{
 				floater->processResponse(mQueryID, content);
@@ -517,7 +518,7 @@ void LLFloaterAvatarPicker::find()
 		url += "?page_size=100&names=";
 		url += LLURI::escape(text);
 		llinfos << "avatar picker " << url << llendl;
-		LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID));
+		LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID, getKey().asString()));
 	}
 	else
 	{
-- 
cgit v1.2.3


From d41202336b7c797bc3fe4feffa8be2164518e845 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 4 Sep 2012 14:21:25 -0700
Subject: CHUI-303: Problem was that the prior solution only updated (using
 dirtyFilter()) the inventory window that the paste occurred in. Resolution:
 Now each inventory window calls dirtyFilter(), which then determines
 visibility of the pasted item.

---
 indra/newview/llinventorybridge.cpp | 12 ++----------
 indra/newview/llinventorymodel.cpp  |  1 +
 2 files changed, 3 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 745375fe3d..72c54e5ce2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3193,16 +3193,8 @@ void LLFolderBridge::pasteFromClipboard()
 						LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id);
 						llassert(vicat);
 						if (vicat)
-						{
-                            //Set the pasted folder to dirty, could do this in changeCategoryParent() but only need to set dirty
-                            //when pasting from the clipboard. Setting dirty allows updating the filter state, which determines
-                            //visibility in the new pasted location.
-                            LLFolderViewFolder * folderViewItem = mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(item_id) : NULL;
-                            if(folderViewItem && folderViewItem->getViewModelItem())
-                            {
-                                folderViewItem->getViewModelItem()->dirtyFilter();
-                            }
-                         
+						{       
+                            //changeCategoryParent() implicity calls dirtyFilter
 							changeCategoryParent(model, vicat, parent_id, FALSE);
 						}
 					}
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 0673970d89..e7d59d92d9 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -986,6 +986,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)
 				cat_array->put(old_cat);
 			}
 			mask |= LLInventoryObserver::STRUCTURE;
+            mask |= LLInventoryObserver::INTERNAL;
 		}
 		if(old_cat->getName() != cat->getName())
 		{
-- 
cgit v1.2.3


From 8cd5d361600f34a0a7fa504a721bea3301191644 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 4 Sep 2012 22:11:28 -0700
Subject: CHUI-285 : Create participant widgets in the conversation list

---
 indra/newview/llconversationmodel.cpp  | 12 ++++--
 indra/newview/llconversationmodel.h    | 14 ++++---
 indra/newview/llconversationview.cpp   | 38 ++++++++++++++++-
 indra/newview/llconversationview.h     | 20 ++++++++-
 indra/newview/llimfloatercontainer.cpp | 75 +++++++++++++++++++++++++---------
 5 files changed, 128 insertions(+), 31 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index d7f9093a4a..aa21b08ec8 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -36,21 +36,24 @@
 LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(display_name),
-	mUUID(uuid)
+	mUUID(uuid),
+	mNeedsRefresh(true)
 {
 }
 
 LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
-	mUUID(uuid)
+	mUUID(uuid),
+	mNeedsRefresh(true)
 {
 }
 
 LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
-	mUUID()
+	mUUID(),
+	mNeedsRefresh(true)
 {
 }
 
@@ -102,11 +105,13 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
 {
 	addChild(participant);
 	mIsLoaded = true;
+	mNeedsRefresh = true;
 }
 
 void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
 {
 	removeChild(participant);
+	mNeedsRefresh = true;
 }
 
 void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
@@ -122,6 +127,7 @@ void LLConversationItemSession::clearParticipants()
 {
 	clearChildren();
 	mIsLoaded = false;
+	mNeedsRefresh = true;
 }
 
 LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 1a2e09dfab..5947055e0f 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -60,7 +60,7 @@ public:
 	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
 	virtual BOOL isItemRenameable() const { return TRUE; }
-	virtual BOOL renameItem(const std::string& new_name) { mName = new_name; return TRUE; }
+	virtual BOOL renameItem(const std::string& new_name) { mName = new_name; mNeedsRefresh = true; return TRUE; }
 	virtual BOOL isItemMovable( void ) const { return FALSE; }
 	virtual BOOL isItemRemovable( void ) const { return FALSE; }
 	virtual BOOL isItemInTrash( void) const { return FALSE; }
@@ -102,10 +102,14 @@ public:
 	
 //	bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
 	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
-
+	
+	void resetRefresh() { mNeedsRefresh = false; }
+	bool needsRefresh() { return mNeedsRefresh; }
+	
 protected:
 	std::string mName;	// Name of the session or the participant
 	LLUUID mUUID;		// UUID of the session or the participant
+	bool mNeedsRefresh;	// Flag signaling to the view that something changed for this item
 };
 
 class LLConversationItemSession : public LLConversationItem
@@ -115,7 +119,7 @@ public:
 	LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItemSession() {}
 	
-	void setSessionID(const LLUUID& session_id) { mUUID = session_id; }
+	void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; }
 	void addParticipant(LLConversationItemParticipant* participant);
 	void removeParticipant(LLConversationItemParticipant* participant);
 	void removeParticipant(const LLUUID& participant_id);
@@ -142,8 +146,8 @@ public:
 	
 	bool isMuted() { return mIsMuted; }
 	bool isModerator() {return mIsModerator; }
-	void setIsMuted(bool is_muted) { mIsMuted = is_muted; }
-	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; }
+	void setIsMuted(bool is_muted) { mIsMuted = is_muted; mNeedsRefresh = true; }
+	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
 	
 	void dumpDebugData();
 
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index fefb7e9cac..2f71e92a7d 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -79,12 +79,46 @@ void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
 	}
 }
 
+LLConversationViewParticipant* LLConversationViewSession::findParticipant(const LLUUID& participant_id)
+{
+	// This is *not* a general tree parsing algorithm. We search only in the mItems list
+	// assuming there is no mFolders which makes sense for sessions (sessions don't contain
+	// sessions).
+	LLConversationViewParticipant* participant = NULL;
+	items_t::const_iterator iter;
+	for (iter = getItemsBegin(); iter != getItemsEnd(); iter++)
+	{
+		participant = dynamic_cast<LLConversationViewParticipant*>(*iter);
+		if (participant->hasSameValue(participant_id))
+		{
+			break;
+		}
+	}
+	return (iter == getItemsEnd() ? NULL : participant);
+}
+
+void LLConversationViewSession::refresh()
+{
+	// Refresh the session view from its model data
+	// LLConversationItemSession* vmi = dynamic_cast<LLConversationItemSession*>(getViewModelItem());
+	
+	// Note: for the moment, all that needs to be done is done by LLFolderViewItem::refresh()
+	
+	// Do the regular upstream refresh
+	LLFolderViewFolder::refresh();
+}
+
 //
 // Implementation of conversations list participant (avatar) widgets
 //
 
-LLConversationViewParticipant::LLConversationViewParticipant( const LLFolderViewItem::Params& p ):
-	LLFolderViewItem(p)
+LLConversationViewParticipant::Params::Params() :	
+	participant_id()
+{}
+
+LLConversationViewParticipant::LLConversationViewParticipant( const LLConversationViewParticipant::Params& p ):
+	LLFolderViewItem(p),
+	mUUID(p.participant_id)
 {
 }
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 5695925f43..27ceb2af3b 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -30,6 +30,8 @@
 #include "llfolderviewitem.h"
 
 class LLIMFloaterContainer;
+class LLConversationViewSession;
+class LLConversationViewParticipant;
 
 // Implementation of conversations list session widgets
 
@@ -53,18 +55,34 @@ public:
 	virtual ~LLConversationViewSession( void ) { }
 	virtual void selectItem();	
 	void setVisibleIfDetached(BOOL visible);
+	LLConversationViewParticipant* findParticipant(const LLUUID& participant_id);
+
+	virtual void refresh();
 };
 
 // Implementation of conversations list participant (avatar) widgets
 
 class LLConversationViewParticipant : public LLFolderViewItem
 {
+public:
+	struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
+	{
+		Optional<LLUUID>	participant_id;
+		
+		Params();
+	};
+	
 protected:
 	friend class LLUICtrlFactory;
-	LLConversationViewParticipant( const LLFolderViewItem::Params& p );
+	LLConversationViewParticipant( const Params& p );
 	
 public:
 	virtual ~LLConversationViewParticipant( void ) { }
+
+	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
+
+private:
+	LLUUID mUUID;		// UUID of the participant
 };
 
 #endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index aa85e5023d..dfe9e6491d 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -289,6 +289,59 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 
 void LLIMFloaterContainer::draw()
 {
+	// CHUI Notes
+	// Currently, the model is not responsible for creating the view which is a good thing. This means that
+	// the model could change substantially and the view could decide to echo only a portion of this model.
+	// Consequently, the participant views need to be created either by the session view or by the container panel.
+	// For the moment, we create them here (which makes for complicated code...) to conform to the pattern
+	// implemented in llinventorypanel.cpp (see LLInventoryPanel::buildNewViews()).
+	// The best however would be to have an observer on the model so that we would not pool on each draw to know
+	// if the view needs refresh. The current implementation (testing for change on draw) is less
+	// efficient perf wise than a listener/observer scheme. We will implement that shortly.
+	
+	// On each session in mConversationsItems
+	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	{
+		// Get the current session descriptors
+		LLConversationItem* session_model = it_session->second;
+		LLUUID session_id = it_session->first;
+		LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
+		// If the session model has been changed, refresh the corresponding view
+		if (session_model->needsRefresh())
+		{
+			session_view->refresh();
+		}
+		// Iterate through each model participant child
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+			LLUUID participant_id = participant_model->getUUID();
+			LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+			// Is there a corresponding view? If not create it
+			if (!participant_view)
+			{
+				participant_view = createConversationViewParticipant(participant_model);
+				participant_view->addToFolder(session_view);
+				mConversationsListPanel->addChild(participant_view);
+				participant_view->setVisible(TRUE);
+			}
+			else
+			// Else, see if it needs refresh
+			{
+				if (participant_model->needsRefresh())
+				{
+					participant_view->refresh();
+				}
+			}
+			// Reset the need for refresh
+			session_model->resetRefresh();
+			// Next participant
+			current_participant_model++;
+		}
+	}
+	
 	if (mTabContainer->getTabCount() == 0)
 	{
 		// Do not close the container when every conversation is torn off because the user
@@ -536,24 +589,6 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 		participant_view->setVisible(TRUE);
 		current_participant_model++;
 	}
-	// Debugging hack : uncomment to force the creation of a dummy participant 
-	// This hack is to be eventually deleted
-	if (item->getChildrenCount() == 0)
-	{
-		llinfos << "Merov debug : create dummy participant" << llendl;
-		// Create a dummy participant : we let that leak but that's just for debugging...
-		std::string name("Debug Test : ");
-		name += display_name;
-		LLUUID test_id;
-		test_id.generate(name);
-		LLConversationItemParticipant* participant_model = new LLConversationItemParticipant(name, test_id, getRootViewModel());
-		// Create the dummy widget
-		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
-		participant_view->addToFolder(widget);
-		mConversationsListPanel->addChild(participant_view);
-		participant_view->setVisible(TRUE);
-	}
-	// End debugging hack
 
 	repositioningWidgets();
 	
@@ -610,7 +645,7 @@ LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LL
 
 LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParticipant(LLConversationItem* item)
 {
-	LLConversationViewSession::Params params;
+	LLConversationViewParticipant::Params params;
 	
 	params.name = item->getDisplayName();
 	//params.icon = bridge->getIcon();
@@ -620,7 +655,7 @@ LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParti
 	params.listener = item;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
-	params.container = this;
+	params.participant_id = item->getUUID();
 	
 	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
 }
-- 
cgit v1.2.3


From 3cf624b371eace5ec382796d7bd811d181d5e877 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 5 Sep 2012 18:48:07 +0300
Subject: CHUI-268 (Transfer the common functionality from LLNearbyChat and
 LLIMFloater to LLIMConversation):  moved  focusLost(), focusReceived and
 enable/disable of the call button to base class

---
 indra/newview/llimconversation.cpp | 42 ++++++++++++++++++++++++++++++++++++++
 indra/newview/llimconversation.h   | 14 +++++++++----
 indra/newview/llimfloater.cpp      | 39 -----------------------------------
 indra/newview/llimfloater.h        |  9 --------
 indra/newview/llnearbychat.cpp     | 23 +--------------------
 indra/newview/llnearbychat.h       |  7 -------
 6 files changed, 53 insertions(+), 81 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 5a5196fb7e..d8c81a7849 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -31,6 +31,8 @@
 
 #include "llchatentry.h"
 #include "llchathistory.h"
+#include "llchiclet.h"
+#include "llchicletbar.h"
 #include "lldraghandle.h"
 #include "llfloaterreg.h"
 #include "llimfloater.h"
@@ -53,6 +55,8 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)
   , mInputEditorTopPad(0)
   , mRefreshTimer(new LLTimer())
 {
+	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
 	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
 			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
@@ -182,6 +186,44 @@ void LLIMConversation::draw()
 	}
 }
 
+void LLIMConversation::enableDisableCallBtn()
+{
+    getChildView("voice_call_btn")->setEnabled(
+    		mSessionID.notNull()
+    		&& mSession
+    		&& mSession->mSessionInitialized
+    		&& LLVoiceClient::getInstance()->voiceEnabled()
+    		&& LLVoiceClient::getInstance()->isVoiceWorking()
+    		&& mSession->mCallBackEnabled);
+}
+
+
+void LLIMConversation::onFocusReceived()
+{
+	setBackgroundOpaque(true);
+
+	if (mSessionID.notNull())
+	{
+		LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, true);
+
+		if (getVisible())
+		{
+			// suppress corresponding toast only if this floater is visible and have focus
+			LLIMModel::getInstance()->setActiveSessionID(mSessionID);
+			LLIMModel::instance().sendNoUnreadMessages(mSessionID);
+		}
+	}
+
+	LLTransientDockableFloater::onFocusReceived();
+}
+
+void LLIMConversation::onFocusLost()
+{
+	setBackgroundOpaque(false);
+	LLTransientDockableFloater::onFocusLost();
+}
+
+
 void LLIMConversation::buildParticipantList()
 {
 	if (mIsNearbyChat)
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 26151ad1be..50feb12aed 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -33,6 +33,7 @@
 #include "lltransientdockablefloater.h"
 #include "llviewercontrol.h"
 #include "lleventtimer.h"
+#include "llimview.h"
 #include "llconversationmodel.h"
 
 class LLPanelChatControlPanel;
@@ -87,9 +88,6 @@ protected:
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
 
-	// set the enable/disable state for the Call button
-	virtual void enableDisableCallBtn() = 0;
-
 	void buildParticipantList();
 	void onSortMenuItemClicked(const LLSD& userdata);
 
@@ -99,9 +97,18 @@ protected:
 	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
 	void updateHeaderAndToolbar();
 
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn();
+
+	// process focus events to set a currently active session
+	/* virtual */ void onFocusLost();
+	/* virtual */ void onFocusReceived();
+
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
 
+	LLIMModel::LLIMSession* mSession;
+
 	LLLayoutPanel* mParticipantListPanel;
 	LLParticipantList* mParticipantList;
 	LLUUID mSessionID;
@@ -119,7 +126,6 @@ private:
 	/// Refreshes the floater at a constant rate.
 	virtual void refresh() = 0;
 
-
 	/**
 	 * Adjusts chat history height to fit vertically with input chat field
 	 * and avoid overlapping, since input chat field can be vertically expanded.
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index a601561c62..7b475c1e0b 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -92,24 +92,6 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	setDocked(true);
 }
 
-void LLIMFloater::onFocusLost()
-{
-	LLIMModel::getInstance()->resetActiveSessionID();
-	
-	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, false);
-}
-
-void LLIMFloater::onFocusReceived()
-{
-	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, true);
-
-	if (getVisible())
-	{
-		// suppress corresponding toast only if this floater is visible and have focus
-		LLIMModel::getInstance()->setActiveSessionID(mSessionID);
-		LLIMModel::instance().sendNoUnreadMessages(mSessionID);
-	}
-}
 
 // virtual
 void LLIMFloater::refresh()
@@ -513,27 +495,6 @@ void LLIMFloater::boundVoiceChannel()
 	}
 }
 
-void LLIMFloater::enableDisableCallBtn()
-{
-	bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled()
-			&& LLVoiceClient::getInstance()->isVoiceWorking();
-
-	if (mSession)
-	{
-		bool session_initialized = mSession->mSessionInitialized;
-		bool callback_enabled = mSession->mCallBackEnabled;
-
-		BOOL enable_connect =
-				session_initialized && voice_enabled && callback_enabled;
-		getChildView("voice_call_btn")->setEnabled(enable_connect);
-	}
-	else
-	{
-		getChildView("voice_call_btn")->setEnabled(false);
-	}
-}
-
-
 void LLIMFloater::onCallButtonClicked()
 {
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 24a8f17feb..7b2c9e7aef 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -134,10 +134,6 @@ public:
 
 private:
 
-	// process focus events to set a currently active session
-	/* virtual */ void onFocusLost();
-	/* virtual */ void onFocusReceived();
-
 	/*virtual*/ void refresh();
 
 	/*virtual*/ void onClickCloseBtn();
@@ -169,9 +165,6 @@ private:
 
 	void onCallButtonClicked();
 
-	// set the enable/disable state for the Call button
-	virtual void enableDisableCallBtn();
-
 	void boundVoiceChannel();
 
 	// Add the "User is typing..." indicator.
@@ -184,8 +177,6 @@ private:
 
 	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
 
-
-	LLIMModel::LLIMSession* mSession;
 	S32 mLastMessageIndex;
 
 	EInstantMessage mDialog;
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 25bbc82fee..c2ad8cfda3 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -133,6 +133,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& llsd)
 	setIsChrome(TRUE);
 	mKey = LLSD();
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
+	mSessionID = LLUUID();
 	setName("nearby_chat");
 	setIsSingleInstance(TRUE);
 }
@@ -216,21 +217,6 @@ bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
 	return false;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLNearbyChat::onFocusReceived()
-{
-	setBackgroundOpaque(true);
-	LLIMConversation::onFocusReceived();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLNearbyChat::onFocusLost()
-{
-	setBackgroundOpaque(false);
-	LLIMConversation::onFocusLost();
-}
 
 BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
 {
@@ -326,13 +312,6 @@ void	LLNearbyChat::setVisible(BOOL visible)
 }
 
 
-void LLNearbyChat::enableDisableCallBtn()
-{
-	// bool btn_enabled = LLAgent::isActionAllowed("speak");
-
-	getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/);
-}
-
 void LLNearbyChat::onTearOffClicked()
 {
 	LLIMConversation::onTearOffClicked();
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 4fc5cb7f76..1db7afc01f 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -51,10 +51,6 @@ public:
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 
-	// focus overrides
-	/*virtual*/ void	onFocusLost();
-	/*virtual*/ void	onFocusReceived();
-
 	/*virtual*/ void	setVisible(BOOL visible);
 
 	void loadHistory();
@@ -102,9 +98,6 @@ protected:
 
 	void displaySpeakingIndicator();
 
-	// set the enable/disable state for the Call button
-	virtual void enableDisableCallBtn();
-
 	// Which non-zero channel did we last chat on?
 	static S32 sLastSpecialChatChannel;
 
-- 
cgit v1.2.3


From 1229f42ade088f69164b59742305119bacc8f4de Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 5 Sep 2012 18:55:07 -0700
Subject: CHUI-285 : Clear the needs refresh flag when refreshing, comment
 clean up.

---
 indra/newview/llconversationview.cpp   | 15 ++++++++++++++-
 indra/newview/llconversationview.h     |  1 +
 indra/newview/llimfloatercontainer.cpp |  1 -
 3 files changed, 15 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 2f71e92a7d..9f3df93aba 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -100,7 +100,8 @@ LLConversationViewParticipant* LLConversationViewSession::findParticipant(const
 void LLConversationViewSession::refresh()
 {
 	// Refresh the session view from its model data
-	// LLConversationItemSession* vmi = dynamic_cast<LLConversationItemSession*>(getViewModelItem());
+	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+	vmi->resetRefresh();
 	
 	// Note: for the moment, all that needs to be done is done by LLFolderViewItem::refresh()
 	
@@ -122,4 +123,16 @@ LLConversationViewParticipant::LLConversationViewParticipant( const LLConversati
 {
 }
 
+void LLConversationViewParticipant::refresh()
+{
+	// Refresh the participant view from its model data
+	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+	vmi->resetRefresh();
+	
+	// Note: for the moment, all that needs to be done is done by LLFolderViewItem::refresh()
+	
+	// Do the regular upstream refresh
+	LLFolderViewItem::refresh();
+}
+
 // EOF
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 27ceb2af3b..a3755d9722 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -81,6 +81,7 @@ public:
 
 	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
 
+	virtual void refresh();
 private:
 	LLUUID mUUID;		// UUID of the participant
 };
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 1be0c5f075..56648d09b5 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -552,7 +552,6 @@ void LLIMFloaterContainer::repositioningWidgets()
 	}
 }
 
-// CHUI-137 : Temporary implementation of conversations list
 void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 {
 	bool is_nearby_chat = uuid.isNull();
-- 
cgit v1.2.3


From 1a913365b594de81de56896a9fbdfd6d8c4f21e0 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 6 Sep 2012 23:08:10 +0300
Subject: CHUI-319 FIXED ("User has said something new" text shown when
 navigating chat history with More History button)

- Added flag to chat history whether to show notification about unread messages or not
---
 indra/newview/llchathistory.cpp                                     | 5 +++--
 indra/newview/llchathistory.h                                       | 6 +++++-
 indra/newview/skins/default/xui/en/floater_conversation_preview.xml | 1 +
 3 files changed, 9 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index e3d57ab7ae..3636f9e9d2 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -585,7 +585,8 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
 	mBottomSeparatorPad(p.bottom_separator_pad),
 	mTopHeaderPad(p.top_header_pad),
 	mBottomHeaderPad(p.bottom_header_pad),
-	mIsLastMessageFromLog(false)
+	mIsLastMessageFromLog(false),
+	mNotifyAboutUnreadMsg(p.notify_unread_msg)
 {
 	LLTextEditor::Params editor_params(p);
 	editor_params.rect = getLocalRect();
@@ -707,7 +708,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	bool from_me = chat.mFromID == gAgent.getID();
 	mEditor->setPlainText(use_plain_text_chat_history);
 
-	if (!mEditor->scrolledToEnd() && !from_me && !chat.mFromName.empty())
+	if (mNotifyAboutUnreadMsg && !mEditor->scrolledToEnd() && !from_me && !chat.mFromName.empty())
 	{
 		mUnreadChatSources.insert(chat.mFromName);
 		mMoreChatPanel->setVisible(TRUE);
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index 28344e6a10..990c52f31b 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -60,6 +60,8 @@ class LLChatHistory : public LLUICtrl
 
 			Optional<LLTextBox::Params>	more_chat_text;
 
+			Optional<bool>			notify_unread_msg;
+
 			Params()
 			:	message_header("message_header"),
 				message_separator("message_separator"),
@@ -71,7 +73,8 @@ class LLChatHistory : public LLUICtrl
 				bottom_separator_pad("bottom_separator_pad"),
 				top_header_pad("top_header_pad"),
 				bottom_header_pad("bottom_header_pad"),
-				more_chat_text("more_chat_text")
+				more_chat_text("more_chat_text"),
+				notify_unread_msg("notify_unread_msg", true)
 			{}
 
 		};
@@ -122,6 +125,7 @@ class LLChatHistory : public LLUICtrl
 		LLUUID mLastFromID;
 		LLDate mLastMessageTime;
 		bool mIsLastMessageFromLog;
+		bool mNotifyAboutUnreadMsg;
 		//std::string mLastMessageTimeStr;
 
 		std::string mMessageHeaderFilename;
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 c837a0ee57..28ba03ebe9 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -45,6 +45,7 @@
      visible="true"
      height="310"
      name="chat_history"
+     notify_unread_msg="false"
      parse_highlights="true"
      parse_urls="true"
      left="5"
-- 
cgit v1.2.3


From fd17cb601465b3433b647b895baede9b0fd822dd Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 6 Sep 2012 23:16:22 +0300
Subject: CHUI-320 FIXED (Inconsistent name formatting in conversation log
 depending if user started conversation or not)

- On P2P session started, before creating entry of conversation log, requesting avatar name in form of Display Name (user.name)
---
 indra/newview/llconversationlog.cpp | 23 ++++++++++++++++++++---
 indra/newview/llconversationlog.h   |  3 +++
 2 files changed, 23 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 7db6a93709..e80a709203 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -26,6 +26,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llconversationlog.h"
 #include "lltrans.h"
 
@@ -152,6 +153,7 @@ void LLConversation::setListenIMFloaterOpened()
 		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
 	}
 }
+
 /************************************************************************/
 /*             LLConversationLogFriendObserver implementation           */
 /************************************************************************/
@@ -262,9 +264,16 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 	if (session)
 	{
-		LLConversation conversation(*session);
-		LLConversationLog::instance().logConversation(conversation);
-		session->mVoiceChannel->setStateChangedCallback(boost::bind(&LLConversationLog::onVoiceChannelConnected, this, _5, _2));
+		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));
+		}
 	}
 }
 
@@ -425,3 +434,11 @@ void LLConversationLog::onVoiceChannelConnected(const LLUUID& session_id, const
 		}
 	}
 }
+
+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));
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 9fd54c61c9..0d7f0080e5 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -62,6 +62,7 @@ public:
 
 	void	setIsVoice(bool is_voice);
 	void	setIsPast (bool is_past) { mIsConversationPast = is_past; }
+	void	setConverstionName(std::string conv_name) { mConversationName = conv_name; }
 
 	/*
 	 * Resets flag of unread offline message to false when im floater with this conversation is opened.
@@ -156,6 +157,8 @@ private:
 	bool saveToFile(const std::string& filename);
 	bool loadFromFile(const std::string& filename);
 
+	void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session);
+
 	typedef std::vector<LLConversation> conversations_vec_t;
 	std::vector<LLConversation>				mConversations;
 	std::set<LLConversationLogObserver*>	mObservers;
-- 
cgit v1.2.3


From 973f54ace7706c6e3b12cc3364b4c7ffb1b841c9 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 6 Sep 2012 23:18:59 +0300
Subject: CHUI-324 FIXED (No sort order field set by default in conversation
 log)

- Corrected value in settings XML
---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b98fea7032..593381cb29 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10105,7 +10105,7 @@
       <key>Type</key>
       <string>U32</string>
       <key>Value</key>
-      <integer>2</integer>
+      <integer>1</integer>
     </map>
     <key>SortFriendsFirst</key>
     <map>
-- 
cgit v1.2.3


From 62eb7ec0301c0313cedc2fcb63df8779b22a6d26 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 6 Sep 2012 23:34:47 +0300
Subject: CHUI-318 FIXED (User cannot navigate forward in chat history viewer
 once the More History option is selected.)

- Added spinner so that user could select desired history page. Also displaying total count of pages.
---
 indra/newview/llfloaterconversationpreview.cpp     | 11 +++++++
 indra/newview/llfloaterconversationpreview.h       |  3 ++
 .../xui/en/floater_conversation_preview.xml        | 36 +++++++++++++++++-----
 3 files changed, 43 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 7083fb987d..c9d9d7aa3b 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -29,6 +29,7 @@
 #include "llfloaterconversationpreview.h"
 #include "llimview.h"
 #include "lllineeditor.h"
+#include "llspinctrl.h"
 #include "lltrans.h"
 
 LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
@@ -69,6 +70,15 @@ BOOL LLFloaterConversationPreview::postBuild()
 	LLLogChat::loadChatHistory(file, mMessages, true);
 	mCurrentPage = mMessages.size() / mPageSize;
 
+	mPageSpinner = getChild<LLSpinCtrl>("history_page_spin");
+	mPageSpinner->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this));
+	mPageSpinner->setMinValue(1);
+	mPageSpinner->setMaxValue(mCurrentPage + 1);
+	mPageSpinner->set(mCurrentPage + 1);
+
+	std::string total_page_num = llformat("/ %d", mCurrentPage + 1);
+	getChild<LLTextBox>("page_num_label")->setValue(total_page_num);
+
 	return LLFloater::postBuild();
 }
 
@@ -128,6 +138,7 @@ void LLFloaterConversationPreview::showHistory()
 
 void LLFloaterConversationPreview::onMoreHistoryBtnClick()
 {
+	mCurrentPage = mPageSpinner->getValueF32();
 	if (--mCurrentPage < 0)
 	{
 		return;
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index 2246a44761..0341e5d2a0 100644
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -29,6 +29,8 @@
 #include "llchathistory.h"
 #include "llfloater.h"
 
+class LLSpinCtrl;
+
 class LLFloaterConversationPreview : public LLFloater
 {
 public:
@@ -45,6 +47,7 @@ private:
 	void onMoreHistoryBtnClick();
 	void showHistory();
 
+	LLSpinCtrl*		mPageSpinner;
 	LLChatHistory*	mChatHistory;
 	LLUUID			mSessionID;
 	int				mCurrentPage;
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 28ba03ebe9..d74c2c252d 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -51,14 +51,36 @@
      left="5"
      width="390">
     </chat_history>
-    <button
+    <text
      follows="bottom|right"
+     font="SansSerif"
      height="22"
      layout="topleft"
-     name="more_history"
-     label="More history..."
-     right="-15"
-     top_pad="5"
-     width="100">
-    </button>
+     name="page_label"
+     right="-110"
+     top_pad="7"
+     value="Page"
+     width="35">
+    </text>
+    <spinner
+     decimal_digits="0"
+     follows="bottom|right"
+     height="23"
+     increment="1"
+     label_width="40"
+     layout="topleft"
+     left_pad="0"
+     name="history_page_spin"
+     top_delta="-3"
+     width="50"/>
+    <text
+     follows="bottom|right"
+     font="SandSerif"
+     height="22"
+     layout="topleft"
+     name="page_num_label"
+     left_pad="5"
+     top_delta="4"
+     width="40">
+    </text>
 </floater>
-- 
cgit v1.2.3


From ee5e689331ff6ba44cebaf9e9fb48f7bc3f590c4 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 6 Sep 2012 16:32:17 -0700
Subject: CHUI-285 : Completed. Update the names of the participants.

---
 indra/newview/llconversationmodel.cpp | 8 ++++++++
 indra/newview/llconversationmodel.h   | 3 +++
 indra/newview/llparticipantlist.cpp   | 5 ++---
 3 files changed, 13 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index aa21b08ec8..fa49987d15 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -193,6 +193,14 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 {
 }
 
+void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
+{
+	mName = av_name.mDisplayName;
+	// *TODO : we should also store that one, to be used in the tooltip : av_name.mUsername
+	// *TODO : we need to request or initiate a list resort
+	mNeedsRefresh = true;
+}
+
 void LLConversationItemParticipant::dumpDebugData()
 {
 	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 5947055e0f..26c7a29d76 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -29,6 +29,7 @@
 
 #include "llfolderviewitem.h"
 #include "llfolderviewmodel.h"
+#include "llavatarname.h"
 
 // Implementation of conversations list
 
@@ -149,6 +150,8 @@ public:
 	void setIsMuted(bool is_muted) { mIsMuted = is_muted; mNeedsRefresh = true; }
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
 	
+	void onAvatarNameCache(const LLAvatarName& av_name);
+
 	void dumpDebugData();
 
 private:
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index fa3432fc89..2282734109 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -652,6 +652,8 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 		LLAvatarName avatar_name;
 		bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
 		participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.mDisplayName , avatar_id, mRootViewModel);
+		// Binds avatar's name update callback
+		LLAvatarNameCache::get(avatar_id, boost::bind(&LLConversationItemParticipant::onAvatarNameCache, participant, _2));
 		if (mAvatarList)
 		{
 			mAvatarList->getIDs().push_back(avatar_id);
@@ -670,9 +672,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 		mAvalineUpdater->watchAvalineCaller(avatar_id);
 	}
 
-	// *TODO : Merov : need to declare and bind a name update callback on that "participant" instance. See LLAvatarListItem::updateAvatarName() for pattern.
-	// For the moment, we'll get the correct name only if it's already in the name cache (see call to LLAvatarNameCache::get() here above)
-
 	// *TODO : Merov : need to update the online/offline status of the participant.
 	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
 
-- 
cgit v1.2.3


From 47fe3b48fe32f9eb810a23d82eb08c11c41ac335 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 10 Sep 2012 13:48:37 +0300
Subject: CHUI-268 (Transfer the common functionality from LLNearbyChat and
 LLIMFloater to LLIMConversation): moved appendMessage() to base class

---
 indra/newview/llimconversation.cpp | 40 ++++++++++++++++++++++++++++++++++
 indra/newview/llimconversation.h   |  5 +++++
 indra/newview/llimfloater.cpp      | 19 ----------------
 indra/newview/llimfloater.h        |  1 -
 indra/newview/llnearbychat.cpp     | 44 ++------------------------------------
 indra/newview/llnearbychat.h       |  2 --
 6 files changed, 47 insertions(+), 64 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index d8c81a7849..ef3b4f7404 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -223,6 +223,46 @@ void LLIMConversation::onFocusLost()
 	LLTransientDockableFloater::onFocusLost();
 }
 
+std::string LLIMConversation::appendTime()
+{
+	time_t utc_time;
+	utc_time = time_corrected();
+	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+		+LLTrans::getString("TimeMin")+"]";
+
+	LLSD substitution;
+
+	substitution["datetime"] = (S32) utc_time;
+	LLStringUtil::format (timeStr, substitution);
+
+	return timeStr;
+}
+
+void LLIMConversation::appendMessage(const LLChat& chat, const LLSD &args)
+{
+	LLChat& tmp_chat = const_cast<LLChat&>(chat);
+
+	if(tmp_chat.mTimeStr.empty())
+		tmp_chat.mTimeStr = appendTime();
+
+	if (!chat.mMuted)
+	{
+		tmp_chat.mFromName = chat.mFromName;
+		LLSD chat_args;
+		if (args) chat_args = args;
+		chat_args["use_plain_text_chat_history"] =
+				gSavedSettings.getBOOL("PlainTextChatHistory");
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] =
+				!mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+
+		if (mChatHistory)
+		{
+			mChatHistory->appendMessage(chat, chat_args);
+		}
+	}
+}
+
 
 void LLIMConversation::buildParticipantList()
 {
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 50feb12aed..41a76c206e 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -104,6 +104,11 @@ protected:
 	/* virtual */ void onFocusLost();
 	/* virtual */ void onFocusReceived();
 
+	// prepare chat's params and out one message to chatHistory
+	void appendMessage(const LLChat& chat, const LLSD &args = 0);
+
+	std::string appendTime();
+
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 7b475c1e0b..2474fe0891 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -848,25 +848,6 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	}
 }
 
-void LLIMFloater::appendMessage(const LLChat& chat, const LLSD &args)
-{
-	LLChat& tmp_chat = const_cast<LLChat&>(chat);
-
-	if (!chat.mMuted)
-	{
-		tmp_chat.mFromName = chat.mFromName;
-		LLSD chat_args;
-		if (args) chat_args = args;
-		chat_args["use_plain_text_chat_history"] =
-				gSavedSettings.getBOOL("PlainTextChatHistory");
-		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
-		chat_args["show_names_for_p2p_conv"] = !mIsP2PChat
-				|| gSavedSettings.getBOOL("IMShowNamesForP2PConv");
-
-		mChatHistory->appendMessage(chat, chat_args);
-	}
-}
-
 void LLIMFloater::updateMessages()
 {
 	std::list<LLSD> messages;
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 7b2c9e7aef..e4a67a3d56 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -152,7 +152,6 @@ private:
 
 	BOOL isInviteAllowed() const;
 	BOOL inviteToSession(const uuid_vec_t& agent_ids);
-	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
 	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
 	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index c2ad8cfda3..ddd271e23f 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -69,7 +69,7 @@
 
 S32 LLNearbyChat::sLastSpecialChatChannel = 0;
 
-// --- 2 functions in the global namespace :( ---
+// --- function in the global namespace :( ---
 bool isWordsName(const std::string& name)
 {
 	// checking to see if it's display name plus username in parentheses
@@ -89,22 +89,6 @@ bool isWordsName(const std::string& name)
 	}
 }
 
-std::string appendTime()
-{
-	time_t utc_time;
-	utc_time = time_corrected();
-	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
-		+LLTrans::getString("TimeMin")+"]";
-
-	LLSD substitution;
-
-	substitution["datetime"] = (S32) utc_time;
-	LLStringUtil::format (timeStr, substitution);
-
-	return timeStr;
-}
-
-
 const S32 EXPANDED_HEIGHT = 266;
 const S32 COLLAPSED_HEIGHT = 60;
 const S32 EXPANDED_MIN_HEIGHT = 150;
@@ -129,6 +113,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& llsd)
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
 {
+    mIsP2PChat = false;
 	mIsNearbyChat = true;
 	setIsChrome(TRUE);
 	mKey = LLSD();
@@ -604,31 +589,6 @@ void LLNearbyChat::sendChat( EChatType type )
 	}
 }
 
-
-void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args)
-{
-	LLChat& tmp_chat = const_cast<LLChat&>(chat);
-
-	if(tmp_chat.mTimeStr.empty())
-		tmp_chat.mTimeStr = appendTime();
-
-	if (!chat.mMuted)
-	{
-		tmp_chat.mFromName = chat.mFromName;
-		LLSD chat_args;
-		if (args) chat_args = args;
-		chat_args["use_plain_text_chat_history"] =
-				gSavedSettings.getBOOL("PlainTextChatHistory");
-		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
-		chat_args["show_names_for_p2p_conv"] = true;
-
-		if (mChatHistory)
-		{
-			mChatHistory->appendMessage(chat, chat_args);
-		}
-	}
-}
-
 void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
 {
 	appendMessage(chat, args);
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 1db7afc01f..2cbafbfa62 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -108,8 +108,6 @@ protected:
 
 private:
 
-	// prepare chat's params and out one message to chatHistory
-	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 	void	onNearbySpeakers	();
 
 	/*virtual*/ void refresh();
-- 
cgit v1.2.3


From d9309bd16334a7d76da1b02e8fc43117a06ef7b2 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 7 Sep 2012 12:34:21 +0300
Subject: CHUI-323 FIXED (Local chat message panel out of position in
 Conversation floater): Prevented too early creation LLNearbyChat

---
 indra/newview/llimconversation.cpp          | 28 ++++++++++++++--------------
 indra/newview/llnearbychathandler.cpp       |  3 ++-
 indra/newview/llnotificationhandlerutil.cpp |  2 +-
 indra/newview/llnotificationtiphandler.cpp  |  2 +-
 indra/newview/llviewerwindow.cpp            |  6 +++---
 5 files changed, 21 insertions(+), 20 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index ef3b4f7404..216c5bbd70 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -148,7 +148,7 @@ BOOL LLIMConversation::postBuild()
 
 	updateHeaderAndToolbar();
 
-	mSaveRect = !getHost();
+	mSaveRect = isTornOff();
 	initRectControl();
 
 	if (isChatMultiTab())
@@ -349,11 +349,11 @@ void LLIMConversation::hideOrShowTitle()
 	LLView* floater_contents = getChild<LLView>("contents_view");
 
 	LLRect floater_rect = getLocalRect();
-	S32 top_border_of_contents = floater_rect.mTop - (getHost()? 0 : floater_header_size);
+	S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0);
 	LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents);
 	LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom);
 	mDragHandle->setShape(handle_rect);
-	mDragHandle->setVisible(!getHost());
+	mDragHandle->setVisible(isTornOff());
 	floater_contents->setShape(contents_rect);
 }
 
@@ -371,8 +371,8 @@ void LLIMConversation::hideAllStandardButtons()
 
 void LLIMConversation::updateHeaderAndToolbar()
 {
-	bool is_hosted = !!getHost();
-	if (is_hosted)
+	bool is_torn_off = !getHost();
+	if (!is_torn_off)
 	{
 		hideAllStandardButtons();
 	}
@@ -381,7 +381,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 	// Participant list should be visible only in torn off floaters.
 	bool is_participant_list_visible =
-			!is_hosted
+			is_torn_off
 			&& gSavedSettings.getBOOL("IMShowControlPanel")
 			&& !mIsP2PChat;
 
@@ -389,21 +389,21 @@ void LLIMConversation::updateHeaderAndToolbar()
 
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
-	bool is_expanded = is_hosted || is_participant_list_visible;
+	bool is_expanded = !is_torn_off || is_participant_list_visible;
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
 
 	// toggle floater's drag handle and title visibility
 	if (mDragHandle)
 	{
-		mDragHandle->setTitleVisible(!is_hosted);
+		mDragHandle->setTitleVisible(is_torn_off);
 	}
 
 	// The button (>>) should be disabled for torn off P2P conversations.
-	mExpandCollapseBtn->setEnabled(is_hosted || !mIsP2PChat);
+	mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat);
 
-	mTearOffBtn->setImageOverlay(getString(is_hosted? "tear_off_icon" : "return_icon"));
+	mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon"));
 
-	mCloseBtn->setVisible(is_hosted && !mIsNearbyChat);
+	mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat);
 
 	enableDisableCallBtn();
 
@@ -440,7 +440,7 @@ void LLIMConversation::processChatHistoryStyleUpdate()
 		}
 	}
 
-	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
 	if (nearby_chat)
 	{
              nearby_chat->reloadMessages();
@@ -510,8 +510,8 @@ void LLIMConversation::onClose(bool app_quitting)
 
 void LLIMConversation::onTearOffClicked()
 {
-    setFollows(getHost()? FOLLOWS_NONE : FOLLOWS_ALL);
-    mSaveRect = !getHost();
+    setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
+    mSaveRect = isTornOff();
     initRectControl();
 	LLFloater::onClickTearOff(this);
 	updateHeaderAndToolbar();
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index ca3fffeffd..f3e17ea61b 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -487,6 +487,8 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	if(chat_msg.mText.empty())
 		return;//don't process empty messages
 
+	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+
 	// Build notification data 
 	LLSD chat;
 	chat["message"] = chat_msg.mText;
@@ -537,7 +539,6 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 		}
 	}
 
-	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
 	nearby_chat->addMessage(chat_msg, true, args);
 
 	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT 
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 2484040ac4..9fd73746e8 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -181,7 +181,7 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
 // static
 void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
 {
-    LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+    LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
 	if (nearby_chat)
 	{
 		LLChat chat_msg(notification->getMessage());
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index ef6668247c..a293e6acb6 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -86,7 +86,7 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 
 		// don't show toast if Nearby Chat is opened
 		LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
-		if (nearby_chat && nearby_chat->isChatVisible())
+		if (nearby_chat->isChatVisible())
 		{
 			return false;
 		}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 791cadaee4..403288b2fd 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2493,7 +2493,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		return TRUE;
 	}
 
-	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
 
 	// Traverses up the hierarchy
 	if( keyboard_focus )
@@ -2561,10 +2561,10 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	// If "Pressing letter keys starts local chat" option is selected, we are not in mouselook, 
 	// no view has keyboard focus, this is a printable character key (and no modifier key is 
 	// pressed except shift), then give focus to nearby chat (STORM-560)
-	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
+	if ( nearby_chat && gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
-		LLChatEntry* chat_editor = nearby_chat->getChatBox();
+		LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")->getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
-- 
cgit v1.2.3


From 42dbf23dc56e0ab6842dd14b5701ffdb359f8bb6 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 7 Sep 2012 21:35:08 +0300
Subject: CHUI-325 FIXED (Cap conversation log to 30 days, purge older data on
 login)

- Remove conversations older than 30 days from call log
---
 indra/newview/llconversationlog.cpp | 22 ++++++++++++++++++++++
 indra/newview/llconversationlog.h   |  2 ++
 2 files changed, 24 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index e80a709203..cc02e18698 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -30,6 +30,8 @@
 #include "llconversationlog.h"
 #include "lltrans.h"
 
+const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec
+
 struct Conversation_params
 {
 	Conversation_params(time_t time)
@@ -139,6 +141,14 @@ const std::string LLConversation::createTimestamp(const time_t& utc_time)
 	return timeStr;
 }
 
+bool LLConversation::isOlderThan(U32 days) const
+{
+	time_t now = time_corrected();
+	U32 age = (U32)((now - mTime) / SEC_PER_DAY); // age of conversation in days
+
+	return age > days;
+}
+
 void LLConversation::setListenIMFloaterOpened()
 {
 	LLIMFloater* floater = LLIMFloater::findInstance(mSessionID);
@@ -394,10 +404,22 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 		params.mHistoryFileName = std::string(history_file_name);
 
 		LLConversation conversation(params);
+
+		// CHUI-325
+		// The conversation log should be capped to the last 30 days. Conversations with the last utterance
+		// being over 30 days old should be purged from the conversation log text file on login.
+		if (conversation.isOlderThan(CONVERSATION_LIFETIME))
+		{
+			continue;
+		}
+
 		mConversations.push_back(conversation);
 	}
 	fclose(fp);
 
+	LLFile::remove(filename);
+	cache();
+
 	notifyObservers();
 	return true;
 }
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 0d7f0080e5..16be37d67a 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -64,6 +64,8 @@ public:
 	void	setIsPast (bool is_past) { mIsConversationPast = is_past; }
 	void	setConverstionName(std::string conv_name) { mConversationName = conv_name; }
 
+	bool isOlderThan(U32 days) const;
+
 	/*
 	 * Resets flag of unread offline message to false when im floater with this conversation is opened.
 	 */
-- 
cgit v1.2.3


From c26867bb6d1226c82c11f2f386f73b6d8e3ed749 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 7 Sep 2012 19:53:38 -0700
Subject: CHUI-285 : Implement sort, alphabetical only for the moment

---
 indra/newview/llconversationmodel.cpp  | 38 +++++++++++++++++++++++++---------
 indra/newview/llconversationmodel.h    | 15 +++-----------
 indra/newview/llimfloatercontainer.cpp | 16 ++++++++++++--
 indra/newview/llimfloatercontainer.h   |  2 ++
 indra/newview/llparticipantlist.cpp    |  2 --
 5 files changed, 47 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index fa49987d15..e810bac1d9 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -78,14 +78,6 @@ void LLConversationItem::showProperties(void)
 {
 }
 
-bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
-{
-	// We compare only by name for the moment
-	// *TODO : Implement the sorting by date
-	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
-	return (compare < 0);
-}
-
 //
 // LLConversationItemSession
 // 
@@ -197,12 +189,38 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 {
 	mName = av_name.mDisplayName;
 	// *TODO : we should also store that one, to be used in the tooltip : av_name.mUsername
-	// *TODO : we need to request or initiate a list resort
 	mNeedsRefresh = true;
+	if (mParent)
+	{
+		mParent->requestSort();
+	}
 }
 
 void LLConversationItemParticipant::dumpDebugData()
 {
 	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
-}	
+}
+
+//
+// LLConversationSort
+// 
+
+bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
+{
+	// For the moment, we sort only by name
+	// *TODO : Implement the sorting by date as well (most recent first)
+	// *TODO : Check the type of item (session/participants) as order should be different for both (eventually)
+	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+	return (compare < 0);	
+}
+
+//
+// LLConversationViewModel
+//
+
+void LLConversationViewModel::sort(LLFolderViewFolder* folder) 
+{
+	base_t::sort(folder);
+}
+
 // EOF
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 26c7a29d76..2775bf8186 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -208,23 +208,14 @@ private:
 class LLConversationSort
 {
 public:
-	LLConversationSort(U32 order = 0)
-	:	mSortOrder(order),
-	mByDate(false),
-	mByName(false)
-	{
-		mByDate = (order & LLConversationFilter::SO_DATE);
-		mByName = (order & LLConversationFilter::SO_NAME);
-	}
+	LLConversationSort(U32 order = 0) : mSortOrder(order) { }
 	
-	bool isByDate() const { return mByDate; }
+	bool isByDate() const { return (mSortOrder & LLConversationFilter::SO_DATE); }
 	U32 getSortOrder() const { return mSortOrder; }
 	
 	bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
 private:
 	U32  mSortOrder;
-	bool mByDate;
-	bool mByName;
 };
 
 class LLConversationViewModel
@@ -233,7 +224,7 @@ class LLConversationViewModel
 public:
 	typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t;
 	
-	void sort(LLFolderViewFolder* folder) { } // *TODO : implement conversation sort
+	void sort(LLFolderViewFolder* folder);
 	bool contentsReady() { return true; }	// *TODO : we need to check that participants names are available somewhat
 	bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items
 	
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 56648d09b5..fa0750c39c 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -45,6 +45,7 @@
 #include "lltransientfloatermgr.h"
 #include "llviewercontrol.h"
 #include "llconversationview.h"
+#include "llcallbacklist.h"
 
 //
 // LLIMFloaterContainer
@@ -65,6 +66,8 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 
 LLIMFloaterContainer::~LLIMFloaterContainer()
 {
+	gIdleCallbacks.deleteFunction(idle, this);
+
 	mNewMessageConnection.disconnect();
 	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
 
@@ -139,6 +142,9 @@ BOOL LLIMFloaterContainer::postBuild()
 	LLAvatarNameCache::addUseDisplayNamesCallback(
 			boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
+	// Add callback: we'll take care of view updates on idle
+	gIdleCallbacks.addFunction(idle, this);
+
 	return TRUE;
 }
 
@@ -290,6 +296,13 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 	}
 }
 
+//static
+void LLIMFloaterContainer::idle(void* user_data)
+{
+	LLIMFloaterContainer* panel = (LLIMFloaterContainer*)user_data;
+	panel->mConversationsRoot->update();
+}
+
 void LLIMFloaterContainer::draw()
 {
 	// CHUI Notes
@@ -579,7 +592,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	}
 	if (!item)
 	{
-		llinfos << "Merov debug : Couldn't create conversation session item : " << display_name << llendl;
+		llwarns << "Couldn't create conversation session item : " << display_name << llendl;
 		return;
 	}
 	// *TODO: Should we flag LLConversationItemSession with a mIsNearbyChat?
@@ -602,7 +615,6 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	// Note: usually, we do not get an updated avatar list at that point
 	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
 	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
-	llinfos << "Merov debug : create participant, children size = " << item->getChildrenCount() << llendl;
 	while (current_participant_model != end_participant_model)
 	{
 		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index a72a3e2221..c4dd386d7c 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -75,6 +75,8 @@ public:
 
 	void collapseMessagesPane(bool collapse);
 	
+	// Callbacks
+	static void idle(void* user_data);
 
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 2282734109..0d1a37c835 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -675,8 +675,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 	// *TODO : Merov : need to update the online/offline status of the participant.
 	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
 
-	llinfos << "Merov debug : added participant, name = " << participant->getName() << llendl;
-	
 	// Add the participant model to the session's children list
 	addParticipant(participant);
 
-- 
cgit v1.2.3


From 6df8c2b42066efad4d46a601ecaabbc9bf1dcd91 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Sun, 9 Sep 2012 14:48:06 -0700
Subject: CHUI-285 : Complete. Fix participants repositioning.

---
 indra/newview/llimfloatercontainer.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index fa0750c39c..978b91b598 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -358,6 +358,8 @@ void LLIMFloaterContainer::draw()
 		}
 	}
 	
+	repositioningWidgets();
+
 	if (mTabContainer->getTabCount() == 0)
 	{
 		// Do not close the container when every conversation is torn off because the user
@@ -365,8 +367,6 @@ void LLIMFloaterContainer::draw()
 		collapseMessagesPane(true);
 	}
 	LLFloater::draw();
-
-	repositioningWidgets();
 }
 
 void LLIMFloaterContainer::tabClose()
-- 
cgit v1.2.3


From 913375051e2dbe3f1ec68d7b8b86cac613e26ec3 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 10 Sep 2012 16:12:20 +0300
Subject: CHUI-333 (Icons overlap in message panel when maximizing width of
 conversation list): increaced expanded_min_dim for the message pane

---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index e439fc9005..413e66738d 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -113,7 +113,7 @@
          height="430"
          name="messages_layout_panel"
          width="412"
-         expanded_min_dim="205">
+         expanded_min_dim="225">
             <panel_container
              follows="all"
              height="430"
-- 
cgit v1.2.3


From d79037017e3a1627be848b9162f28ae16fcb6004 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 10 Sep 2012 16:20:47 +0300
Subject: CHUI-332 (Overlap of icons in chrome when collapsing and expanding
 conversation list) changed expanded_min_dim of the right panel

---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 413e66738d..1583add857 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -36,7 +36,7 @@
          name="conversations_layout_panel"
          min_dim="38"
          width="268"
-         expanded_min_dim="120">
+         expanded_min_dim="165">
             <layout_stack
              animate="false" 
              follows="left|top|right"
-- 
cgit v1.2.3


From 5dc8738076d158aa74a93f7f3630a17d9102fdc4 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 10 Sep 2012 07:40:13 -0700
Subject: CHUI-283: Basic Implementation, just have hard coded avatar icon
 appearing and profile/info buttons visible. profile/info buttons do not have
 proper positioning or mouseclick events.

---
 indra/llcommon/llfoldertype.h          |   4 +-
 indra/llui/llfolderviewitem.cpp        |   8 ++-
 indra/llui/llfolderviewitem.h          |   2 +-
 indra/newview/llconversationmodel.h    |   4 +-
 indra/newview/llconversationview.cpp   | 110 ++++++++++++++++++++++++++++++++-
 indra/newview/llconversationview.h     |  42 +++++++++++--
 indra/newview/llimfloatercontainer.cpp |   2 +-
 indra/newview/llviewerfoldertype.cpp   |   2 +
 8 files changed, 163 insertions(+), 11 deletions(-)
 mode change 100644 => 100755 indra/llcommon/llfoldertype.h
 mode change 100644 => 100755 indra/llui/llfolderviewitem.cpp
 mode change 100644 => 100755 indra/llui/llfolderviewitem.h
 mode change 100644 => 100755 indra/newview/llconversationmodel.h
 mode change 100644 => 100755 indra/newview/llconversationview.cpp
 mode change 100644 => 100755 indra/newview/llconversationview.h
 mode change 100644 => 100755 indra/newview/llimfloatercontainer.cpp
 mode change 100644 => 100755 indra/newview/llviewerfoldertype.cpp

(limited to 'indra')

diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h
old mode 100644
new mode 100755
index a0c847914f..6b5ae572a9
--- a/indra/llcommon/llfoldertype.h
+++ b/indra/llcommon/llfoldertype.h
@@ -89,7 +89,9 @@ public:
 
 		FT_COUNT,
 
-		FT_NONE = -1
+		FT_NONE = -1,
+
+        FT_PROFILE = 58
 	};
 
 	static EType 				lookup(const std::string& type_name);
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
old mode 100644
new mode 100755
index 52923389cd..c46af27a04
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -609,13 +609,14 @@ void LLFolderViewItem::draw()
 	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
 	static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 
+
+    getViewModelItem()->update();
+
 	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	const S32 TOP_PAD = default_params.item_top_pad;
 	const S32 FOCUS_LEFT = 1;
 	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
-	getViewModelItem()->update();
-
 	//--------------------------------------------------------------------------------//
 	// Draw open folder arrow
 	//
@@ -793,6 +794,9 @@ void LLFolderViewItem::draw()
 							  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
 							  filter_string_length, S32_MAX, &right_x, FALSE );
 		}
+
+        
+        LLView::draw(); 
 	}
 
 const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
old mode 100644
new mode 100755
index 6eacbe8bd0..766d9b3fe3
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -231,7 +231,7 @@ public:
 
 	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
 
-	virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
+	//virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return LLView::findChildView(name, recurse); }
 
 	//	virtual void handleDropped();
 	virtual void draw();
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
old mode 100644
new mode 100755
index 1a2e09dfab..7baabf7f76
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -29,6 +29,7 @@
 
 #include "llfolderviewitem.h"
 #include "llfolderviewmodel.h"
+#include "llviewerfoldertype.h"
 
 // Implementation of conversations list
 
@@ -55,7 +56,7 @@ public:
 	virtual const std::string& getSearchableName() const { return mName; }
 	virtual const LLUUID& getUUID() const { return mUUID; }
 	virtual time_t getCreationDate() const { return 0; }
-	virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
+	virtual LLPointer<LLUIImage> getIcon() const { return LLUI::getUIImage(LLViewerFolderType::lookupIconName(LLFolderType::FT_PROFILE, FALSE)); }
 	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
 	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
@@ -115,6 +116,7 @@ public:
 	LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItemSession() {}
 	
+    LLPointer<LLUIImage> getIcon() const { return NULL; }
 	void setSessionID(const LLUUID& session_id) { mUUID = session_id; }
 	void addParticipant(LLConversationItemParticipant* participant);
 	void removeParticipant(LLConversationItemParticipant* participant);
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
old mode 100644
new mode 100755
index fefb7e9cac..d1a8478697
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -32,9 +32,15 @@
 #include "llimconversation.h"
 #include "llimfloatercontainer.h"
 
+
+#include "lluictrlfactory.h"
+#include "llavatariconctrl.h"
+
 //
 // Implementation of conversations list session widgets
 //
+ 
+
 
 LLConversationViewSession::Params::Params() :	
 	container()
@@ -83,9 +89,111 @@ void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
 // Implementation of conversations list participant (avatar) widgets
 //
 
-LLConversationViewParticipant::LLConversationViewParticipant( const LLFolderViewItem::Params& p ):
+static LLDefaultChildRegistry::Register<LLConversationViewParticipant> r("conversation_view_participant");
+
+LLConversationViewParticipant::Params::Params() :	
+container(),
+view_profile_button("view_profile_button"),
+info_button("info_button")
+{}
+
+LLConversationViewParticipant::LLConversationViewParticipant( const LLConversationViewParticipant::Params& p ):
 	LLFolderViewItem(p)
+{	
+
+}
+
+void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params)
+{
+	LLButton::Params view_profile_button_params(params.view_profile_button());
+	LLButton * button = LLUICtrlFactory::create<LLButton>(view_profile_button_params);
+	addChild(button);
+	
+	LLButton::Params info_button_params(params.info_button());
+	button = LLUICtrlFactory::create<LLButton>(info_button_params);
+	addChild(button);	
+}
+
+BOOL LLConversationViewParticipant::postBuild()
+{
+	mInfoBtn = getChild<LLButton>("info_btn");
+	mProfileBtn = getChild<LLButton>("profile_btn");
+	
+	mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
+	mProfileBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onProfileBtnClick, this));
+	
+	
+	LLFolderViewItem::postBuild();
+	return TRUE;
+}
+
+void LLConversationViewParticipant::onInfoBtnClick()
+{
+	
+	
+}
+
+void LLConversationViewParticipant::onProfileBtnClick()
+{
+	
+}
+
+LLButton* LLConversationViewParticipant::createProfileButton()
+{
+	
+	LLButton::Params params;
+	
+	
+	//<button
+	params.follows.flags(FOLLOWS_RIGHT);
+	//params.height="20";
+	LLUIImage * someImage = LLUI::getUIImage("Web_Profile_Off");
+	params.image_overlay = someImage;
+	params.layout="topleft";
+	params.left_pad=5;
+	//params.right="-28";
+	params.name="profile_btn";
+	params.tab_stop="false";
+	params.tool_tip="View profile";
+	params.top_delta=-2;
+	//params.width="20";
+	///>	
+	
+	
+	/*
+	LLConversationViewParticipant::Params params;
+	
+	params.name = item->getDisplayName();
+	//params.icon = bridge->getIcon();
+	//params.icon_open = bridge->getOpenIcon();
+	//params.creation_date = bridge->getCreationDate();
+	params.root = mConversationsRoot;
+	params.listener = item;
+	params.rect = LLRect (0, 0, 0, 0);
+	params.tool_tip = params.name;
+	params.container = this;
+	*/
+	
+	LLButton * button = LLUICtrlFactory::create<LLButton>(params);
+	LLRect someRect;
+	someRect.setOriginAndSize(30, 0, 20, 20);
+	button->setShape(someRect);
+	
+	//button->follows= "right";
+	//button->height = 20;
+	//button->image_overlay="Web_Profile_Off";
+	//button->right = -28;
+	//button->width = 20;
+
+	
+	
+	return button;
+}
+
+
+void LLConversationViewParticipant::draw()
 {
+    LLFolderViewItem::draw();
 }
 
 // EOF
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
old mode 100644
new mode 100755
index 5695925f43..a7f468cb27
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -29,6 +29,14 @@
 
 #include "llfolderviewitem.h"
 
+
+
+
+#include "llstyle.h"
+#include "llcallbackmap.h"
+#include "lltextbox.h"
+#include "llbutton.h";
+
 class LLIMFloaterContainer;
 
 // Implementation of conversations list session widgets
@@ -57,14 +65,40 @@ public:
 
 // Implementation of conversations list participant (avatar) widgets
 
+class LLAvatarIconCtrl;
+
 class LLConversationViewParticipant : public LLFolderViewItem
 {
+
+public:
+
+    struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
+    {
+        Optional<LLIMFloaterContainer*>			container;
+		Optional<LLButton::Params>				view_profile_button,
+												info_button;
+
+        Params();
+    };
+
+    virtual ~LLConversationViewParticipant( void ) { }
+    virtual void draw();
+    
 protected:
-	friend class LLUICtrlFactory;
-	LLConversationViewParticipant( const LLFolderViewItem::Params& p );
+    friend class LLUICtrlFactory;
+    LLConversationViewParticipant( const Params& p );
+	void initFromParams(const Params& params);
+	BOOL postBuild();
+
+	void onInfoBtnClick();
+	void onProfileBtnClick();	
 	
-public:
-	virtual ~LLConversationViewParticipant( void ) { }
+private:
+	LLButton* createProfileButton();
+	LLButton * mInfoBtn;
+	LLButton * mProfileBtn;
+	
+
 };
 
 #endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
old mode 100644
new mode 100755
index 5261d30cd9..9758f5a93e
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -634,7 +634,7 @@ LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LL
 
 LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParticipant(LLConversationItem* item)
 {
-	LLConversationViewSession::Params params;
+	LLConversationViewParticipant::Params params;
 	
 	params.name = item->getDisplayName();
 	//params.icon = bridge->getIcon();
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
old mode 100644
new mode 100755
index a179b61cff..d470abb8c5
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -147,6 +147,8 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
 		addEntry((LLFolderType::EType)type, 		new ViewerFolderEntry("New Folder",				"Inv_FolderOpen",		"Inv_FolderClosed",		FALSE,     false));
 	}	
 #endif
+
+    addEntry(LLFolderType::FT_PROFILE, 				new ViewerFolderEntry("Profile",				"Generic_Person",		"Generic_Person",		FALSE,     false, "default"));
 }
 
 bool LLViewerFolderDictionary::initEnsemblesFromFile()
-- 
cgit v1.2.3


From 8366efc339e7eca3918d7246b3bb7a9ba61ce765 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 10 Sep 2012 08:38:49 -0700
Subject: CHUI-283, fixed a build problem and also added a missing file.

---
 indra/newview/llconversationview.h                 |  2 +-
 .../en/widgets/conversation_view_participant.xml   | 33 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100755 indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml

(limited to 'indra')

diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index a7f468cb27..0a008475a3 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -35,7 +35,7 @@
 #include "llstyle.h"
 #include "llcallbackmap.h"
 #include "lltextbox.h"
-#include "llbutton.h";
+#include "llbutton.h"
 
 class LLIMFloaterContainer;
 
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
new file mode 100755
index 0000000000..0cff25e083
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<conversation_view_participant
+  folder_arrow_image="ForSale_Badge"
+  folder_indentation="8"
+  item_height="20" 
+  item_top_pad="4"
+  selection_image="Rounded_Square"
+  mouse_opaque="true"
+  follows="left|top|right"
+>
+<view_profile_button
+     height="20"
+     image_overlay="Web_Profile_Off"
+     layout="topleft"
+     left_pad="5"
+     right="200"
+     name="profile_btn"
+     tab_stop="false"
+     tool_tip="View profile"
+     top_delta="-2"
+     width="20" />
+ <info_button
+     height="16"
+     image_pressed="Info_Press"
+     image_unselected="Info_Over"
+     layout="topleft"
+     left_pad="3"
+     right="225"
+     name="info_btn"
+     tab_stop="false"
+     top_delta="0"
+     width="16" />
+</conversation_view_participant>
-- 
cgit v1.2.3


From be06bebffcc1a08c3018ab3712048599455e025b Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Mon, 10 Sep 2012 20:12:27 +0300
Subject: CHUI-282 WIP Modified conversation view item and IM floater container
 so that the folder view handles the positioning of items in conversations
 list.

---
 indra/llui/llfolderviewitem.h                      |   1 -
 indra/newview/llconversationview.cpp               | 170 ++++++++++++++++++++-
 indra/newview/llconversationview.h                 |  13 +-
 indra/newview/llimfloatercontainer.cpp             |  60 ++++++--
 indra/newview/llimfloatercontainer.h               |   2 +
 indra/newview/llinventoryicon.h                    |   2 +-
 .../xui/en/panel_conversation_list_item.xml        |  78 ++++++++++
 7 files changed, 307 insertions(+), 19 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/panel_conversation_list_item.xml

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 6eacbe8bd0..141956c3f0 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -113,7 +113,6 @@ protected:
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
-private:
 	BOOL						mIsSelected;
 
 public:
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 9f3df93aba..514bf38b00 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -42,10 +42,173 @@ LLConversationViewSession::Params::Params() :
 
 LLConversationViewSession::LLConversationViewSession( const LLConversationViewSession::Params& p ):
 	LLFolderViewFolder(p),
-	mContainer(p.container)
+	mContainer(p.container),
+	mItemPanel(NULL),
+	mSessionTitle(NULL)
 {
 }
 
+BOOL LLConversationViewSession::postBuild()
+{
+	LLFolderViewItem::postBuild();
+
+	mItemPanel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_conversation_list_item.xml", NULL, LLPanel::child_registry_t::instance());
+
+	addChild(mItemPanel);
+
+	mSessionTitle = mItemPanel->getChild<LLTextBox>("conversation_title");
+
+	refresh();
+
+	return TRUE;
+}
+
+void LLConversationViewSession::draw()
+{
+	if (mAutoOpenCountdown != 0.f)
+	{
+		mControlLabelRotation = mAutoOpenCountdown * -90.f;
+	}
+	else if (isOpen())
+	{
+		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
+	}
+	else
+	{
+		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
+	}
+
+	const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
+	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+	static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+	static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+
+	const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+	const S32 TOP_PAD = default_params.item_top_pad;
+	const S32 FOCUS_LEFT = 1;
+
+	getViewModelItem()->update();
+
+	//--------------------------------------------------------------------------------//
+	// Draw open folder arrow
+	//
+	if (hasVisibleChildren() || getViewModelItem()->hasChildren())
+	{
+		LLUIImage* arrow_image = default_params.folder_arrow_image;
+		gl_draw_scaled_rotated_image(
+			mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
+			ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
+	}
+
+
+	//--------------------------------------------------------------------------------//
+	// Draw highlight for selected items
+	//
+	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+	const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
+	const S32 focus_top = getRect().getHeight();
+	const S32 focus_bottom = getRect().getHeight() - mItemHeight;
+	const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
+	if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE
+	{
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		LLColor4 bg_color = sHighlightBgColor;
+		if (!mIsCurSelection)
+		{
+			// do time-based fade of extra objects
+			F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
+			if (getRoot() && getRoot()->getShowSingleSelection())
+			{
+				// fading out
+				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
+			}
+			else
+			{
+				// fading in
+				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
+			}
+		}
+		gl_rect_2d(FOCUS_LEFT,
+				   focus_top,
+				   getRect().getWidth() - 2,
+				   focus_bottom,
+				   bg_color, filled);
+		if (mIsCurSelection)
+		{
+			gl_rect_2d(FOCUS_LEFT,
+					   focus_top,
+					   getRect().getWidth() - 2,
+					   focus_bottom,
+					   sFocusOutlineColor, FALSE);
+		}
+		if (folder_open)
+		{
+			gl_rect_2d(FOCUS_LEFT,
+					   focus_bottom + 1, // overlap with bottom edge of above rect
+					   getRect().getWidth() - 2,
+					   0,
+					   sFocusOutlineColor, FALSE);
+			if (show_context)
+			{
+				gl_rect_2d(FOCUS_LEFT,
+						   focus_bottom + 1,
+						   getRect().getWidth() - 2,
+						   0,
+						   sHighlightBgColor, TRUE);
+			}
+		}
+	}
+	else if (mIsMouseOverTitle)
+	{
+		gl_rect_2d(FOCUS_LEFT,
+			focus_top,
+			getRect().getWidth() - 2,
+			focus_bottom,
+			sMouseOverColor, FALSE);
+	}
+
+	//--------------------------------------------------------------------------------//
+	// Draw DragNDrop highlight
+	//
+	if (mDragAndDropTarget)
+	{
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		gl_rect_2d(FOCUS_LEFT,
+				   focus_top,
+				   getRect().getWidth() - 2,
+				   focus_bottom,
+				   sHighlightBgColor, FALSE);
+		if (folder_open)
+		{
+			gl_rect_2d(FOCUS_LEFT,
+					   focus_bottom + 1, // overlap with bottom edge of above rect
+					   getRect().getWidth() - 2,
+					   0,
+					   sHighlightBgColor, FALSE);
+		}
+		mDragAndDropTarget = FALSE;
+	}
+
+	LLView::draw();
+
+	mExpanderHighlighted = FALSE;
+}
+
+// virtual
+S32 LLConversationViewSession::arrange(S32* width, S32* height)
+{
+	LLRect rect(getIndentation() + ARROW_SIZE,
+				getLocalRect().mTop,
+				getLocalRect().mRight,
+				getLocalRect().mTop - getItemHeight());
+	mItemPanel->setRect(rect);
+	mItemPanel->reshape(rect.getWidth(), rect.getHeight());
+
+	return LLFolderViewFolder::arrange(width, height);
+}
+
 void LLConversationViewSession::selectItem()
 {
 	LLFolderViewItem::selectItem();
@@ -103,6 +266,11 @@ void LLConversationViewSession::refresh()
 	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
 	vmi->resetRefresh();
 	
+	if (mSessionTitle)
+	{
+		mSessionTitle->setText(vmi->getDisplayName());
+	}
+
 	// Note: for the moment, all that needs to be done is done by LLFolderViewItem::refresh()
 	
 	// Do the regular upstream refresh
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index a3755d9722..ec99b2eb9b 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -29,6 +29,7 @@
 
 #include "llfolderviewitem.h"
 
+class LLTextBox;
 class LLIMFloaterContainer;
 class LLConversationViewSession;
 class LLConversationViewParticipant;
@@ -53,11 +54,21 @@ protected:
 	
 public:
 	virtual ~LLConversationViewSession( void ) { }
-	virtual void selectItem();	
+	virtual void selectItem();
+
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void draw();
+
+	/*virtual*/ S32 arrange(S32* width, S32* height);
+
 	void setVisibleIfDetached(BOOL visible);
 	LLConversationViewParticipant* findParticipant(const LLUUID& participant_id);
 
 	virtual void refresh();
+
+private:
+	LLPanel*	mItemPanel;
+	LLTextBox*	mSessionTitle;
 };
 
 // Implementation of conversations list participant (avatar) widgets
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 480f964939..9157d16aea 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -38,6 +38,7 @@
 #include "llavataractions.h"
 #include "llavatariconctrl.h"
 #include "llavatarnamecache.h"
+#include "llcallbacklist.h"
 #include "llgroupiconctrl.h"
 #include "llfloateravatarpicker.h"
 #include "llfloaterpreference.h"
@@ -76,6 +77,8 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 	{
 		LLIMMgr::getInstance()->removeSessionObserver(this);
 	}
+
+	gIdleCallbacks.deleteFunction(idle, (void*)this);
 }
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
@@ -117,16 +120,31 @@ BOOL LLIMFloaterContainer::postBuild()
 
 	// CHUI-98 : View Model for conversations
 	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
-	LLFolderView::Params p;
-	p.view_model = &mConversationViewModel;
-	p.parent_panel = mConversationsListPanel;
-	p.rect = mConversationsListPanel->getLocalRect();
-	p.follows.flags = FOLLOWS_ALL;
-	p.listener = base_item;
-	p.root = NULL;
 
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    p.name = getName();
+    p.title = getLabel();
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mConversationsListPanel;
+    p.tool_tip = p.name;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
-	mConversationsListPanel->addChild(mConversationsRoot);
+
+	// Scroller
+	LLRect scroller_view_rect = mConversationsListPanel->getRect();
+	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
+	scroller_params.rect(scroller_view_rect);
+
+	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+	scroller->setFollowsAll();
+	mConversationsListPanel->addChild(scroller);
+	scroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(scroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
 
 	addConversationListItem(LLUUID()); // manually add nearby chat
 
@@ -149,6 +167,9 @@ BOOL LLIMFloaterContainer::postBuild()
 
         mConversationsPane->handleReshape(list_size, TRUE);
 	}
+
+	gIdleCallbacks.addFunction(idle, (void*)this);
+
 	mInitialized = true;
 	return TRUE;
 }
@@ -301,6 +322,13 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 	}
 }
 
+// static
+void LLIMFloaterContainer::idle(void* user_data)
+{
+	LLIMFloaterContainer* self = static_cast<LLIMFloaterContainer*>(user_data);
+	self->mConversationsRoot->update();
+}
+
 void LLIMFloaterContainer::draw()
 {
 	// CHUI Notes
@@ -338,7 +366,6 @@ void LLIMFloaterContainer::draw()
 			{
 				participant_view = createConversationViewParticipant(participant_model);
 				participant_view->addToFolder(session_view);
-				mConversationsListPanel->addChild(participant_view);
 				participant_view->setVisible(TRUE);
 			}
 			else
@@ -363,8 +390,6 @@ void LLIMFloaterContainer::draw()
 		collapseMessagesPane(true);
 	}
 	LLFloater::draw();
-
-	repositioningWidgets();
 }
 
 void LLIMFloaterContainer::tabClose()
@@ -616,7 +641,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	widget->addToFolder(mConversationsRoot);
 
 	// Add it to the UI
-	mConversationsListPanel->addChild(widget);
+//	mConversationsListPanel->addChild(widget);
 	widget->setVisible(TRUE);
 	
 	// Create the participants widgets now
@@ -629,12 +654,16 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
 		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
 		participant_view->addToFolder(widget);
-		mConversationsListPanel->addChild(participant_view);
-		participant_view->setVisible(TRUE);
+//		mConversationsListPanel->addChild(participant_view);
+//		participant_view->setVisible(TRUE);
 		current_participant_model++;
 	}
 
-	repositioningWidgets();
+	S32 width = 0;
+	S32 height = 0;
+	mConversationsRoot->arrange(&width, &height);
+
+//	repositioningWidgets();
 	
 	return;
 }
@@ -678,6 +707,7 @@ LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LL
 	//params.icon = bridge->getIcon();
 	//params.icon_open = bridge->getOpenIcon();
 	//params.creation_date = bridge->getCreationDate();
+	params.item_height = 24;
 	params.root = mConversationsRoot;
 	params.listener = item;
 	params.rect = LLRect (0, 0, 0, 0);
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 53e3849600..427baa03e3 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -71,6 +71,8 @@ public:
 
 	static LLIMFloaterContainer* getInstance();
 
+	static void idle(void* user_data);
+
 	virtual void setMinimized(BOOL b);
 
 	void collapseMessagesPane(bool collapse);
diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h
index c7e2998a20..5c8acf9e85 100644
--- a/indra/newview/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -1,5 +1,5 @@
 /** 
- * @file llinventoryfunctions.h
+ * @file llinventoryicon.h
  * @brief Miscellaneous inventory-related functions and classes
  * class definition
  *
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
new file mode 100644
index 0000000000..d1f25b45fe
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|top|right"
+ height="24"
+ layout="topleft"
+ mouse_opaque="flase"
+ name="conversation_list_item"
+ width="120">
+    <avatar_icon
+     follows="top|left"
+     height="20"
+     default_icon_name="Generic_Person"
+     layout="topleft"
+     left="5"
+     mouse_opaque="true"
+     top="2"
+     width="20" />
+    <layout_stack
+     animate="false"
+     follows="all"
+     height="24"
+     layout="topleft"
+     left_pad="5"
+     name="caonversation_item_stack"
+     orientation="horizontal"
+     top="0"
+     width="90">
+        <layout_panel
+         auto_resize="false"
+         user_resize="false"        
+         height="24"
+         name="call_icon_panel"
+         visible="false"
+         width="20">
+            <icon
+             height="20"
+             follows="top|right|left"
+             image_name="Conv_toolbar_hang_up"
+             layout="topleft"
+             left="0"
+             name="selected_icon"
+             top="2"
+             width="20" />
+        </layout_panel>
+        <layout_panel
+         auto_resize="true"
+         user_resize="false"
+         left_pad="0"        
+         height="24"
+         name="conversation_title_panel"
+         min_dim="50"
+         width="70"
+         expanded_min_dim="50">
+		    <text
+		     follows="left|top|right"
+		     font="SansSerifSmall"
+		     height="15"
+		     layout="topleft"
+		     left="5"
+		     name="conversation_title"
+		     parse_urls="false"
+		     top="6"
+		     use_ellipses="true"
+		     value="(loading)"
+		     width="35" />
+		    <output_monitor
+		     auto_update="true"
+		     follows="top|right"
+		     draw_border="false"
+		     height="16"
+		     layout="topleft"
+		     left_pad="5"
+		     mouse_opaque="true"
+		     name="speaking_indicator"
+		     width="20" />
+        </layout_panel>
+    </layout_stack>
+</panel>
-- 
cgit v1.2.3


From 20b95f6ac0a63ce36cb1a7f51505bbf9ef8015c2 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 10 Sep 2012 11:02:13 -0700
Subject: Attempt to fix Linux build

---
 indra/newview/llfloaterconversationpreview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index c9d9d7aa3b..9ea35fcbad 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -138,7 +138,7 @@ void LLFloaterConversationPreview::showHistory()
 
 void LLFloaterConversationPreview::onMoreHistoryBtnClick()
 {
-	mCurrentPage = mPageSpinner->getValueF32();
+	mCurrentPage = (int)(mPageSpinner->getValueF32());
 	if (--mCurrentPage < 0)
 	{
 		return;
-- 
cgit v1.2.3


From ef39011f433d93ea72cf636d4c415b468f776a01 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 10 Sep 2012 11:09:05 -0700
Subject: CHUI-283: Now displaying the speaker icon instead of the profile icon

---
 indra/newview/llconversationview.cpp               | 24 +++++++-------------
 indra/newview/llconversationview.h                 |  9 ++++----
 .../en/widgets/conversation_view_participant.xml   | 26 +++++++++++-----------
 3 files changed, 25 insertions(+), 34 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index d1a8478697..9c1c9aa225 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -93,8 +93,8 @@ static LLDefaultChildRegistry::Register<LLConversationViewParticipant> r("conver
 
 LLConversationViewParticipant::Params::Params() :	
 container(),
-view_profile_button("view_profile_button"),
-info_button("info_button")
+info_button("info_button"),
+output_monitor("output_monitor")
 {}
 
 LLConversationViewParticipant::LLConversationViewParticipant( const LLConversationViewParticipant::Params& p ):
@@ -104,23 +104,20 @@ LLConversationViewParticipant::LLConversationViewParticipant( const LLConversati
 }
 
 void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params)
-{
-	LLButton::Params view_profile_button_params(params.view_profile_button());
-	LLButton * button = LLUICtrlFactory::create<LLButton>(view_profile_button_params);
-	addChild(button);
-	
+{	
 	LLButton::Params info_button_params(params.info_button());
-	button = LLUICtrlFactory::create<LLButton>(info_button_params);
+	LLButton * button = LLUICtrlFactory::create<LLButton>(info_button_params);
 	addChild(button);	
+
+    LLOutputMonitorCtrl::Params output_monitor_params(params.output_monitor());
+    LLOutputMonitorCtrl * outputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(output_monitor_params);
+    addChild(outputMonitor);
 }
 
 BOOL LLConversationViewParticipant::postBuild()
 {
 	mInfoBtn = getChild<LLButton>("info_btn");
-	mProfileBtn = getChild<LLButton>("profile_btn");
-	
 	mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
-	mProfileBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onProfileBtnClick, this));
 	
 	
 	LLFolderViewItem::postBuild();
@@ -131,11 +128,6 @@ void LLConversationViewParticipant::onInfoBtnClick()
 {
 	
 	
-}
-
-void LLConversationViewParticipant::onProfileBtnClick()
-{
-	
 }
 
 LLButton* LLConversationViewParticipant::createProfileButton()
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 0a008475a3..98eb32d44e 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -36,6 +36,7 @@
 #include "llcallbackmap.h"
 #include "lltextbox.h"
 #include "llbutton.h"
+#include "lloutputmonitorctrl.h"
 
 class LLIMFloaterContainer;
 
@@ -75,9 +76,9 @@ public:
     struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
     {
         Optional<LLIMFloaterContainer*>			container;
-		Optional<LLButton::Params>				view_profile_button,
-												info_button;
-
+		Optional<LLButton::Params>				info_button;
+        Optional<LLOutputMonitorCtrl::Params>   output_monitor;
+        
         Params();
     };
 
@@ -91,12 +92,10 @@ protected:
 	BOOL postBuild();
 
 	void onInfoBtnClick();
-	void onProfileBtnClick();	
 	
 private:
 	LLButton* createProfileButton();
 	LLButton * mInfoBtn;
-	LLButton * mProfileBtn;
 	
 
 };
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
index 0cff25e083..0b5c1b9511 100755
--- a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -8,26 +8,26 @@
   mouse_opaque="true"
   follows="left|top|right"
 >
-<view_profile_button
-     height="20"
-     image_overlay="Web_Profile_Off"
-     layout="topleft"
-     left_pad="5"
-     right="200"
-     name="profile_btn"
-     tab_stop="false"
-     tool_tip="View profile"
-     top_delta="-2"
-     width="20" />
- <info_button
+<info_button
      height="16"
      image_pressed="Info_Press"
      image_unselected="Info_Over"
      layout="topleft"
      left_pad="3"
-     right="225"
+     right="200"
      name="info_btn"
      tab_stop="false"
      top_delta="0"
      width="16" />
+<output_monitor
+	auto_update="true"
+	draw_border="false"
+	height="16"
+	layout="topleft"
+	left_pad="5"
+	right="225"
+	mouse_opaque="true"
+	name="speaking_indicator"
+	visible="true"
+	width="20" />	 
 </conversation_view_participant>
-- 
cgit v1.2.3


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


From ab43940f11b9690c1d3f6874241c66f200f84258 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 12 Sep 2012 15:43:05 -0700
Subject: CHUI-283: Now the speaker icon and information icon are functional.

---
 indra/newview/llconversationview.cpp | 72 +++++++-----------------------------
 indra/newview/llconversationview.h   |  6 +--
 2 files changed, 17 insertions(+), 61 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 1d1c774874..9fb4b4f0dc 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -31,7 +31,7 @@
 #include "llconversationmodel.h"
 #include "llimconversation.h"
 #include "llimfloatercontainer.h"
-
+#include "llfloaterreg.h"
 
 #include "lluictrlfactory.h"
 #include "llavatariconctrl.h"
@@ -151,6 +151,7 @@ BOOL LLConversationViewParticipant::postBuild()
 	mInfoBtn = getChild<LLButton>("info_btn");
 	mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
 	
+	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
 	
 	LLFolderViewItem::postBuild();
 	return TRUE;
@@ -168,68 +169,23 @@ void LLConversationViewParticipant::refresh()
 	LLFolderViewItem::refresh();
 }
 
-void LLConversationViewParticipant::onInfoBtnClick()
+void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
 {
-	
-	
+    //Add the item to the folder (conversation)
+    LLFolderViewItem::addToFolder(folder);
+	
+    //Now retrieve the folder (conversation) UUID, which is the speaker session
+    LLConversationItem* vmi = this->getParentFolder() ? dynamic_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
+    if(vmi)
+    {
+        mSpeakingIndicator->setSpeakerId(mUUID, 
+            vmi->getUUID()); //set the session id
 }
-
-LLButton* LLConversationViewParticipant::createProfileButton()
-{
-	
-	LLButton::Params params;
-	
-	
-	//<button
-	params.follows.flags(FOLLOWS_RIGHT);
-	//params.height="20";
-	LLUIImage * someImage = LLUI::getUIImage("Web_Profile_Off");
-	params.image_overlay = someImage;
-	params.layout="topleft";
-	params.left_pad=5;
-	//params.right="-28";
-	params.name="profile_btn";
-	params.tab_stop="false";
-	params.tool_tip="View profile";
-	params.top_delta=-2;
-	//params.width="20";
-	///>	
-	
-	
-	/*
-	LLConversationViewParticipant::Params params;
-	
-	params.name = item->getDisplayName();
-	//params.icon = bridge->getIcon();
-	//params.icon_open = bridge->getOpenIcon();
-	//params.creation_date = bridge->getCreationDate();
-	params.root = mConversationsRoot;
-	params.listener = item;
-	params.rect = LLRect (0, 0, 0, 0);
-	params.tool_tip = params.name;
-	params.container = this;
-	*/
-	
-	LLButton * button = LLUICtrlFactory::create<LLButton>(params);
-	LLRect someRect;
-	someRect.setOriginAndSize(30, 0, 20, 20);
-	button->setShape(someRect);
-	
-	//button->follows= "right";
-	//button->height = 20;
-	//button->image_overlay="Web_Profile_Off";
-	//button->right = -28;
-	//button->width = 20;
-
-	
-	
-	return button;
 }
 
-
-void LLConversationViewParticipant::draw()
+void LLConversationViewParticipant::onInfoBtnClick()
 {
-    LLFolderViewItem::draw();
+	LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID));
 }
 
 // EOF
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index a7946f4d06..2ac6c999d6 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -89,9 +89,9 @@ public:
     };
 
     virtual ~LLConversationViewParticipant( void ) { }
-    virtual void draw();
     bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
     virtual void refresh();
+    void addToFolder(LLFolderViewFolder* folder);
     
 protected:
 	friend class LLUICtrlFactory;
@@ -102,9 +102,9 @@ protected:
 	void onInfoBtnClick();
 	
 private:
-	LLButton* createProfileButton();
 	LLButton * mInfoBtn;
-    LLUUID mUUID;		// UUID of the participant	
+    LLOutputMonitorCtrl* mSpeakingIndicator;
+    LLUUID mUUID;		// UUID of the participant
 };
 
 #endif // LL_LLCONVERSATIONVIEW_H
-- 
cgit v1.2.3


From 5cad4b5768cccc8301da5e15dd09a0a4e68d4112 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 12 Sep 2012 23:18:52 -0700
Subject: CHUI-308 : Temp fix while waiting for a scroll container to be
 implemented

---
 indra/newview/llimfloatercontainer.cpp | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index faca92e662..b70305a4e9 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -118,7 +118,7 @@ BOOL LLIMFloaterContainer::postBuild()
 	
 	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
-	// CHUI-98 : View Model for conversations
+	// Create the root model and view for all conversation sessions
 	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
 	LLFolderView::Params p;
 	p.view_model = &mConversationViewModel;
@@ -129,6 +129,8 @@ BOOL LLIMFloaterContainer::postBuild()
 	p.root = NULL;
 
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+	mConversationsRoot->setVisible(TRUE);
+	
 	mConversationsListPanel->addChild(mConversationsRoot);
 
 	addConversationListItem(LLUUID()); // manually add nearby chat
@@ -370,8 +372,13 @@ void LLIMFloaterContainer::draw()
 		}
 	}
 	
-	repositioningWidgets();
-
+	// CHUI-308 : Hack! We shouldn't have to do that but we have too as long as
+	// we don't have a scroll container.
+	// *TODO: Take those 3 lines out once we implement the scroll container.
+	repositioningWidgets();	
+	mConversationsRoot->setRect(mConversationsListPanel->getLocalRect());
+	mConversationsRoot->setFollowsAll();
+	
 	if (mTabContainer->getTabCount() == 0)
 	{
 		// Do not close the container when every conversation is torn off because the user
@@ -630,7 +637,6 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	widget->addToFolder(mConversationsRoot);
 
 	// Add it to the UI
-	mConversationsListPanel->addChild(widget);
 	widget->setVisible(TRUE);
 	
 	// Create the participants widgets now
-- 
cgit v1.2.3


From 8c0fcf0e391ff5db78f95f031562eedec998f164 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 13 Sep 2012 16:12:53 +0300
Subject: CHUI-321 FIXED (Indicate within the Call Log why there's nothing in
 it)

I. On "LogInstantMessages" variable set to false:
    1. save call log to file
    2. clear call log
    3. show message: "Conversations are not being logged. To log conversations in the future, select "Save IM logs in my computer" under Preferences > Privacy."
  On "LogInstantMessages" set to true:
    1. clear message
    2. reload all saved call log entries

II. Refactored the way LLConversationLog reacts on "LogInstantMessages" value change
---
 indra/newview/llappviewer.cpp                      |  5 +--
 indra/newview/llconversationlog.cpp                | 36 +++++++++++++---------
 indra/newview/llconversationlog.h                  |  4 +--
 indra/newview/llfloaterconversationlog.cpp         | 13 ++++++++
 indra/newview/llfloaterconversationlog.h           |  2 ++
 .../default/xui/en/floater_conversation_log.xml    |  5 +++
 6 files changed, 44 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4dacde4792..08a1a237f5 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1834,10 +1834,7 @@ bool LLAppViewer::cleanup()
 	LLMuteList::getInstance()->cache(gAgent.getID());
 
 	//save call log list
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
-	{
-		LLConversationLog::instance().cache();
-	}
+	LLConversationLog::instance().cache();
 
 	if (mPurgeOnExit)
 	{
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 239a89015f..27be2bc5ae 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -193,37 +193,40 @@ void LLConversationLogFriendObserver::changed(U32 mask)
 
 LLConversationLog::LLConversationLog()
 {
-	loadFromFile(getFileName());
-
 	LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
 	if (ctrl)
 	{
-		ctrl->getSignal()->connect(boost::bind(&LLConversationLog::observeIMSession, this));
-
+		ctrl->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
 		if (ctrl->getValue().asBoolean())
 		{
-			LLIMMgr::instance().addSessionObserver(this);
-			newMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
+			enableLogging(true);
 		}
 	}
-
-	mFriendObserver = new LLConversationLogFriendObserver;
-	LLAvatarTracker::instance().addObserver(mFriendObserver);
-
 }
 
-void LLConversationLog::observeIMSession()
+void LLConversationLog::enableLogging(bool enable)
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	if (enable)
 	{
+		loadFromFile(getFileName());
+
 		LLIMMgr::instance().addSessionObserver(this);
-		LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
+		newMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
+
+		mFriendObserver = new LLConversationLogFriendObserver;
+		LLAvatarTracker::instance().addObserver(mFriendObserver);
 	}
 	else
 	{
+		saveToFile(getFileName());
+
 		LLIMMgr::instance().removeSessionObserver(this);
 		newMessageSignalConnection.disconnect();
+		LLAvatarTracker::instance().removeObserver(mFriendObserver);
+		mConversations.clear();
 	}
+
+	notifyObservers();
 }
 
 void LLConversationLog::logConversation(const LLUUID& session_id)
@@ -338,7 +341,10 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
 
 void LLConversationLog::cache()
 {
-	saveToFile(getFileName());
+	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	{
+		saveToFile(getFileName());
+	}
 }
 
 std::string LLConversationLog::getFileName()
@@ -349,7 +355,7 @@ std::string LLConversationLog::getFileName()
 
 bool LLConversationLog::saveToFile(const std::string& filename)
 {
-	if(!filename.size())
+	if (!filename.size())
 	{
 		llwarns << "Call log list filename is empty!" << llendl;
 		return false;
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index ffd27f7e20..a458e975bb 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -144,6 +144,8 @@ private:
 
 	LLConversationLog();
 
+	void enableLogging(bool enable);
+
 	/**
 	 * adds conversation to the conversation list and notifies observers
 	 */
@@ -151,8 +153,6 @@ private:
 
 	void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask);
 
-	void observeIMSession();
-
 	/**
 	 * constructs file name in which conversations log will be saved
 	 * file name is conversation.log
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index 7b4c999e52..089aec1905 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -63,6 +63,13 @@ BOOL LLFloaterConversationLog::postBuild()
 
 	getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
 
+	LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
+	if (ctrl)
+	{
+		ctrl->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
+		onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean());
+	}
+
 	return LLFloater::postBuild();
 }
 
@@ -130,3 +137,9 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
 
 	return false;
 }
+
+void LLFloaterConversationLog::onCallLoggingEnabledDisabled(bool enabled)
+{
+	std::string no_items_msg = enabled ? "" : getString("logging_calls_disabled");
+	mConversationLogList->setNoItemsCommentText(no_items_msg);
+}
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
index e971330f3d..9e79cbd7d8 100644
--- a/indra/newview/llfloaterconversationlog.h
+++ b/indra/newview/llfloaterconversationlog.h
@@ -49,6 +49,8 @@ private:
 	bool isActionEnabled(const LLSD& userdata);
 	bool isActionChecked(const LLSD& userdata);
 
+	void onCallLoggingEnabledDisabled(bool enabled);
+
 	LLConversationLogList* mConversationLogList;
 };
 
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index 9cdeb0d788..df78bbccec 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -13,6 +13,11 @@
   reuse_instance="true"
   title="CONVERSATION LOG"
   width="450">
+  
+  <string name="logging_calls_disabled">
+     Conversations are not being logged. To log conversations in the future, select "Save IM logs in my computer" under Preferences > Privacy.
+  </string>
+  
 	<panel
       follows="left|top|right"
       height="27"
-- 
cgit v1.2.3


From 7da24ddaa3813f7b409b51ed5d330c7609b4f8a9 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 13 Sep 2012 17:00:26 +0300
Subject: CHUI-332 [Overlap of icons in chrome when collapsing and expanding
 conversation list]: force header resizing after show/hide minimize button

---
 indra/newview/llimfloatercontainer.cpp                      | 7 +++++++
 indra/newview/skins/default/xui/en/floater_im_container.xml | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index b70305a4e9..a1bd623ac5 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -492,6 +492,13 @@ void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
 	setCanResize(is_left_pane_expanded || is_right_pane_expanded);
 	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
 
+    // force set correct size for the title after show/hide minimize button
+	LLRect cur_rect = getRect();
+	LLRect force_rect = cur_rect;
+	force_rect.mRight = cur_rect.mRight + 1;
+    setRect(force_rect);
+    setRect(cur_rect);
+
     // restore floater's resize limits (prevent collapse when left panel is expanded)
 	if (is_left_pane_expanded && !is_right_pane_expanded)
 	{
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 1583add857..413e66738d 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -36,7 +36,7 @@
          name="conversations_layout_panel"
          min_dim="38"
          width="268"
-         expanded_min_dim="165">
+         expanded_min_dim="120">
             <layout_stack
              animate="false" 
              follows="left|top|right"
-- 
cgit v1.2.3


From a6370cf4a72371e090d45f2a147929d016f42780 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 13 Sep 2012 18:49:57 +0300
Subject: CHUI-334 FIXED (Date not shown in the chat log for current date
 entries)

Before the "%Y/%m/%d" was always cutted from timestamp string for today's date. Now I added flag whether we should cut off timestamp or not.
---
 indra/newview/llfloaterconversationpreview.cpp |  6 +++++-
 indra/newview/lllogchat.cpp                    | 17 +++++++++++++----
 indra/newview/lllogchat.h                      |  4 ++--
 3 files changed, 20 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index dbcf154ef2..88efc39764 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -65,7 +65,11 @@ BOOL LLFloaterConversationPreview::postBuild()
 	std::string title = getString("Title", args);
 	setTitle(title);
 
-	LLLogChat::loadChatHistory(file, mMessages, true);
+	LLSD load_params;
+	load_params["load_all_history"] = true;
+	load_params["cut_off_todays_date"] = false;
+
+	LLLogChat::loadChatHistory(file, mMessages, load_params);
 	mCurrentPage = mMessages.size() / mPageSize;
 
 	mPageSpinner = getChild<LLSpinCtrl>("history_page_spin");
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 073f5f00c5..3692658e9e 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -387,13 +387,16 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
 }
 
 // static
-void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, bool load_all_history/*= false*/)
+void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
 {
 	if (file_name.empty())
 	{
 		llwarns << "Session name is Empty!" << llendl;
 		return ;
 	}
+
+	bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
+
 	//LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
 	//LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
 	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
@@ -449,7 +452,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 		else
 		{
 			LLSD item;
-			if (!LLChatLogParser::parse(line, item))
+			if (!LLChatLogParser::parse(line, item, load_params))
 			{
 				item[IM_TEXT] = line;
 			}
@@ -500,10 +503,11 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 	}
 	}
 
-bool LLChatLogParser::parse(std::string& raw, LLSD& im)
+bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params)
 {
 	if (!raw.length()) return false;
 	
+	bool cut_off_todays_date = parse_params.has("cut_off_todays_date")  ? parse_params["cut_off_todays_date"].asBoolean()  : true;
 	im = LLSD::emptyMap();
 
 	//matching a timestamp
@@ -518,7 +522,12 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
 		boost::trim(timestamp);
 		timestamp.erase(0, 1);
 		timestamp.erase(timestamp.length()-1, 1);
-		LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
+
+		if (cut_off_todays_date)
+		{
+			LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
+		}
+
 		im[IM_TIME] = timestamp;
 	}
 	else
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 95f83e64e5..d3e9adcc37 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -55,7 +55,7 @@ public:
 		                    void (*callback)(ELogLineType, const LLSD&, void*), 
 							void* userdata);
 
-	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, bool load_all_history = false);
+	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
 private:
 	static std::string cleanFileName(std::string filename);
 };
@@ -105,7 +105,7 @@ public:
 	 *
 	 * @return false if failed to parse mandatory data - message text
 	 */
-	static bool parse(std::string& raw, LLSD& im);
+	static bool parse(std::string& raw, LLSD& im, const LLSD& parse_params = LLSD());
 
 protected:
 	LLChatLogParser();
-- 
cgit v1.2.3


From 4b52515b543546844835064dfb89e5af2bbbd948 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Thu, 13 Sep 2012 20:10:45 +0300
Subject: CHUI-282 WIP Fixed conversation list items selection. Fixed
 displaying session participants only when session item is open.

---
 indra/newview/llconversationmodel.cpp              |  5 ++++
 indra/newview/llconversationmodel.h                |  2 ++
 indra/newview/llconversationview.cpp               | 32 ++++++++++++++++++----
 indra/newview/llimfloatercontainer.cpp             | 22 ++-------------
 .../xui/en/panel_conversation_list_item.xml        | 22 +++++++--------
 .../xui/en/widgets/conversation_view_session.xml   |  9 ++++++
 6 files changed, 56 insertions(+), 36 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index fa49987d15..51a37fe856 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -101,6 +101,11 @@ LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolde
 {
 }
 
+bool LLConversationItemSession::hasChildren() const
+{
+	return getChildrenCount() > 0;
+}
+
 void LLConversationItemSession::addParticipant(LLConversationItemParticipant* participant)
 {
 	addChild(participant);
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 26c7a29d76..e5c727feae 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -120,6 +120,8 @@ public:
 	LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItemSession() {}
 	
+	/*virtual*/ bool hasChildren() const;
+
 	void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; }
 	void addParticipant(LLConversationItemParticipant* participant);
 	void removeParticipant(LLConversationItemParticipant* participant);
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 514bf38b00..53971a3159 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -35,12 +35,13 @@
 //
 // Implementation of conversations list session widgets
 //
+static LLDefaultChildRegistry::Register<LLConversationViewSession> r_conversation_view_session("conversation_view_session");
 
 LLConversationViewSession::Params::Params() :	
 	container()
 {}
 
-LLConversationViewSession::LLConversationViewSession( const LLConversationViewSession::Params& p ):
+LLConversationViewSession::LLConversationViewSession(const LLConversationViewSession::Params& p):
 	LLFolderViewFolder(p),
 	mContainer(p.container),
 	mItemPanel(NULL),
@@ -65,6 +66,8 @@ BOOL LLConversationViewSession::postBuild()
 
 void LLConversationViewSession::draw()
 {
+// *TODO Seth PE: remove the code duplicated from LLFolderViewFolder::draw()
+// ***** LLFolderViewFolder::draw() code begin *****
 	if (mAutoOpenCountdown != 0.f)
 	{
 		mControlLabelRotation = mAutoOpenCountdown * -90.f;
@@ -77,7 +80,10 @@ void LLConversationViewSession::draw()
 	{
 		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
 	}
+// ***** LLFolderViewFolder::draw() code end *****
 
+// *TODO Seth PE: remove the code duplicated from LLFolderViewItem::draw()
+// ***** LLFolderViewItem::draw() code begin *****
 	const LLColor4U DEFAULT_WHITE(255, 255, 255);
 
 	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
@@ -190,10 +196,27 @@ void LLConversationViewSession::draw()
 		}
 		mDragAndDropTarget = FALSE;
 	}
+// ***** LLFolderViewItem::draw() code end *****
 
-	LLView::draw();
+	// draw children if root folder, or any other folder that is open or animating to closed state
+	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this)
+						 || isOpen()
+						 || mCurHeight != mTargetHeight;
 
-	mExpanderHighlighted = FALSE;
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		(*fit)->setVisible(draw_children);
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		(*iit)->setVisible(draw_children);
+	}
+
+	LLView::draw();
 }
 
 // virtual
@@ -203,8 +226,7 @@ S32 LLConversationViewSession::arrange(S32* width, S32* height)
 				getLocalRect().mTop,
 				getLocalRect().mRight,
 				getLocalRect().mTop - getItemHeight());
-	mItemPanel->setRect(rect);
-	mItemPanel->reshape(rect.getWidth(), rect.getHeight());
+	mItemPanel->setShape(rect);
 
 	return LLFolderViewFolder::arrange(width, height);
 }
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 9157d16aea..79009942bf 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -132,7 +132,7 @@ BOOL LLIMFloaterContainer::postBuild()
     p.root = NULL;
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
 
-	// Scroller
+	// a scroller for folder view
 	LLRect scroller_view_rect = mConversationsListPanel->getRect();
 	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
 	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
@@ -639,10 +639,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 
 	// Add a new conversation widget to the root folder of the folder view
 	widget->addToFolder(mConversationsRoot);
-
-	// Add it to the UI
-//	mConversationsListPanel->addChild(widget);
-	widget->setVisible(TRUE);
+	widget->requestArrange();
 	
 	// Create the participants widgets now
 	// Note: usually, we do not get an updated avatar list at that point
@@ -654,16 +651,8 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
 		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
 		participant_view->addToFolder(widget);
-//		mConversationsListPanel->addChild(participant_view);
-//		participant_view->setVisible(TRUE);
 		current_participant_model++;
 	}
-
-	S32 width = 0;
-	S32 height = 0;
-	mConversationsRoot->arrange(&width, &height);
-
-//	repositioningWidgets();
 	
 	return;
 }
@@ -683,8 +672,6 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	// Suppress the conversation items and widgets from their respective maps
 	mConversationsItems.erase(uuid);
 	mConversationsWidgets.erase(uuid);
-
-	repositioningWidgets();
 	
 	// Don't let the focus fall IW, select and refocus on the first conversation in the list
 	if (change_focus)
@@ -704,13 +691,8 @@ LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LL
 	LLConversationViewSession::Params params;
 	
 	params.name = item->getDisplayName();
-	//params.icon = bridge->getIcon();
-	//params.icon_open = bridge->getOpenIcon();
-	//params.creation_date = bridge->getCreationDate();
-	params.item_height = 24;
 	params.root = mConversationsRoot;
 	params.listener = item;
-	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
 	params.container = this;
 	
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
index d1f25b45fe..375ea79ebe 100644
--- a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
@@ -3,8 +3,8 @@
  follows="left|top|right"
  height="24"
  layout="topleft"
- mouse_opaque="flase"
  name="conversation_list_item"
+ mouse_opaque="false"
  width="120">
     <avatar_icon
      follows="top|left"
@@ -12,7 +12,6 @@
      default_icon_name="Generic_Person"
      layout="topleft"
      left="5"
-     mouse_opaque="true"
      top="2"
      width="20" />
     <layout_stack
@@ -21,7 +20,8 @@
      height="24"
      layout="topleft"
      left_pad="5"
-     name="caonversation_item_stack"
+     mouse_opaque="false"
+     name="conversation_item_stack"
      orientation="horizontal"
      top="0"
      width="90">
@@ -29,6 +29,7 @@
          auto_resize="false"
          user_resize="false"        
          height="24"
+         mouse_opaque="false"
          name="call_icon_panel"
          visible="false"
          width="20">
@@ -44,13 +45,11 @@
         </layout_panel>
         <layout_panel
          auto_resize="true"
-         user_resize="false"
-         left_pad="0"        
+         user_resize="false"    
          height="24"
+         mouse_opaque="false"
          name="conversation_title_panel"
-         min_dim="50"
-         width="70"
-         expanded_min_dim="50">
+         width="70">
 		    <text
 		     follows="left|top|right"
 		     font="SansSerifSmall"
@@ -70,9 +69,10 @@
 		     height="16"
 		     layout="topleft"
 		     left_pad="5"
-		     mouse_opaque="true"
-		     name="speaking_indicator"
-		     width="20" />
+ 		     mouse_opaque="true"
+ 		     name="speaking_indicator"
+ 		     visible="false"
+ 		     width="20" />
         </layout_panel>
     </layout_stack>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
new file mode 100644
index 0000000000..f44731ea3d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<conversation_view_session
+  folder_arrow_image="Folder_Arrow"
+  folder_indentation="8"
+  item_height="24" 
+  item_top_pad="4"
+  selection_image="Rounded_Square"
+  mouse_opaque="true"
+  follows="left|top|right"/>
-- 
cgit v1.2.3


From 2084d33c1ec827b4e8d975a3bf1232e971f704e2 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 13 Sep 2012 11:22:41 -0700
Subject: CHUI-283: Now the information icon only appears upon mousehover. Also
 the information/speaker icon are right justified.

---
 indra/llui/llfolderviewitem.cpp                    |  2 +-
 indra/newview/llconversationview.cpp               | 23 ++++++++++++++++++----
 indra/newview/llconversationview.h                 |  5 ++++-
 indra/newview/llimfloatercontainer.cpp             |  3 ++-
 .../en/widgets/conversation_view_participant.xml   | 11 +++++------
 5 files changed, 31 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index c46af27a04..155a605c3b 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -771,7 +771,7 @@ void LLFolderViewItem::draw()
 	//
 	font->renderUTF8(mLabel, 0, text_left, y, color,
 					 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-					 S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);
+					 S32_MAX, getRect().getWidth() - (S32) text_left - TEXT_PAD_RIGHT, &right_x, TRUE);
 
 	//--------------------------------------------------------------------------------//
 	// Draw label suffix
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 9fb4b4f0dc..7b1c9ef912 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -138,10 +138,12 @@ LLConversationViewParticipant::LLConversationViewParticipant( const LLConversati
 void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params)
 {	
 	LLButton::Params info_button_params(params.info_button());
+    applyXUILayout(info_button_params, this);
 	LLButton * button = LLUICtrlFactory::create<LLButton>(info_button_params);
 	addChild(button);	
 
     LLOutputMonitorCtrl::Params output_monitor_params(params.output_monitor());
+    applyXUILayout(output_monitor_params, this);
     LLOutputMonitorCtrl * outputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(output_monitor_params);
     addChild(outputMonitor);
 }
@@ -150,9 +152,10 @@ BOOL LLConversationViewParticipant::postBuild()
 {
 	mInfoBtn = getChild<LLButton>("info_btn");
 	mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
-	
+	mInfoBtn->setVisible(false);
+
 	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
-	
+
 	LLFolderViewItem::postBuild();
 	return TRUE;
 }
@@ -179,8 +182,8 @@ void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
     if(vmi)
     {
         mSpeakingIndicator->setSpeakerId(mUUID, 
-            vmi->getUUID()); //set the session id
-}
+        vmi->getUUID()); //set the session id
+    }
 }
 
 void LLConversationViewParticipant::onInfoBtnClick()
@@ -188,5 +191,17 @@ void LLConversationViewParticipant::onInfoBtnClick()
 	LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID));
 }
 
+void LLConversationViewParticipant::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+    mInfoBtn->setVisible(true);
+    LLFolderViewItem::onMouseEnter(x, y, mask);
+}
+
+void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+    mInfoBtn->setVisible(false);
+    LLFolderViewItem::onMouseEnter(x, y, mask);
+}
+
 // EOF
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 2ac6c999d6..0dcf6542a3 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -92,7 +92,10 @@ public:
     bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
     virtual void refresh();
     void addToFolder(LLFolderViewFolder* folder);
-    
+
+    void onMouseEnter(S32 x, S32 y, MASK mask);
+    void onMouseLeave(S32 x, S32 y, MASK mask);
+
 protected:
 	friend class LLUICtrlFactory;
     LLConversationViewParticipant( const Params& p );
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index faca92e662..3243fd48de 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -703,6 +703,7 @@ LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LL
 LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParticipant(LLConversationItem* item)
 {
 	LLConversationViewParticipant::Params params;
+    LLRect panel_rect = mConversationsListPanel->getRect();
 	
 	params.name = item->getDisplayName();
 	//params.icon = bridge->getIcon();
@@ -710,7 +711,7 @@ LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParti
 	//params.creation_date = bridge->getCreationDate();
 	params.root = mConversationsRoot;
 	params.listener = item;
-	params.rect = LLRect (0, 0, 0, 0);
+	params.rect = LLRect (0, 16, panel_rect.getWidth(), 0);
 	params.tool_tip = params.name;
 	params.participant_id = item->getUUID();
 	
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
index 0b5c1b9511..60015576b5 100755
--- a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -9,23 +9,22 @@
   follows="left|top|right"
 >
 <info_button
+	 follows="right"
+	 auto_update="true"
      height="16"
      image_pressed="Info_Press"
      image_unselected="Info_Over"
      layout="topleft"
-     left_pad="3"
-     right="200"
+     right="-28"
      name="info_btn"
-     tab_stop="false"
-     top_delta="0"
      width="16" />
 <output_monitor
+	follows="right"
 	auto_update="true"
 	draw_border="false"
 	height="16"
 	layout="topleft"
-	left_pad="5"
-	right="225"
+	right="-3"
 	mouse_opaque="true"
 	name="speaking_indicator"
 	visible="true"
-- 
cgit v1.2.3


From 386c50d414e6357975cb18814b6bfb048b46b3da Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 14 Sep 2012 00:29:50 +0300
Subject: CHUI-282 WIP Removed the hack added for CHUI-308 to resize the folder
 view in conversation list. Fixed some glitches after automated merge.

---
 indra/newview/llimfloatercontainer.cpp | 11 -----------
 indra/newview/llimfloatercontainer.h   |  2 --
 2 files changed, 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 6aa7a2e054..58b788d231 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -80,8 +80,6 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 	{
 		LLIMMgr::getInstance()->removeSessionObserver(this);
 	}
-
-	gIdleCallbacks.deleteFunction(idle, (void*)this);
 }
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
@@ -171,8 +169,6 @@ BOOL LLIMFloaterContainer::postBuild()
         mConversationsPane->handleReshape(list_size, TRUE);
 	}
 
-	gIdleCallbacks.addFunction(idle, (void*)this);
-
 	mInitialized = true;
 
 	// Add callback: we'll take care of view updates on idle
@@ -390,13 +386,6 @@ void LLIMFloaterContainer::draw()
 		}
 	}
 	
-	// CHUI-308 : Hack! We shouldn't have to do that but we have too as long as
-	// we don't have a scroll container.
-	// *TODO: Take those 3 lines out once we implement the scroll container.
-	repositioningWidgets();	
-	mConversationsRoot->setRect(mConversationsListPanel->getLocalRect());
-	mConversationsRoot->setFollowsAll();
-	
 	if (mTabContainer->getTabCount() == 0)
 	{
 		// Do not close the container when every conversation is torn off because the user
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index bda1ce0cb1..324adfcc11 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -71,8 +71,6 @@ public:
 
 	static LLIMFloaterContainer* getInstance();
 
-	static void idle(void* user_data);
-
 	virtual void setMinimized(BOOL b);
 
 	void collapseMessagesPane(bool collapse);
-- 
cgit v1.2.3


From c6863d18d7c981756c57bbcd52baa06af00d1551 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 13 Sep 2012 19:10:28 -0700
Subject: CHUI-283: Now upon the information icon and speaker icon do not
 overlap the username text. Instead the username text will be truncated with
 an ellipse to prevent the overlap. Also did a code cleanup.

---
 indra/llcommon/llfoldertype.h          |  2 +-
 indra/llui/llfolderviewitem.cpp        | 31 +++++++-------
 indra/llui/llfolderviewitem.h          |  4 +-
 indra/newview/llconversationmodel.h    |  2 +-
 indra/newview/llconversationview.cpp   | 78 ++++++++++++++++++++++++++++++++--
 indra/newview/llconversationview.h     | 20 +++++----
 indra/newview/llimfloatercontainer.cpp |  2 +
 indra/newview/llviewerfoldertype.cpp   |  2 +-
 8 files changed, 110 insertions(+), 31 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h
index 6b5ae572a9..609b550900 100755
--- a/indra/llcommon/llfoldertype.h
+++ b/indra/llcommon/llfoldertype.h
@@ -91,7 +91,7 @@ public:
 
 		FT_NONE = -1,
 
-        FT_PROFILE = 58
+        FT_PROFILEXXXGGG = 58
 	};
 
 	static EType 				lookup(const std::string& type_name);
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 155a605c3b..7ca02b726a 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -98,6 +98,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 :	LLView(p),
 	mLabelWidth(0),
 	mLabelWidthDirty(false),
+    mLabelPaddingRight(DEFAULT_TEXT_PADDING_RIGHT),
 	mParentFolder( NULL ),
 	mIsSelected( FALSE ),
 	mIsCurSelection( FALSE ),
@@ -291,7 +292,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
 		: 0;
 	if (mLabelWidthDirty)
 	{
-		mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + TEXT_PAD_RIGHT; 
+		mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight; 
 		mLabelWidthDirty = false;
 	}
 
@@ -610,13 +611,13 @@ void LLFolderViewItem::draw()
 	static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 
 
-    getViewModelItem()->update();
-
 	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	const S32 TOP_PAD = default_params.item_top_pad;
 	const S32 FOCUS_LEFT = 1;
 	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
+    getViewModelItem()->update();
+
 	//--------------------------------------------------------------------------------//
 	// Draw open folder arrow
 	//
@@ -771,7 +772,7 @@ void LLFolderViewItem::draw()
 	//
 	font->renderUTF8(mLabel, 0, text_left, y, color,
 					 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-					 S32_MAX, getRect().getWidth() - (S32) text_left - TEXT_PAD_RIGHT, &right_x, TRUE);
+					 S32_MAX, getRect().getWidth() - (S32) text_left - mLabelPaddingRight, &right_x, TRUE);
 
 	//--------------------------------------------------------------------------------//
 	// Draw label suffix
@@ -786,18 +787,18 @@ void LLFolderViewItem::draw()
 	//--------------------------------------------------------------------------------//
 	// Highlight string match
 	//
-		if (filter_string_length > 0)
-		{
-		F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
-			F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-		font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
-							  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-							  filter_string_length, S32_MAX, &right_x, FALSE );
-		}
+    if (filter_string_length > 0)
+    {
+        F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
+        F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+        font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
+            sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+            filter_string_length, S32_MAX, &right_x, FALSE );
+    }
 
-        
-        LLView::draw(); 
-	}
+
+    LLView::draw(); 
+}
 
 const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
 {
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 766d9b3fe3..fab24e52d1 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -68,7 +68,7 @@ public:
 						ICON_PAD = 2,
 						ICON_WIDTH = 16,
 						TEXT_PAD = 1,
-						TEXT_PAD_RIGHT = 4,
+                        DEFAULT_TEXT_PADDING_RIGHT = 4,
 						ARROW_SIZE = 12,
 						MAX_FOLDER_ITEM_OVERLAP = 2;
 	
@@ -85,6 +85,7 @@ protected:
 	std::string					mLabel;
 	S32							mLabelWidth;
 	bool						mLabelWidthDirty;
+    S32                         mLabelPaddingRight;
 	LLFolderViewFolder*			mParentFolder;
 	LLFolderViewModelItem*		mViewModelItem;
 	LLFontGL::StyleFlags		mLabelStyle;
@@ -243,6 +244,7 @@ public:
 
 private:
 	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
+
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 4f13d3d3a1..e1713f9db7 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -57,7 +57,7 @@ public:
 	virtual const std::string& getSearchableName() const { return mName; }
 	virtual const LLUUID& getUUID() const { return mUUID; }
 	virtual time_t getCreationDate() const { return 0; }
-	virtual LLPointer<LLUIImage> getIcon() const { return LLUI::getUIImage(LLViewerFolderType::lookupIconName(LLFolderType::FT_PROFILE, FALSE)); }
+	virtual LLPointer<LLUIImage> getIcon() const { return LLUI::getUIImage(LLViewerFolderType::lookupIconName(LLFolderType::FT_PROFILEXXXGGG, FALSE)); }
 	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
 	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 7b1c9ef912..bc85cd68bc 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -28,13 +28,13 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llconversationview.h"
+
+#include <boost/bind.hpp>
 #include "llconversationmodel.h"
 #include "llimconversation.h"
 #include "llimfloatercontainer.h"
 #include "llfloaterreg.h"
-
 #include "lluictrlfactory.h"
-#include "llavatariconctrl.h"
 
 //
 // Implementation of conversations list session widgets
@@ -120,6 +120,8 @@ void LLConversationViewSession::refresh()
 //
 
 static LLDefaultChildRegistry::Register<LLConversationViewParticipant> r("conversation_view_participant");
+bool LLConversationViewParticipant::sStaticInitialized = false;
+S32 LLConversationViewParticipant::sChildrenWidths[LLConversationViewParticipant::ALIC_COUNT];
 
 LLConversationViewParticipant::Params::Params() :	
 container(),
@@ -130,6 +132,8 @@ output_monitor("output_monitor")
 
 LLConversationViewParticipant::LLConversationViewParticipant( const LLConversationViewParticipant::Params& p ):
 	LLFolderViewItem(p),
+    mInfoBtn(NULL),
+    mSpeakingIndicator(NULL),
     mUUID(p.participant_id)
 {
 
@@ -156,8 +160,16 @@ BOOL LLConversationViewParticipant::postBuild()
 
 	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
 
-	LLFolderViewItem::postBuild();
-	return TRUE;
+    if (!sStaticInitialized)
+    {
+        // Remember children widths including their padding from the next sibling,
+        // so that we can hide and show them again later.
+        initChildrenWidths(this);
+        sStaticInitialized = true;
+    }
+
+    computeLabelRightPadding();
+	return LLFolderViewItem::postBuild();
 }
 
 void LLConversationViewParticipant::refresh()
@@ -194,14 +206,72 @@ void LLConversationViewParticipant::onInfoBtnClick()
 void LLConversationViewParticipant::onMouseEnter(S32 x, S32 y, MASK mask)
 {
     mInfoBtn->setVisible(true);
+    computeLabelRightPadding();
     LLFolderViewItem::onMouseEnter(x, y, mask);
 }
 
 void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
 {
     mInfoBtn->setVisible(false);
+    computeLabelRightPadding();
     LLFolderViewItem::onMouseEnter(x, y, mask);
 }
 
+// static
+void LLConversationViewParticipant::initChildrenWidths(LLConversationViewParticipant* self)
+{
+    //speaking indicator width + padding
+    S32 speaking_indicator_width = self->getRect().getWidth() - self->mSpeakingIndicator->getRect().mLeft;
+
+    //info btn width + padding
+    S32 info_btn_width = self->mSpeakingIndicator->getRect().mLeft - self->mInfoBtn->getRect().mLeft;
+
+    S32 index = ALIC_COUNT;
+    sChildrenWidths[--index] = info_btn_width;
+    sChildrenWidths[--index] = speaking_indicator_width;
+    llassert(index == 0);
+}
+
+void LLConversationViewParticipant::computeLabelRightPadding()
+{
+    mLabelPaddingRight = DEFAULT_TEXT_PADDING_RIGHT;
+    LLView* control;
+    S32 ctrl_width;
+
+    for (S32 i = 0; i < ALIC_COUNT; ++i)
+    {
+        control = getItemChildView((EAvatarListItemChildIndex)i);
+
+        // skip invisible views
+        if (!control->getVisible()) continue;
+
+        ctrl_width = sChildrenWidths[i]; // including space between current & left controls
+        // accumulate the amount of space taken by the controls
+        mLabelPaddingRight += ctrl_width;
+    }
+}
+
+LLView* LLConversationViewParticipant::getItemChildView(EAvatarListItemChildIndex child_view_index)
+{
+    LLView* child_view = NULL;
+
+    switch (child_view_index)
+    {
+        case ALIC_SPEAKER_INDICATOR:
+            child_view = mSpeakingIndicator;
+            break;
+        case ALIC_INFO_BUTTON:
+            child_view = mInfoBtn;
+            break;
+        default:
+            LL_WARNS("AvatarItemReshape") << "Unexpected child view index is passed: " << child_view_index << LL_ENDL;
+            llassert(0);
+            break;
+            // leave child_view untouched
+    }
+
+    return child_view;
+}
+
 // EOF
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 0dcf6542a3..686a79ad39 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -29,12 +29,6 @@
 
 #include "llfolderviewitem.h"
 
-
-
-
-#include "llstyle.h"
-#include "llcallbackmap.h"
-#include "lltextbox.h"
 #include "llbutton.h"
 #include "lloutputmonitorctrl.h"
 
@@ -71,8 +65,6 @@ public:
 
 // Implementation of conversations list participant (avatar) widgets
 
-class LLAvatarIconCtrl;
-
 class LLConversationViewParticipant : public LLFolderViewItem
 {
 
@@ -108,6 +100,18 @@ private:
 	LLButton * mInfoBtn;
     LLOutputMonitorCtrl* mSpeakingIndicator;
     LLUUID mUUID;		// UUID of the participant
+
+    typedef enum e_avatar_item_child {
+        ALIC_SPEAKER_INDICATOR,
+        ALIC_INFO_BUTTON,
+        ALIC_COUNT,
+    } EAvatarListItemChildIndex;
+
+    static bool	sStaticInitialized; // this variable is introduced to improve code readability
+    static S32 sChildrenWidths[ALIC_COUNT];
+    static void initChildrenWidths(LLConversationViewParticipant* self);
+    void computeLabelRightPadding();
+    LLView* getItemChildView(EAvatarListItemChildIndex child_view_index);
 };
 
 #endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 9320117eb5..299d38298e 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -724,6 +724,8 @@ LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParti
 	//params.creation_date = bridge->getCreationDate();
 	params.root = mConversationsRoot;
 	params.listener = item;
+
+    //16 and panel_rect.getWidth() are used since that is currently the values used in repositioningWidgets()
 	params.rect = LLRect (0, 16, panel_rect.getWidth(), 0);
 	params.tool_tip = params.name;
 	params.participant_id = item->getUUID();
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index d470abb8c5..0a402d8c42 100755
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -148,7 +148,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
 	}	
 #endif
 
-    addEntry(LLFolderType::FT_PROFILE, 				new ViewerFolderEntry("Profile",				"Generic_Person",		"Generic_Person",		FALSE,     false, "default"));
+    addEntry(LLFolderType::FT_PROFILEXXXGGG, 				new ViewerFolderEntry("Profile",				"Generic_Person",		"Generic_Person",		FALSE,     false, "default"));
 }
 
 bool LLViewerFolderDictionary::initEnsemblesFromFile()
-- 
cgit v1.2.3


From 72f6bebe59f5f900af02a4d234a4091a3e034529 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 14 Sep 2012 16:11:42 +0300
Subject: CHUI-261 Additional fix (Nearby chat controls and log are not visible
 on next login after tearing off and docking nearby chat in previous session):
 prevent start LLNearbyChat before start its container

---
 indra/newview/llimconversation.cpp | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index bab588126f..a2efe63546 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -381,6 +381,9 @@ void LLIMConversation::hideAllStandardButtons()
 
 void LLIMConversation::updateHeaderAndToolbar()
 {
+	// prevent start conversation before its container
+    LLIMFloaterContainer::getInstance();
+
 	bool is_torn_off = !getHost();
 	if (!is_torn_off)
 	{
-- 
cgit v1.2.3


From 399ba09c08d8ccaf9b34daa8b743f837639b2f35 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 14 Sep 2012 18:47:39 -0700
Subject: CHUI-283: Now the info/speaker icon are better positioned within the
 participant item. Also the participant item now matches the height of the
 session (conversation) item.

---
 indra/newview/llimfloatercontainer.cpp                               | 2 +-
 .../skins/default/xui/en/widgets/conversation_view_participant.xml   | 5 +----
 2 files changed, 2 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 54a40627fb..e039702683 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -721,7 +721,7 @@ LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParti
 	params.listener = item;
 
     //16 and panel_rect.getWidth() are used since that is currently the values used in repositioningWidgets()
-	params.rect = LLRect (0, 16, panel_rect.getWidth(), 0);
+	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
 	params.tool_tip = params.name;
 	params.participant_id = item->getUUID();
 	
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
index 60015576b5..b00e8aaeee 100755
--- a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -2,7 +2,7 @@
 <conversation_view_participant
   folder_arrow_image="ForSale_Badge"
   folder_indentation="8"
-  item_height="20" 
+  item_height="24" 
   item_top_pad="4"
   selection_image="Rounded_Square"
   mouse_opaque="true"
@@ -10,11 +10,9 @@
 >
 <info_button
 	 follows="right"
-	 auto_update="true"
      height="16"
      image_pressed="Info_Press"
      image_unselected="Info_Over"
-     layout="topleft"
      right="-28"
      name="info_btn"
      width="16" />
@@ -23,7 +21,6 @@
 	auto_update="true"
 	draw_border="false"
 	height="16"
-	layout="topleft"
 	right="-3"
 	mouse_opaque="true"
 	name="speaking_indicator"
-- 
cgit v1.2.3


From 9b0d627a06a817fc11edc4c6c718f1114aa7cfcf Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 14 Sep 2012 19:47:52 -0700
Subject: CHUI-192 : Implement menus and settings for sorting. The sort itself
 is not performed though. Wait for CHUI-340 for this.

---
 indra/newview/app_settings/settings.xml            | 11 +++
 indra/newview/llconversationmodel.h                | 23 ++++--
 indra/newview/llimfloatercontainer.cpp             | 89 ++++++++++++++++++++++
 indra/newview/llimfloatercontainer.h               |  4 +
 .../skins/default/xui/en/menu_participant_view.xml | 70 +++++++++++++++++
 5 files changed, 190 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 593381cb29..9ada5e5918 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1683,6 +1683,17 @@
       <key>Value</key>
       <integer>100</integer>
     </map>
+    <key>ConversationSortOrder</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies sort key for conversations</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>131073</integer>
+    </map>
     <key>NearbyChatIsNotTornOff</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index c340194dd3..ef1903ab19 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -170,10 +170,14 @@ public:
 		
 	enum ESortOrderType
 	{
-		SO_NAME = 0,						// Sort inventory by name
-		SO_DATE = 0x1,						// Sort inventory by date
+		SO_NAME = 0,						// Sort by name
+		SO_DATE = 0x1,						// Sort by date (most recent)
+		SO_SESSION_TYPE = 0x2,				// Sort by type (valid only for sessions)
+		SO_DISTANCE = 0x3,					// Sort by distance (valid only for participants in nearby chat)
 	};
-
+	// Default sort order is by type for sessions and by date for participants
+	static const U32 SO_DEFAULT = (SO_SESSION_TYPE << 16) | (SO_DATE);
+	
 	LLConversationFilter() { mEmpty = ""; }
 	~LLConversationFilter() {}
 		
@@ -211,13 +215,18 @@ private:
 class LLConversationSort
 {
 public:
-	LLConversationSort(U32 order = 0) : mSortOrder(order) { }
-	
-	bool isByDate() const { return (mSortOrder & LLConversationFilter::SO_DATE); }
-	U32 getSortOrder() const { return mSortOrder; }
+	LLConversationSort(U32 order = LLConversationFilter::SO_DEFAULT) : mSortOrder(order) { }
 	
+	// 16 LSB bits used for participants, 16 MSB bits for sessions
+	U32 getSortOrderSessions() const { return ((mSortOrder >> 16) & 0xFFFF); }
+	U32 getSortOrderParticipants() const { return (mSortOrder & 0xFFFF); }
+	void setSortOrderSessions(LLConversationFilter::ESortOrderType session) { mSortOrder = ((session & 0xFFFF) << 16) | (mSortOrder & 0xFFFF); }
+	void setSortOrderParticipants(LLConversationFilter::ESortOrderType participant) { mSortOrder = (mSortOrder & 0xFFFF0000) | (participant & 0xFFFF); }
+
 	bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
+	operator U32() const { return mSortOrder; }
 private:
+	// Note: we're treating this value as a sort order bitmask as done in other places in the code (e.g. inventory)
 	U32  mSortOrder;
 };
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 81dddfaa70..ab4b64471b 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -58,6 +58,7 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 	mInitialized(false)
 {
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLIMFloaterContainer::onCustomAction,  this, _2));
+	mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLIMFloaterContainer::isActionChecked, this, _2));
 
 	// Firstly add our self to IMSession observers, so we catch session events
     LLIMMgr::getInstance()->addSessionObserver(this);
@@ -169,6 +170,9 @@ BOOL LLIMFloaterContainer::postBuild()
         mConversationsPane->handleReshape(list_size, TRUE);
 	}
 
+	// Init the sort order now that the root had been created
+	setSortOrder(LLConversationSort(gSavedSettings.getU32("ConversationSortOrder")));
+	
 	mInitialized = true;
 
 	// Add callback: we'll take care of view updates on idle
@@ -546,6 +550,30 @@ void LLIMFloaterContainer::onCustomAction(const LLSD& userdata)
 {
 	std::string command = userdata.asString();
 
+	if ("sort_sessions_by_type" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_SESSION_TYPE);
+	}
+	if ("sort_sessions_by_name" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_NAME);
+	}
+	if ("sort_sessions_by_recent" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_name" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_NAME);
+	}
+	if ("sort_participants_by_recent" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_distance" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_DISTANCE);
+	}
 	if ("chat_preferences" == command)
 	{
 		LLFloaterPreference* floater_prefs = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
@@ -561,6 +589,67 @@ void LLIMFloaterContainer::onCustomAction(const LLSD& userdata)
 	}
 }
 
+BOOL LLIMFloaterContainer::isActionChecked(const LLSD& userdata)
+{
+	LLConversationSort order = mConversationViewModel.getSorter();
+	std::string command = userdata.asString();
+	if ("sort_sessions_by_type" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_SESSION_TYPE);
+	}
+	if ("sort_sessions_by_name" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_NAME);
+	}
+	if ("sort_sessions_by_recent" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_name" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_NAME);
+	}
+	if ("sort_participants_by_recent" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_distance" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE);
+	}
+	
+	return FALSE;
+}
+
+void LLIMFloaterContainer::setSortOrderSessions(const LLConversationFilter::ESortOrderType order)
+{
+	LLConversationSort old_order = mConversationViewModel.getSorter();
+	if (order != old_order.getSortOrderSessions())
+	{
+		old_order.setSortOrderSessions(order);
+		setSortOrder(old_order);
+	}
+}
+
+void LLIMFloaterContainer::setSortOrderParticipants(const LLConversationFilter::ESortOrderType order)
+{
+	LLConversationSort old_order = mConversationViewModel.getSorter();
+	if (order != old_order.getSortOrderParticipants())
+	{
+		old_order.setSortOrderParticipants(order);
+		setSortOrder(old_order);
+	}
+}
+
+void LLIMFloaterContainer::setSortOrder(const LLConversationSort& order)
+{
+	mConversationViewModel.setSorter(order);
+	mConversationsRoot->arrangeAll();
+	// try to keep selection onscreen, even if it wasn't to start with
+	mConversationsRoot->scrollToShowSelection();
+	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
+}
+
 void LLIMFloaterContainer::repositioningWidgets()
 {
 	if (!mInitialized)
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index f6048bed37..1f526091bb 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -105,7 +105,11 @@ private:
 	void onAddButtonClicked();
 	void onAvatarPicked(const uuid_vec_t& ids);
 
+	BOOL isActionChecked(const LLSD& userdata);
 	void onCustomAction (const LLSD& userdata);
+	void setSortOrderSessions(const LLConversationFilter::ESortOrderType order);
+	void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order);
+	void setSortOrder(const LLConversationSort& order);
 
 	LLButton* mExpandCollapseBtn;
 	LLLayoutPanel* mMessagesPane;
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index df2700c94c..0043c14479 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -2,6 +2,76 @@
 <toggleable_menu
  layout="topleft"
  name="participant_manu_view">
+    <menu_item_check
+     label="Sort conversations by type"
+     layout="topleft"
+     name="sort_sessions_by_type">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_sessions_by_type" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_sessions_by_type" />
+    </menu_item_check>
+    <menu_item_check
+     label="Sort conversations by name"
+     layout="topleft"
+     name="sort_sessions_by_name">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_sessions_by_name" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_sessions_by_name" />
+    </menu_item_check>
+    <menu_item_check
+     label="Sort conversations by recent activity"
+     layout="topleft"
+     name="sort_sessions_by_recent">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_sessions_by_recent" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_sessions_by_recent" />
+    </menu_item_check>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_check
+     label="Sort participants by name"
+     layout="topleft"
+     name="sort_participants_by_name">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_participants_by_name" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_participants_by_name" />
+    </menu_item_check>
+    <menu_item_check
+     label="Sort participants by recent activity"
+     layout="topleft"
+     name="sort_participants_by_recent">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_participants_by_recent" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_participants_by_recent" />
+    </menu_item_check>
+    <menu_item_check
+     label="Sort participants by distance from you"
+     layout="topleft"
+     name="sort_participants_by_distance">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_participants_by_distance" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_participants_by_distance" />
+    </menu_item_check>
+    <menu_item_separator
+     layout="topleft" />
     <menu_item_call
          label="Chat preferences..."
          name="chat_preferences">
-- 
cgit v1.2.3


From d22c8510b19f12e81dc68562de45c2c364036440 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 17 Sep 2012 17:53:17 -0700
Subject: CHUI-340 : WIP : Sorting implemented. Type and name work. Date and
 distance still need the relevant values to be computed.

---
 indra/newview/llconversationmodel.cpp  | 70 ++++++++++++++++++++++++++++++----
 indra/newview/llconversationmodel.h    | 17 +++++++++
 indra/newview/llimfloatercontainer.cpp |  1 -
 indra/newview/llparticipantlist.cpp    | 21 ++++++++++
 4 files changed, 101 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index c36c3cbc65..612744c3e9 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -37,7 +37,8 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(display_name),
 	mUUID(uuid),
-	mNeedsRefresh(true)
+	mNeedsRefresh(true),
+	mConvType(CONV_UNKNOWN)
 {
 }
 
@@ -45,7 +46,8 @@ LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInte
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
 	mUUID(uuid),
-	mNeedsRefresh(true)
+	mNeedsRefresh(true),
+	mConvType(CONV_UNKNOWN)
 {
 }
 
@@ -53,7 +55,8 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
 	mUUID(),
-	mNeedsRefresh(true)
+	mNeedsRefresh(true),
+	mConvType(CONV_UNKNOWN)
 {
 }
 
@@ -86,11 +89,13 @@ LLConversationItemSession::LLConversationItemSession(std::string display_name, c
 	LLConversationItem(display_name,uuid,root_view_model),
 	mIsLoaded(false)
 {
+	mConvType = CONV_SESSION_UNKNOWN;
 }
 
 LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(uuid,root_view_model)
 {
+	mConvType = CONV_SESSION_UNKNOWN;
 }
 
 bool LLConversationItemSession::hasChildren() const
@@ -183,11 +188,13 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 	mIsMuted(false),
 	mIsModerator(false)
 {
+	mConvType = CONV_PARTICIPANT;
 }
 
 LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(uuid,root_view_model)
 {
+	mConvType = CONV_PARTICIPANT;
 }
 
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
@@ -212,11 +219,60 @@ void LLConversationItemParticipant::dumpDebugData()
 
 bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
 {
-	// For the moment, we sort only by name
-	// *TODO : Implement the sorting by date as well (most recent first)
-	// *TODO : Check the type of item (session/participants) as order should be different for both (eventually)
+	LLConversationItem::EConversationType type_a = a->getType();
+	LLConversationItem::EConversationType type_b = b->getType();
+
+	if ((type_a == LLConversationItem::CONV_PARTICIPANT) && (type_b == LLConversationItem::CONV_PARTICIPANT))
+	{
+		// If both are participants
+		U32 sort_order = getSortOrderParticipants();
+		if (sort_order == LLConversationFilter::SO_DATE)
+		{
+			F32 time_a = 0.0;
+			F32 time_b = 0.0;
+			if (a->getTime(time_a) && b->getTime(time_b))
+			{
+				return (time_a > time_b);
+			}
+		}
+		else if (sort_order == LLConversationFilter::SO_DISTANCE)
+		{
+			F32 dist_a = 0.0;
+			F32 dist_b = 0.0;
+			if (a->getDistanceToAgent(dist_a) && b->getDistanceToAgent(dist_b))
+			{
+				return (dist_a > dist_b);
+			}
+		}
+	}
+	else if ((type_a > LLConversationItem::CONV_PARTICIPANT) && (type_b > LLConversationItem::CONV_PARTICIPANT))
+	{
+		// If both are sessions
+		U32 sort_order = getSortOrderSessions();
+		if (sort_order == LLConversationFilter::SO_DATE)
+		{
+			F32 time_a = 0.0;
+			F32 time_b = 0.0;
+			if (a->getTime(time_a) && b->getTime(time_b))
+			{
+				return (time_a > time_b);
+			}
+		}
+		else if (sort_order == LLConversationFilter::SO_SESSION_TYPE)
+		{
+			return (type_a < type_b);
+		}
+	}
+	else
+	{
+		// If one is a participant and the other a session, the session is always "less" than the participant
+		// so we simply compare the type
+		// Notes: as a consequence, CONV_UNKNOWN (which should never get created...) always come first
+		return (type_a < type_b);
+	}
+	// By default, in all other possible cases (including sort order of type LLConversationFilter::SO_NAME of course), sort by name
 	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
-	return (compare < 0);	
+	return (compare < 0);
 }
 
 //
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index ef1903ab19..954543f91a 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -46,6 +46,17 @@ typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
 class LLConversationItem : public LLFolderViewModelItemCommon
 {
 public:
+	enum EConversationType
+	{
+		CONV_UNKNOWN         = 0,
+		CONV_PARTICIPANT     = 1,
+		CONV_SESSION_NEARBY  = 2,	// The order counts here as it is used to sort sessions by type
+		CONV_SESSION_1_ON_1  = 3,
+		CONV_SESSION_AD_HOC  = 4,
+		CONV_SESSION_GROUP   = 5,
+		CONV_SESSION_UNKNOWN = 6
+	};
+	
 	LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItem(LLFolderViewModelInterface& root_view_model);
@@ -93,6 +104,11 @@ public:
 	virtual void selectItem(void) { } 
 	virtual void showProperties(void);
 
+	// Methods used in sorting (see LLConversationSort::operator()
+	EConversationType const getType() const { return mConvType; }
+	virtual const bool getTime(F32& time) const { return false; }
+	virtual const bool getDistanceToAgent(F32& distance) const { return false; }
+	
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
 	// requested. 
@@ -111,6 +127,7 @@ public:
 protected:
 	std::string mName;	// Name of the session or the participant
 	LLUUID mUUID;		// UUID of the session or the participant
+	EConversationType mConvType;	// Type of conversation item
 	bool mNeedsRefresh;	// Flag signaling to the view that something changed for this item
 };
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index ab4b64471b..76bd6b14b9 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -740,7 +740,6 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 		llwarns << "Couldn't create conversation session item : " << display_name << llendl;
 		return;
 	}
-	// *TODO: Should we flag LLConversationItemSession with a mIsNearbyChat?
 	item->renameItem(display_name);
 	
 	mConversationsItems[uuid] = item;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 0d1a37c835..339cee3f95 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -280,6 +280,27 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 	}
 	// we need to exclude agent id for non group chat
 	sort();
+	
+	// Identify and store what kind of session we are
+	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(data_source->getSessionID());
+	if (im_session)
+	{
+		// By default, sessions that can't be identified as group or ad-hoc will be considered P2P (i.e. 1 on 1)
+		mConvType = CONV_SESSION_1_ON_1;
+		if (im_session->isAdHocSessionType())
+		{
+			mConvType = CONV_SESSION_AD_HOC;
+		}
+		else if (im_session->isGroupSessionType())
+		{
+			mConvType = CONV_SESSION_GROUP;
+		}
+	}
+	else 
+	{
+		// That's the only session that doesn't get listed in the LLIMModel as a session...
+		mConvType = CONV_SESSION_NEARBY;
+	}
 }
 
 LLParticipantList::~LLParticipantList()
-- 
cgit v1.2.3


From a3607a8d8c86b2c25bfa0abda1b0fc9b00f2c099 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 18 Sep 2012 16:41:37 +0300
Subject: CHUI-339 FIXED (2 entries shown in conversation log for ad hoc
 conference for user that starts the conference)

---
 indra/newview/llconversationlog.cpp | 35 ++++++++++++++++++++++-------------
 indra/newview/llconversationlog.h   |  8 ++++----
 indra/newview/llimview.cpp          | 21 +++++++++++++++++----
 indra/newview/llimview.h            |  6 ++++--
 4 files changed, 47 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 27be2bc5ae..44bee70427 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -75,7 +75,7 @@ LLConversation::LLConversation(const LLIMModel::LLIMSession& session)
 	mConversationType(session.mSessionType),
 	mConversationName(session.mName),
 	mHistoryFileName(session.mHistoryFileName),
-	mSessionID(session.mSessionID),
+	mSessionID(session.isOutgoingAdHoc() ? session.generateOutgouigAdHocHash() : session.mSessionID),
 	mParticipantID(session.mOtherParticipantID),
 	mIsVoice(session.mStartedAsIMCall),
 	mHasOfflineIMs(session.mHasOfflineMessage)
@@ -231,8 +231,8 @@ void LLConversationLog::enableLogging(bool enable)
 
 void LLConversationLog::logConversation(const LLUUID& session_id)
 {
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
-	LLConversation* conversation = findConversation(session_id);
+	const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
+	LLConversation* conversation = findConversation(session);
 
 	if (session && conversation)
 	{
@@ -240,14 +240,12 @@ void LLConversationLog::logConversation(const LLUUID& session_id)
 	}
 	else if (session && !conversation)
 	{
-		createConversation(session_id);
+		createConversation(session);
 	}
 }
 
-void LLConversationLog::createConversation(const LLUUID& session_id)
+void LLConversationLog::createConversation(const LLIMModel::LLIMSession* session)
 {
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
-
 	if (session)
 	{
 		LLConversation conversation(*session);
@@ -262,14 +260,18 @@ void LLConversationLog::createConversation(const LLUUID& session_id)
 	}
 }
 
-void LLConversationLog::updateConversationName(const LLUUID& session_id, const std::string& name)
+void LLConversationLog::updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name)
 {
-	LLConversation* conversation = findConversation(session_id);
+	if (!session)
+	{
+		return;
+	}
 
+	LLConversation* conversation = findConversation(session);
 	if (conversation)
 	{
 		conversation->setConverstionName(name);
-		notifyPrticularConversationObservers(session_id, LLConversationLogObserver::CHANGED_NAME);
+		notifyPrticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME);
 	}
 }
 
@@ -282,8 +284,15 @@ void LLConversationLog::updateConversationTimestamp(LLConversation* conversation
 	}
 }
 
-LLConversation* LLConversationLog::findConversation(const LLUUID& session_id)
+LLConversation* LLConversationLog::findConversation(const LLIMModel::LLIMSession* session)
 {
+	if (!session)
+	{
+		return NULL;
+	}
+
+	const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
+
 	conversations_vec_t::iterator conv_it = mConversations.begin();
 	for(; conv_it != mConversations.end(); ++conv_it)
 	{
@@ -489,7 +498,7 @@ void LLConversationLog::onNewMessageReceived(const LLSD& data)
 	logConversation(session_id);
 }
 
-void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session)
+void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session)
 {
-	updateConversationName(session->mSessionID, av_name.getCompleteName());
+	updateConversationName(session, av_name.getCompleteName());
 }
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index a458e975bb..6fff7d6772 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -162,13 +162,13 @@ private:
 	bool saveToFile(const std::string& filename);
 	bool loadFromFile(const std::string& filename);
 
-	void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, LLIMModel::LLIMSession* session);
+	void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session);
 
-	void createConversation(const LLUUID& session_id);
+	void createConversation(const LLIMModel::LLIMSession* session);
 	void updateConversationTimestamp(LLConversation* conversation);
-	void updateConversationName(const LLUUID& session_id, const std::string& name);
+	void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name);
 
-	LLConversation* findConversation(const LLUUID& session_id);
+	LLConversation* findConversation(const LLIMModel::LLIMSession* session);
 
 	typedef std::vector<LLConversation> conversations_vec_t;
 	std::vector<LLConversation>				mConversations;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index f5392b442a..b45903835a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -536,7 +536,7 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids)
 	return NULL;
 }
 
-bool LLIMModel::LLIMSession::isOutgoingAdHoc()
+bool LLIMModel::LLIMSession::isOutgoingAdHoc() const
 {
 	return IM_SESSION_CONFERENCE_START == mType;
 }
@@ -556,6 +556,19 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
 	return !mOtherParticipantIsAvatar;
 }
 
+LLUUID LLIMModel::LLIMSession::generateOutgouigAdHocHash() const
+{
+	LLUUID hash = LLUUID::null;
+
+	if (mInitialTargetIDs.size())
+	{
+		std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
+		hash = generateHash(sorted_uuids);
+	}
+
+	return hash;
+}
+
 void LLIMModel::LLIMSession::buildHistoryFileName()
 {
 	mHistoryFileName = mName;
@@ -572,7 +585,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 		if (mInitialTargetIDs.size())
 		{
 			std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
-			mHistoryFileName = mName + " hash" + generateHash(sorted_uuids);
+			mHistoryFileName = mName + " hash" + generateHash(sorted_uuids).asString();
 		}
 		else
 		{
@@ -606,7 +619,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 }
 
 //static
-std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
+LLUUID LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
 {
 	LLMD5 md5_uuid;
 	
@@ -620,7 +633,7 @@ std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_
 
 	LLUUID participants_md5_hash;
 	md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData);
-	return participants_md5_hash.asString();
+	return participants_md5_hash;
 }
 
 void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index fa9d20ca53..82cfa394a6 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -85,7 +85,7 @@ public:
 		/** @deprecated */
 		static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
 
-		bool isOutgoingAdHoc();
+		bool isOutgoingAdHoc() const;
 		bool isAdHoc();
 		bool isP2P();
 		bool isOtherParticipantAvaline();
@@ -95,6 +95,8 @@ public:
 		bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
 		bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
 
+		LLUUID generateOutgouigAdHocHash() const;
+
 		//*TODO make private
 		/** ad-hoc sessions involve sophisticated chat history file naming schemes */
 		void buildHistoryFileName();
@@ -139,7 +141,7 @@ public:
 	private:
 		void onAdHocNameCache(const LLAvatarName& av_name);
 
-		static std::string generateHash(const std::set<LLUUID>& sorted_uuids);
+		static LLUUID generateHash(const std::set<LLUUID>& sorted_uuids);
 	};
 	
 
-- 
cgit v1.2.3


From 3fb222e939de7ef71630c5754d964fb81e08fce1 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Tue, 18 Sep 2012 18:07:16 +0300
Subject: CHUI-348 FIXED (Voice call icon still shows in conversation log)

- Removed code responsible for showing voice icon
---
 indra/newview/llconversationlog.cpp         | 18 ++++++------------
 indra/newview/llconversationlog.h           |  5 +----
 indra/newview/llconversationloglistitem.cpp | 12 ++----------
 3 files changed, 9 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 44bee70427..7a5a476efb 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -36,8 +36,7 @@ struct Conversation_params
 {
 	Conversation_params(time_t time)
 	:	mTime(time),
-		mTimestamp(LLConversation::createTimestamp(time)),
-		mIsVoice(false)
+		mTimestamp(LLConversation::createTimestamp(time))
 	{}
 
 	time_t		mTime;
@@ -47,7 +46,6 @@ struct Conversation_params
 	std::string	mHistoryFileName;
 	LLUUID		mSessionID;
 	LLUUID		mParticipantID;
-	bool		mIsVoice;
 	bool		mHasOfflineIMs;
 };
 
@@ -63,7 +61,6 @@ LLConversation::LLConversation(const Conversation_params& params)
 	mHistoryFileName(params.mHistoryFileName),
 	mSessionID(params.mSessionID),
 	mParticipantID(params.mParticipantID),
-	mIsVoice(params.mIsVoice),
 	mHasOfflineIMs(params.mHasOfflineIMs)
 {
 	setListenIMFloaterOpened();
@@ -77,7 +74,6 @@ LLConversation::LLConversation(const LLIMModel::LLIMSession& session)
 	mHistoryFileName(session.mHistoryFileName),
 	mSessionID(session.isOutgoingAdHoc() ? session.generateOutgouigAdHocHash() : session.mSessionID),
 	mParticipantID(session.mOtherParticipantID),
-	mIsVoice(session.mStartedAsIMCall),
 	mHasOfflineIMs(session.mHasOfflineMessage)
 {
 	setListenIMFloaterOpened();
@@ -92,7 +88,6 @@ LLConversation::LLConversation(const LLConversation& conversation)
 	mHistoryFileName	= conversation.getHistoryFileName();
 	mSessionID			= conversation.getSessionID();
 	mParticipantID		= conversation.getParticipantID();
-	mIsVoice			= conversation.isVoice();
 	mHasOfflineIMs		= conversation.hasOfflineMessages();
 
 	setListenIMFloaterOpened();
@@ -147,12 +142,11 @@ void LLConversation::setListenIMFloaterOpened()
 {
 	LLIMFloater* floater = LLIMFloater::findInstance(mSessionID);
 
-	bool has_offline_ims = !mIsVoice && mHasOfflineIMs;
 	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 && !offline_ims_visible)
+	if (mHasOfflineIMs && !offline_ims_visible)
 	{
 		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
 	}
@@ -393,7 +387,7 @@ bool LLConversationLog::saveToFile(const std::string& filename)
 		fprintf(fp, "[%d] %d %d %d %s| %s %s %s|\n",
 				(S32)conv_it->getTime(),
 				(S32)conv_it->getConversationType(),
-				(S32)conv_it->isVoice(),
+				(S32)0,
 				(S32)conv_it->hasOfflineMessages(),
 				     conv_it->getConversationName().c_str(),
 				participant_id.c_str(),
@@ -423,10 +417,11 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	char part_id_buffer[MAX_STRING];
 	char conv_id_buffer[MAX_STRING];
 	char history_file_name[MAX_STRING];
-	int is_voice;
 	int has_offline_ims;
 	int stype;
 	S32 time;
+	// before CHUI-348 it was a flag of conversation voice state
+	int prereserved_unused;
 
 	while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
 	{
@@ -437,7 +432,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 		sscanf(buffer, "[%d] %d %d %d %[^|]| %s %s %[^|]|",
 				&time,
 				&stype,
-				&is_voice,
+				&prereserved_unused,
 				&has_offline_ims,
 				conv_name_buffer,
 				part_id_buffer,
@@ -446,7 +441,6 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 
 		Conversation_params params(time);
 		params.mConversationType = (SessionType)stype;
-		params.mIsVoice = is_voice;
 		params.mHasOfflineIMs = has_offline_ims;
 		params.mConversationName = std::string(conv_name_buffer);
 		params.mParticipantID = LLUUID(part_id_buffer);
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 6fff7d6772..373406aa6f 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -56,11 +56,9 @@ public:
 	const LLUUID&		getParticipantID()		const	{ return mParticipantID; }
 	const std::string&	getTimestamp()			const	{ return mTimestamp; }
 	const time_t&		getTime()				const	{ return mTime; }
-	bool				isVoice()				const	{ return mIsVoice; }
 	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }
 
-	void	setIsVoice(bool is_voice);
-	void	setConverstionName(std::string conv_name) { mConversationName = conv_name; }
+	void setConverstionName(std::string conv_name) { mConversationName = conv_name; }
 
 	bool isOlderThan(U32 days) const;
 
@@ -95,7 +93,6 @@ private:
 	std::string		mHistoryFileName;
 	LLUUID			mSessionID;
 	LLUUID			mParticipantID;
-	bool			mIsVoice;
 	bool			mHasOfflineIMs;
 	std::string		mTimestamp; // last interaction time in form of: mm/dd/yyyy hh:mm
 };
diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
index fac6130371..b4ae5f19da 100644
--- a/indra/newview/llconversationloglistitem.cpp
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -49,10 +49,9 @@ LLConversationLogListItem::LLConversationLogListItem(const LLConversation* conve
 
 	LLIMFloater* floater = LLIMFloater::findInstance(mConversation->getSessionID());
 
-	bool has_offline_ims = !mConversation->isVoice() && mConversation->hasOfflineMessages();
 	bool ims_are_read = LLIMFloater::isVisible(floater) && floater->hasFocus();
 
-	if (has_offline_ims && !ims_are_read)
+	if (mConversation->hasOfflineMessages() && !ims_are_read)
 	{
 		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
 	}
@@ -104,16 +103,9 @@ void LLConversationLogListItem::initIcons()
 			break;
 	}
 
-	if (mConversation->isVoice())
+	if (mConversation->hasOfflineMessages())
 	{
-		getChild<LLIconCtrl>("voice_session_icon")->setVisible(TRUE);
-	}
-	else
-	{
-		if (mConversation->hasOfflineMessages())
-		{
 			getChild<LLIconCtrl>("unread_ims_icon")->setVisible(TRUE);
-		}
 	}
 }
 
-- 
cgit v1.2.3


From 3c8407f32cf947ee1631ed66bba7a676e8b3b670 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 18 Sep 2012 12:15:51 -0700
Subject: CHUI-283: Now the avatar icon loads in the user's avatar image.Also
 the avatar image is of proper size. The participant of the conversation is
 offset correctly as well.

---
 indra/llcommon/llfoldertype.h                      |   4 +-
 indra/llui/llfolderviewitem.cpp                    | 230 +++++++++++----------
 indra/llui/llfolderviewitem.h                      |   3 +
 indra/newview/llconversationmodel.h                |   2 +-
 indra/newview/llconversationview.cpp               |  50 ++++-
 indra/newview/llconversationview.h                 |   6 +-
 indra/newview/llviewerfoldertype.cpp               |   2 -
 .../default/xui/en/floater_pathfinding_console.xml |   2 +-
 .../en/widgets/conversation_view_participant.xml   |   8 +-
 9 files changed, 185 insertions(+), 122 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h
index 609b550900..a0c847914f 100755
--- a/indra/llcommon/llfoldertype.h
+++ b/indra/llcommon/llfoldertype.h
@@ -89,9 +89,7 @@ public:
 
 		FT_COUNT,
 
-		FT_NONE = -1,
-
-        FT_PROFILEXXXGGG = 58
+		FT_NONE = -1
 	};
 
 	static EType 				lookup(const std::string& type_name);
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 7ca02b726a..5fcb1f51d1 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -105,6 +105,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mSelectPending(FALSE),
 	mLabelStyle( LLFontGL::NORMAL ),
 	mHasVisibleChildren(FALSE),
+    mLocalIndentation(p.folder_indentation),
 	mIndentation(0),
 	mItemHeight(p.item_height),
 	mControlLabelRotation(0.f),
@@ -284,11 +285,9 @@ void LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 // makes sure that this view and its children are the right size.
 S32 LLFolderViewItem::arrange( S32* width, S32* height )
 {
-	const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-	S32 indentation = p.folder_indentation();
 	// Only indent deeper items in hierarchy
 	mIndentation = (getParentFolder())
-		? getParentFolder()->getIndentation() + indentation
+		? getParentFolder()->getIndentation() + mLocalIndentation
 		: 0;
 	if (mLabelWidthDirty)
 	{
@@ -596,24 +595,134 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	return handled;
 }
 
+void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, 
+                                                        const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
+{
+
+    //--------------------------------------------------------------------------------//
+    // Draw highlight for selected items
+    //
+
+    const S32 focus_top = getRect().getHeight();
+    const S32 focus_bottom = getRect().getHeight() - mItemHeight;
+    const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
+    const S32 FOCUS_LEFT = 1;
+
+    if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE
+    {
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+        LLColor4 bg_color = bgColor;
+        if (!mIsCurSelection)
+        {
+            // do time-based fade of extra objects
+            F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
+            if (getRoot() && getRoot()->getShowSingleSelection())
+            {
+                // fading out
+                bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
+            }
+            else
+            {
+                // fading in
+                bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
+            }
+        }
+        gl_rect_2d(FOCUS_LEFT,
+            focus_top, 
+            getRect().getWidth() - 2,
+            focus_bottom,
+            bg_color, hasKeyboardFocus);
+        if (mIsCurSelection)
+        {
+            gl_rect_2d(FOCUS_LEFT, 
+                focus_top, 
+                getRect().getWidth() - 2,
+                focus_bottom,
+                focusOutlineColor, FALSE);
+        }
+        if (folder_open)
+        {
+            gl_rect_2d(FOCUS_LEFT,
+                focus_bottom + 1, // overlap with bottom edge of above rect
+                getRect().getWidth() - 2,
+                0,
+                focusOutlineColor, FALSE);
+            if (showContent)
+            {
+                gl_rect_2d(FOCUS_LEFT,
+                    focus_bottom + 1,
+                    getRect().getWidth() - 2,
+                    0,
+                    bgColor, TRUE);
+            }
+        }
+    }
+    else if (mIsMouseOverTitle)
+    {
+        gl_rect_2d(FOCUS_LEFT,
+            focus_top, 
+            getRect().getWidth() - 2,
+            focus_bottom,
+            mouseOverColor, FALSE);
+    }
+
+    //--------------------------------------------------------------------------------//
+    // Draw DragNDrop highlight
+    //
+    if (mDragAndDropTarget)
+    {
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+        gl_rect_2d(FOCUS_LEFT, 
+            focus_top, 
+            getRect().getWidth() - 2,
+            focus_bottom,
+            bgColor, FALSE);
+        if (folder_open)
+        {
+            gl_rect_2d(FOCUS_LEFT,
+                focus_bottom + 1, // overlap with bottom edge of above rect
+                getRect().getWidth() - 2,
+                0,
+                bgColor, FALSE);
+        }
+        mDragAndDropTarget = FALSE;
+    }
+}
+
+void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 right_x)
+{
+    //TODO RN: implement this in terms of getColor()
+    //if (highlight_link) color = sLinkColor;
+    //if (gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
+
+    //--------------------------------------------------------------------------------//
+    // Draw the actual label text
+    //
+    font->renderUTF8(mLabel, 0, x, y, color,
+        LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+        S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, TRUE);
+}
+
 void LLFolderViewItem::draw()
 {
 	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
-	static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+    static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+    static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+    static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+    static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);	
 	static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
 	static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
 	static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
 	static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
 	static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
 	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
-	static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
-
+	
+    const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+    const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
 
 	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	const S32 TOP_PAD = default_params.item_top_pad;
-	const S32 FOCUS_LEFT = 1;
+	
 	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
     getViewModelItem()->update();
@@ -630,93 +739,7 @@ void LLFolderViewItem::draw()
 	}
 
 
-	//--------------------------------------------------------------------------------//
-	// Draw highlight for selected items
-	//
-	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
-	const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
-	const S32 focus_top = getRect().getHeight();
-	const S32 focus_bottom = getRect().getHeight() - mItemHeight;
-	const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
-	if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		LLColor4 bg_color = sHighlightBgColor;
-		if (!mIsCurSelection)
-		{
-			// do time-based fade of extra objects
-			F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
-			if (getRoot() && getRoot()->getShowSingleSelection())
-			{
-				// fading out
-				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
-			}
-			else
-			{
-				// fading in
-				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
-			}
-		}
-		gl_rect_2d(FOCUS_LEFT,
-				   focus_top, 
-				   getRect().getWidth() - 2,
-				   focus_bottom,
-				   bg_color, filled);
-		if (mIsCurSelection)
-		{
-			gl_rect_2d(FOCUS_LEFT, 
-					   focus_top, 
-					   getRect().getWidth() - 2,
-					   focus_bottom,
-					   sFocusOutlineColor, FALSE);
-		}
-		if (folder_open)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_bottom + 1, // overlap with bottom edge of above rect
-					   getRect().getWidth() - 2,
-					   0,
-					   sFocusOutlineColor, FALSE);
-			if (show_context)
-			{
-				gl_rect_2d(FOCUS_LEFT,
-						   focus_bottom + 1,
-						   getRect().getWidth() - 2,
-						   0,
-						   sHighlightBgColor, TRUE);
-			}
-		}
-	}
-	else if (mIsMouseOverTitle)
-	{
-		gl_rect_2d(FOCUS_LEFT,
-			focus_top, 
-			getRect().getWidth() - 2,
-			focus_bottom,
-			sMouseOverColor, FALSE);
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Draw DragNDrop highlight
-	//
-	if (mDragAndDropTarget)
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gl_rect_2d(FOCUS_LEFT, 
-				   focus_top, 
-				   getRect().getWidth() - 2,
-				   focus_bottom,
-				   sHighlightBgColor, FALSE);
-		if (folder_open)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_bottom + 1, // overlap with bottom edge of above rect
-					   getRect().getWidth() - 2,
-					   0,
-					   sHighlightBgColor, FALSE);
-		}
-		mDragAndDropTarget = FALSE;
-	}
+    drawHighlight(show_context, filled, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
 
 	//--------------------------------------------------------------------------------//
 	// Draw open icon
@@ -760,19 +783,10 @@ void LLFolderViewItem::draw()
 		LLUIImage* box_image = default_params.selection_image;
 		LLRect box_rect(left, top, right, bottom);
 		box_image->draw(box_rect, sFilterBGColor);
-		}
+    }
 
-	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
-	//TODO RN: implement this in terms of getColor()
-	//if (highlight_link) color = sLinkColor;
-	//if (gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
-	
-	//--------------------------------------------------------------------------------//
-	// Draw the actual label text
-	//
-	font->renderUTF8(mLabel, 0, text_left, y, color,
-					 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-					 S32_MAX, getRect().getWidth() - (S32) text_left - mLabelPaddingRight, &right_x, TRUE);
+    LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
+    drawLabel(font, text_left, y, color, right_x);
 
 	//--------------------------------------------------------------------------------//
 	// Draw label suffix
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 7025b94a9a..a9e10c92c9 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -93,6 +93,7 @@ protected:
 	LLUIImagePtr				mIcon,
 								mIconOpen,
 								mIconOverlay;
+    S32                         mLocalIndentation;
 	S32							mIndentation;
 	S32							mItemHeight;
 	S32							mDragStartX,
@@ -235,6 +236,8 @@ public:
 
 	//	virtual void handleDropped();
 	virtual void draw();
+    void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
+    void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 right_x);
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 									EDragAndDropType cargo_type,
 									void* cargo_data,
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index ef1903ab19..49af927acf 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -57,7 +57,7 @@ public:
 	virtual const std::string& getSearchableName() const { return mName; }
 	virtual const LLUUID& getUUID() const { return mUUID; }
 	virtual time_t getCreationDate() const { return 0; }
-	virtual LLPointer<LLUIImage> getIcon() const { return LLUI::getUIImage(LLViewerFolderType::lookupIconName(LLFolderType::FT_PROFILEXXXGGG, FALSE)); }
+	virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
 	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
 	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index d5d4fc13da..721abd5892 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -41,7 +41,7 @@
 //
 static LLDefaultChildRegistry::Register<LLConversationViewSession> r_conversation_view_session("conversation_view_session");
 
-
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
 
 LLConversationViewSession::Params::Params() :	
 	container()
@@ -90,7 +90,6 @@ void LLConversationViewSession::draw()
 
 // *TODO Seth PE: remove the code duplicated from LLFolderViewItem::draw()
 // ***** LLFolderViewItem::draw() code begin *****
-	const LLColor4U DEFAULT_WHITE(255, 255, 255);
 
 	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
 	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
@@ -317,21 +316,27 @@ S32 LLConversationViewParticipant::sChildrenWidths[LLConversationViewParticipant
 LLConversationViewParticipant::Params::Params() :	
 container(),
 participant_id(),
+avatar_icon("avatar_icon"),
 info_button("info_button"),
 output_monitor("output_monitor")
 {}
 
 LLConversationViewParticipant::LLConversationViewParticipant( const LLConversationViewParticipant::Params& p ):
 	LLFolderViewItem(p),
+    mAvatarIcon(NULL),
     mInfoBtn(NULL),
     mSpeakingIndicator(NULL),
     mUUID(p.participant_id)
 {
-
 }
 
 void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params)
 {	
+    LLAvatarIconCtrl::Params avatar_icon_params(params.avatar_icon());
+    applyXUILayout(avatar_icon_params, this);
+    LLAvatarIconCtrl * avatarIcon = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_icon_params);
+    addChild(avatarIcon);	
+
 	LLButton::Params info_button_params(params.info_button());
     applyXUILayout(info_button_params, this);
 	LLButton * button = LLUICtrlFactory::create<LLButton>(info_button_params);
@@ -345,6 +350,8 @@ void LLConversationViewParticipant::initFromParams(const LLConversationViewParti
 
 BOOL LLConversationViewParticipant::postBuild()
 {
+    mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon");
+
 	mInfoBtn = getChild<LLButton>("info_btn");
 	mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
 	mInfoBtn->setVisible(false);
@@ -363,6 +370,36 @@ BOOL LLConversationViewParticipant::postBuild()
 	return LLFolderViewItem::postBuild();
 }
 
+void LLConversationViewParticipant::draw()
+{
+    static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+    static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+    static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+    static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+    static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+
+    const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+    const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
+
+    const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+    const S32 TOP_PAD = default_params.item_top_pad;
+
+    const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+    F32 right_x  = 0;
+
+    //TEXT_PAD, TOP_PAD, ICON_PAD and mIndentation are temporary values and will non-const eventually since they don't
+    //apply to every single layout
+    F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+    F32 text_left = (F32)(mAvatarIcon->getRect().mRight + ICON_PAD + mIndentation);
+    LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
+
+    drawHighlight(show_context, filled, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+    drawLabel(font, text_left, y, color, right_x);
+
+    LLView::draw();
+}
+
+
 void LLConversationViewParticipant::refresh()
 {
 	// Refresh the participant view from its model data
@@ -384,8 +421,11 @@ void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
     LLConversationItem* vmi = this->getParentFolder() ? dynamic_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
     if(vmi)
     {
-        mSpeakingIndicator->setSpeakerId(mUUID, 
-        vmi->getUUID()); //set the session id
+        //Allows speaking icon image to be loaded based on mUUID
+        mAvatarIcon->setValue(mUUID);
+
+        //Allows the speaker indicator to be activated based on the user and conversation
+        mSpeakingIndicator->setSpeakerId(mUUID, vmi->getUUID()); 
     }
 }
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 3dbc36e811..075ad09d5b 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -29,6 +29,7 @@
 
 #include "llfolderviewitem.h"
 
+#include "llavatariconctrl.h"
 #include "llbutton.h"
 #include "lloutputmonitorctrl.h"
 
@@ -84,7 +85,8 @@ public:
 	struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
 	{
         Optional<LLIMFloaterContainer*>			container;
-		Optional<LLUUID>	participant_id;
+		Optional<LLUUID>	                    participant_id;
+        Optional<LLAvatarIconCtrl::Params>	    avatar_icon;
 		Optional<LLButton::Params>				info_button;
         Optional<LLOutputMonitorCtrl::Params>   output_monitor;
 		
@@ -104,10 +106,12 @@ protected:
 	LLConversationViewParticipant( const Params& p );
 	void initFromParams(const Params& params);
 	BOOL postBuild();
+    /*virtual*/ void draw();
 	
 	void onInfoBtnClick();
 
 private:
+    LLAvatarIconCtrl* mAvatarIcon;
 	LLButton * mInfoBtn;
     LLOutputMonitorCtrl* mSpeakingIndicator;
 	LLUUID mUUID;		// UUID of the participant
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index 0a402d8c42..a179b61cff 100755
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -147,8 +147,6 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
 		addEntry((LLFolderType::EType)type, 		new ViewerFolderEntry("New Folder",				"Inv_FolderOpen",		"Inv_FolderClosed",		FALSE,     false));
 	}	
 #endif
-
-    addEntry(LLFolderType::FT_PROFILEXXXGGG, 				new ViewerFolderEntry("Profile",				"Generic_Person",		"Generic_Person",		FALSE,     false, "default"));
 }
 
 bool LLViewerFolderDictionary::initEnsemblesFromFile()
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
index 2629313069..79f2027c31 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
@@ -152,7 +152,7 @@
       </text>
       <check_box
           height="19"
-          label="World"
+          label="Test"
           layout="topleft"
           name="show_world"
           top_pad="4"
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
index b00e8aaeee..7ddcfe3b03 100755
--- a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -1,13 +1,19 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <conversation_view_participant
   folder_arrow_image="ForSale_Badge"
-  folder_indentation="8"
+  folder_indentation="0"
   item_height="24" 
   item_top_pad="4"
   selection_image="Rounded_Square"
   mouse_opaque="true"
   follows="left|top|right"
 >
+<avatar_icon
+	 follows="left"
+     height="20"
+     default_icon_name="Generic_Person"
+     left="50"
+     width="20" />
 <info_button
 	 follows="right"
      height="16"
-- 
cgit v1.2.3


From 86ac47474f42598d3edb65970117b442457f7284 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 18 Sep 2012 15:04:23 -0700
Subject: Regress Fix: After a CHUI 283 commit the inventory items suffix was
 overlapping text. Problem was that a variable storing the width of the text
 was not passed in as a reference, which always resulted in the suffix
 overlapping the prior text.

---
 indra/llui/llfolderviewitem.cpp | 4 ++--
 indra/llui/llfolderviewitem.h   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 5fcb1f51d1..a20ce23b18 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -689,7 +689,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
     }
 }
 
-void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 right_x)
+void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x)
 {
     //TODO RN: implement this in terms of getColor()
     //if (highlight_link) color = sLinkColor;
@@ -797,7 +797,7 @@ void LLFolderViewItem::draw()
 						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
 						  S32_MAX, S32_MAX, &right_x, FALSE );
 	}
-
+    
 	//--------------------------------------------------------------------------------//
 	// Highlight string match
 	//
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index a9e10c92c9..5c97407bc1 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -237,7 +237,7 @@ public:
 	//	virtual void handleDropped();
 	virtual void draw();
     void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
-    void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 right_x);
+    void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 									EDragAndDropType cargo_type,
 									void* cargo_data,
-- 
cgit v1.2.3


From fcb010e835d9b894ba6d1012ac8e3a85c5ab3400 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Wed, 19 Sep 2012 19:20:21 +0300
Subject: CHUI-338 FIXED (LLAvatarNameResponder warning shown in debug console
 when using spinner to page through chat history viewer)

- Trying to restore avatarID by its name before appending message to chat history.
- Also prevented requesting avatar name by null LLUUID in LLAvatarIconCtrl::setValue
---
 indra/newview/llavatariconctrl.cpp                 |  7 ++--
 indra/newview/llfloaterconversationpreview.cpp     | 27 ++++++++++++---
 indra/newview/llnearbychat.cpp                     | 40 +++++++++++-----------
 indra/newview/llnearbychat.h                       |  2 ++
 .../xui/en/floater_conversation_preview.xml        |  2 +-
 5 files changed, 50 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index b539ac38ed..62c6c6763b 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -245,9 +245,10 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
 		LLIconCtrl::setValue(value);
 	}
 
-	LLAvatarNameCache::get(mAvatarId,
-		boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, 
-			this, _1, _2));
+	if (mAvatarId != LLUUID::null)
+	{
+		LLAvatarNameCache::get(mAvatarId, boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, this, _1, _2));
+	}
 }
 
 bool LLAvatarIconCtrl::updateFromCache()
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 88efc39764..a3825eafc8 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -29,6 +29,7 @@
 #include "llfloaterconversationpreview.h"
 #include "llimview.h"
 #include "lllineeditor.h"
+#include "llnearbychat.h"
 #include "llspinctrl.h"
 #include "lltrans.h"
 
@@ -43,7 +44,6 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i
 BOOL LLFloaterConversationPreview::postBuild()
 {
 	mChatHistory = getChild<LLChatHistory>("chat_history");
-	getChild<LLUICtrl>("more_history")->setCommitCallback(boost::bind(&LLFloaterConversationPreview::onMoreHistoryBtnClick, this));
 
 	const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID);
 	std::string name;
@@ -119,20 +119,39 @@ void LLFloaterConversationPreview::showHistory()
 	{
 		LLSD msg = *iter;
 
+		LLUUID from_id 		= LLUUID::null;
 		std::string time	= msg["time"].asString();
-		LLUUID from_id		= msg["from_id"].asUUID();
 		std::string from	= msg["from"].asString();
 		std::string message	= msg["message"].asString();
-		bool is_history		= msg["is_history"].asBoolean();
+
+		if (msg["from_id"].isDefined())
+		{
+			from_id = msg["from_id"].asUUID();
+		}
+		else
+ 		{
+			std::string legacy_name = gCacheName->buildLegacyName(from);
+ 			gCacheName->getUUID(legacy_name, from_id);
+ 		}
 
 		LLChat chat;
 		chat.mFromID = from_id;
 		chat.mSessionID = mSessionID;
 		chat.mFromName = from;
 		chat.mTimeStr = time;
-		chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
+		chat.mChatStyle = CHAT_STYLE_HISTORY;
 		chat.mText = message;
 
+		if (from_id.isNull() && SYSTEM_FROM == from)
+		{
+			chat.mSourceType = CHAT_SOURCE_SYSTEM;
+
+		}
+		else if (from_id.isNull())
+		{
+			chat.mSourceType = LLNearbyChat::isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
+		}
+
 		mChatHistory->appendMessage(chat);
 	}
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a803b35aa8..76626bd5a6 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -69,26 +69,6 @@
 
 S32 LLNearbyChat::sLastSpecialChatChannel = 0;
 
-// --- function in the global namespace :( ---
-bool isWordsName(const std::string& name)
-{
-	// checking to see if it's display name plus username in parentheses
-	S32 open_paren = name.find(" (", 0);
-	S32 close_paren = name.find(')', 0);
-
-	if (open_paren != std::string::npos &&
-		close_paren == name.length()-1)
-	{
-		return true;
-	}
-	else
-	{
-		//checking for a single space
-		S32 pos = name.find(' ', 0);
-		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
-	}
-}
-
 const S32 EXPANDED_HEIGHT = 266;
 const S32 COLLAPSED_HEIGHT = 60;
 const S32 EXPANDED_MIN_HEIGHT = 150;
@@ -717,6 +697,26 @@ void LLNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BO
 	send_chat_from_viewer(utf8_out_text, type, channel);
 }
 
+// static
+bool LLNearbyChat::isWordsName(const std::string& name)
+{
+	// checking to see if it's display name plus username in parentheses
+	S32 open_paren = name.find(" (", 0);
+	S32 close_paren = name.find(')', 0);
+
+	if (open_paren != std::string::npos &&
+		close_paren == name.length()-1)
+	{
+		return true;
+	}
+	else
+	{
+		//checking for a single space
+		S32 pos = name.find(' ', 0);
+		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
+	}
+}
+
 // static 
 void LLNearbyChat::startChat(const char* line)
 {
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 2cbafbfa62..648098113a 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -79,6 +79,8 @@ public:
 	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
 	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
 
+	static bool isWordsName(const std::string& name);
+
 	void showHistory();
 
 protected:
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 0e5af67f68..6f1ddaaf4f 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -52,7 +52,7 @@
      width="50"/>
     <text
      follows="bottom|right"
-     font="SandSerif"
+     font="SansSerif"
      height="22"
      layout="topleft"
      name="page_num_label"
-- 
cgit v1.2.3


From f5fc2a9c3af23cc1aaf74e432eb3690d8d376d89 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 19 Sep 2012 17:59:37 -0700
Subject: CHUI-340 : WIP : Update time stamp for IM and voice utterance

---
 indra/newview/llimfloater.cpp       |  3 +++
 indra/newview/llnearbychat.cpp      |  3 +++
 indra/newview/llparticipantlist.cpp | 21 +++++++++++++++++++++
 indra/newview/llparticipantlist.h   |  9 +++++++++
 indra/newview/llspeakers.cpp        | 17 +++++++++++++++++
 indra/newview/llspeakers.h          |  9 +++++++++
 6 files changed, 62 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 2474fe0891..fbc1b8e7fe 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -907,6 +907,9 @@ void LLIMFloater::updateMessages()
 				chat.mText = message;
 			}
 			
+			// Merov debug
+			llinfos << "Merov debug : LLIMFloater::updateMessages, session = " << mSessionID << ", from = " << msg["from"].asString() << ", uuid = " << msg["from_id"].asString() << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
+
 			appendMessage(chat);
 			mLastMessageIndex = msg["index"].asInteger();
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 76626bd5a6..bf47aa06a8 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -233,6 +233,9 @@ void LLNearbyChat::loadHistory()
  			gCacheName->getUUID(legacy_name, from_id);
  		}
 
+		// Merov debug
+		llinfos << "Merov debug : LLNearbyChat::loadHistory, session = " << mSessionID << ", from = " << msg[IM_FROM].asString() << ", uuid = " << msg[IM_FROM_ID].asString() << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
+
 		LLChat chat;
 		chat.mFromName = from;
 		chat.mFromID = from_id;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 339cee3f95..8bc6bb60cf 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -224,12 +224,14 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 	mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
 	mSpeakerClearListener = new SpeakerClearListener(*this);
 	mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this);
+	mSpeakerUpdateListener = new SpeakerUpdateListener(*this);
 	mSpeakerMuteListener = new SpeakerMuteListener(*this);
 
 	mSpeakerMgr->addListener(mSpeakerAddListener, "add");
 	mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
 	mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
 	mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator");
+	mSpeakerMgr->addListener(mSpeakerUpdateListener, "update_speaker");
 
 	setSessionID(mSpeakerMgr->getSessionID());
 	
@@ -584,6 +586,17 @@ bool LLParticipantList::onClearListEvent(LLPointer<LLOldEvents::LLEvent> event,
 	return true;
 }
 
+bool LLParticipantList::onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+	const LLSD& evt_data = event->getValue();
+	if ( evt_data.has("id") )
+	{
+		LLUUID id = evt_data["id"];
+		llinfos << "Merov debug : onSpeakerUpdateEvent, session = " << mUUID << ", uuid = " << id << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
+	}
+	return true;
+}
+
 bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
 {
 	const LLSD& evt_data = event->getValue();
@@ -745,6 +758,14 @@ bool LLParticipantList::SpeakerClearListener::handleEvent(LLPointer<LLOldEvents:
 	return mParent.onClearListEvent(event, userdata);
 }
 
+//
+// LLParticipantList::SpeakerUpdateListener
+//
+bool LLParticipantList::SpeakerUpdateListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+	return mParent.onSpeakerUpdateEvent(event, userdata);
+}
+
 //
 // LLParticipantList::SpeakerModeratorListener
 //
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index f8165aa292..acee68873c 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -95,6 +95,7 @@ protected:
 	bool onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	bool onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	bool onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+	bool onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	bool onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 
 	/**
@@ -136,6 +137,13 @@ protected:
 		/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	};
 
+	class SpeakerUpdateListener : public BaseSpeakerListener
+	{
+	public:
+		SpeakerUpdateListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
+		/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+	};
+	
 	class SpeakerModeratorUpdateListener : public BaseSpeakerListener
 	{
 	public:
@@ -264,6 +272,7 @@ private:
 	LLPointer<SpeakerAddListener>				mSpeakerAddListener;
 	LLPointer<SpeakerRemoveListener>			mSpeakerRemoveListener;
 	LLPointer<SpeakerClearListener>				mSpeakerClearListener;
+	LLPointer<SpeakerUpdateListener>	        mSpeakerUpdateListener;
 	LLPointer<SpeakerModeratorUpdateListener>	mSpeakerModeratorListener;
 	LLPointer<SpeakerMuteListener>				mSpeakerMuteListener;
 
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 07d2f1ad6f..f50ae28421 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -84,6 +84,19 @@ bool LLSpeaker::isInVoiceChannel()
 	return mStatus <= LLSpeaker::STATUS_VOICE_ACTIVE || mStatus == LLSpeaker::STATUS_MUTED;
 }
 
+LLSpeakerUpdateSpeakerEvent::LLSpeakerUpdateSpeakerEvent(LLSpeaker* source)
+: LLEvent(source, "Speaker update speaker event"),
+mSpeakerID (source->mID)
+{
+}
+
+LLSD LLSpeakerUpdateSpeakerEvent::getValue()
+{
+	LLSD ret;
+	ret["id"] = mSpeakerID;
+	return ret;
+}
+
 LLSpeakerUpdateModeratorEvent::LLSpeakerUpdateModeratorEvent(LLSpeaker* source)
 : LLEvent(source, "Speaker add moderator event"),
   mSpeakerID (source->mID),
@@ -374,6 +387,8 @@ void LLSpeakerMgr::update(BOOL resort_ok)
 				{
 					speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
 					speakerp->mHasSpoken = TRUE;
+					llinfos << "Merov debug : LLSpeakerMgr::update, session = " << getSessionID() << ", uuid = " << speaker_id << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
+					speakerp->fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
 				}
 				speakerp->mStatus = LLSpeaker::STATUS_SPEAKING;
 				// interpolate between active color and full speaking color based on power of speech output
@@ -548,6 +563,8 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id)
 	{
 		speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
 		speakerp->mHasSpoken = TRUE;
+		llinfos << "Merov debug : LLSpeakerMgr::speakerChatted, session = " << getSessionID() << ", uuid = " << speaker_id << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
+		speakerp->fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
 	}
 }
 
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 1c6f51e131..8ab08661d3 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -79,6 +79,15 @@ public:
 	BOOL			mModeratorMutedText;
 };
 
+class LLSpeakerUpdateSpeakerEvent : public LLOldEvents::LLEvent
+{
+public:
+	LLSpeakerUpdateSpeakerEvent(LLSpeaker* source);
+	/*virtual*/ LLSD getValue();
+private:
+	const LLUUID& mSpeakerID;
+};
+
 class LLSpeakerUpdateModeratorEvent : public LLOldEvents::LLEvent
 {
 public:
-- 
cgit v1.2.3


From 5cb0a6221613f1a2f1181cea0fb8bd526ab872bf Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 20 Sep 2012 11:28:10 -0700
Subject: CHUI-353: Regress Bug caused by a CHUI 283 commit. Problem: The font
 was rendering differently due to the folderviewitem::draw() method calling
 llview::draw(). I added llview::draw() initially but it is not longer needed.
 Resolution: Removing the call to llview::draw().

---
 indra/llui/llfolderviewitem.cpp | 3 ---
 1 file changed, 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index a20ce23b18..171af92e73 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -809,9 +809,6 @@ void LLFolderViewItem::draw()
             sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
             filter_string_length, S32_MAX, &right_x, FALSE );
     }
-
-
-    LLView::draw(); 
 }
 
 const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
-- 
cgit v1.2.3


From bb8820c70b6dc50524fa8e35a4a14b3cb66bf26c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 20 Sep 2012 13:22:21 -0700
Subject: CHUI-340 : WIP : Fix the event firing from LLSpeakerMgr to
 LLParticipantList

---
 indra/newview/llspeakers.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index f50ae28421..2d2b5202e0 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -86,7 +86,7 @@ bool LLSpeaker::isInVoiceChannel()
 
 LLSpeakerUpdateSpeakerEvent::LLSpeakerUpdateSpeakerEvent(LLSpeaker* source)
 : LLEvent(source, "Speaker update speaker event"),
-mSpeakerID (source->mID)
+  mSpeakerID (source->mID)
 {
 }
 
@@ -387,8 +387,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
 				{
 					speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
 					speakerp->mHasSpoken = TRUE;
-					llinfos << "Merov debug : LLSpeakerMgr::update, session = " << getSessionID() << ", uuid = " << speaker_id << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
-					speakerp->fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
+					fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
 				}
 				speakerp->mStatus = LLSpeaker::STATUS_SPEAKING;
 				// interpolate between active color and full speaking color based on power of speech output
@@ -563,8 +562,7 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id)
 	{
 		speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
 		speakerp->mHasSpoken = TRUE;
-		llinfos << "Merov debug : LLSpeakerMgr::speakerChatted, session = " << getSessionID() << ", uuid = " << speaker_id << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
-		speakerp->fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
+		fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
 	}
 }
 
-- 
cgit v1.2.3


From 381c13d0e51c3c054fdf2afeff8a8bcb6fc7aa11 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 20 Sep 2012 16:12:28 -0700
Subject: CHUI-283: Refactor of how the layout is determined for
 LLFolderViewItem. Changed constant members that defined the layout to
 non-const member varaibles, which are populated using a .xml file.

---
 indra/llui/llfolderview.cpp                        | 20 ++++---
 indra/llui/llfolderviewitem.cpp                    | 63 ++++++++++++++++------
 indra/llui/llfolderviewitem.h                      | 29 ++++++----
 indra/newview/llconversationview.cpp               | 24 ++++-----
 indra/newview/llconversationview.h                 |  2 +
 .../default/xui/en/panel_outbox_inventory.xml      |  9 +++-
 .../en/widgets/conversation_view_participant.xml   | 11 +++-
 .../xui/en/widgets/conversation_view_session.xml   |  9 +++-
 .../default/xui/en/widgets/folder_view_item.xml    |  8 ++-
 .../xui/en/widgets/inbox_folder_view_folder.xml    |  8 ++-
 10 files changed, 130 insertions(+), 53 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 11004fe390..ab4efea4dd 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -56,11 +56,7 @@
 const S32 RENAME_WIDTH_PAD = 4;
 const S32 RENAME_HEIGHT_PAD = 1;
 const S32 AUTO_OPEN_STACK_DEPTH = 16;
-const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH
-			+ LLFolderViewItem::ICON_PAD 
-			+ LLFolderViewItem::ARROW_SIZE 
-			+ LLFolderViewItem::TEXT_PAD 
-			+ /*first few characters*/ 40;
+
 const S32 MINIMUM_RENAMER_WIDTH = 80;
 
 // *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params.
@@ -211,10 +207,11 @@ LLFolderView::LLFolderView(const Params& p)
 	// Textbox
 	LLTextBox::Params text_p;
 	LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-	LLRect new_r = LLRect(rect.mLeft + ICON_PAD,
-			      rect.mTop - TEXT_PAD,
+    //mIconPad, mTextPad are set in folder_view_item.xml
+	LLRect new_r = LLRect(rect.mLeft + mIconPad,
+			      rect.mTop - mTextPad,
 			      rect.mRight,
-			      rect.mTop - TEXT_PAD - font->getLineHeight());
+			      rect.mTop - mTextPad - font->getLineHeight());
 	text_p.rect(new_r);
 	text_p.name(std::string(p.name));
 	text_p.font(font);
@@ -1652,12 +1649,13 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
 		S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); 
 		S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight(); 
 		// when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
-		S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight(); 
+		S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + item->getIconPad()) : local_rect.getHeight();
 		
 		// get portion of item that we want to see...
 		LLRect item_local_rect = LLRect(item->getIndentation(), 
 										local_rect.getHeight(), 
-										llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()), 
+                                        //+32 is supposed to include few first characters
+										llmin(item->getLabelXPos() + 32, local_rect.getWidth()), 
 										llmax(0, local_rect.getHeight() - max_height_to_show));
 
 		LLRect item_doc_rect;
@@ -1874,7 +1872,7 @@ void LLFolderView::updateRenamerPosition()
 	if(mRenameItem)
 	{
 		// See also LLFolderViewItem::draw()
-		S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mRenameItem->getIndentation();
+		S32 x = mRenameItem->getLabelXPos();
 		S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
 		mRenameItem->localPointToScreen( x, y, &x, &y );
 		screenPointToLocal( x, y, &x, &y );
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 171af92e73..9632612752 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -90,7 +90,14 @@ LLFolderViewItem::Params::Params()
 	item_height("item_height"),
 	item_top_pad("item_top_pad"),
 	creation_date(),
-	allow_open("allow_open", true)
+	allow_open("allow_open", true),
+    left_pad("left_pad", 0),
+    icon_pad("icon_pad", 0),
+    icon_width("icon_width", 0),
+    text_pad("text_pad", 0),
+    text_pad_right("text_pad_right", 0),
+    arrow_size("arrow_size", 0),
+    max_folder_item_overlap("max_folder_item_overlap", 0)
 {}
 
 // Default constructor
@@ -98,7 +105,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 :	LLView(p),
 	mLabelWidth(0),
 	mLabelWidthDirty(false),
-    mLabelPaddingRight(DEFAULT_TEXT_PADDING_RIGHT),
+    mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
 	mParentFolder( NULL ),
 	mIsSelected( FALSE ),
 	mIsCurSelection( FALSE ),
@@ -114,7 +121,14 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mRoot(p.root),
 	mViewModelItem(p.listener),
 	mIsMouseOverTitle(false),
-	mAllowOpen(p.allow_open)
+	mAllowOpen(p.allow_open),
+    mLeftPad(p.left_pad),
+    mIconPad(p.icon_pad),
+    mIconWidth(p.icon_width),
+    mTextPad(p.text_pad),
+    mTextPadRight(p.text_pad_right),
+    mArrowSize(p.arrow_size),
+    mMaxFolderItemOverlap(p.max_folder_item_overlap)
 {
 	if (mViewModelItem)
 	{
@@ -291,11 +305,11 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
 		: 0;
 	if (mLabelWidthDirty)
 	{
-		mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight; 
+		mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight; 
 		mLabelWidthDirty = false;
 	}
 
-	*width = llmax(*width, mLabelWidth + mIndentation); 
+	*width = llmax(*width, mLabelWidth); 
 
 	// determine if we need to use ellipses to avoid horizontal scroll. EXT-719
 	bool use_ellipses = getRoot()->getUseEllipses();
@@ -313,6 +327,21 @@ S32 LLFolderViewItem::getItemHeight()
 	return mItemHeight;
 }
 
+S32 LLFolderViewItem::getLabelXPos()
+{
+    return getIndentation() + mArrowSize + mTextPad + mIconWidth + mIconPad;
+}
+
+S32 LLFolderViewItem::getIconPad()
+{
+    return mIconPad;
+}
+
+S32 LLFolderViewItem::getTextPad()
+{
+    return mTextPad;
+}
+
 // *TODO: This can be optimized a lot by simply recording that it is
 // selected in the appropriate places, and assuming that set selection
 // means 'deselect' for a leaf item. Do this optimization after
@@ -734,8 +763,8 @@ void LLFolderViewItem::draw()
 	{
 		LLUIImage* arrow_image = default_params.folder_arrow_image;
 		gl_draw_scaled_rotated_image(
-			mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
-			ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
+			mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
+			mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), sFgColor);
 	}
 
 
@@ -744,7 +773,7 @@ void LLFolderViewItem::draw()
 	//--------------------------------------------------------------------------------//
 	// Draw open icon
 	//
-	const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
+	const S32 icon_x = mIndentation + mArrowSize + mTextPad;
 	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
  	{
 		mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
@@ -769,8 +798,8 @@ void LLFolderViewItem::draw()
 
 	std::string::size_type filter_string_length = mViewModelItem->hasFilterStringMatch() ? mViewModelItem->getFilterStringSize() : 0;
 	F32 right_x  = 0;
-	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
+	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
+	F32 text_left = (F32)getLabelXPos();
 	std::string combined_string = mLabel + mLabelSuffix;
 
 	if (filter_string_length > 0)
@@ -804,11 +833,15 @@ void LLFolderViewItem::draw()
     if (filter_string_length > 0)
     {
         F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
-        F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
+        F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
         font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
             sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
             filter_string_length, S32_MAX, &right_x, FALSE );
     }
+
+    //Gilbert Linden 9-20-2012: Although this should be legal, removing it because it causes the mLabelSuffix rendering to
+    //be distorted...oddly. I initially added this in but didn't need it after all. So removing to prevent unnecessary bug.
+    //LLView::draw();
 }
 
 const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
@@ -984,7 +1017,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
 			folders_t::iterator fit = iter++;
 			// number of pixels that bottom of folder label is from top of parent folder
 			if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() 
-				> llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
+				> llround(mCurHeight) + mMaxFolderItemOverlap)
 			{
 				// hide if beyond current folder height
 				(*fit)->setVisible(FALSE);
@@ -997,7 +1030,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height )
 			items_t::iterator iit = iter++;
 			// number of pixels that bottom of item label is from top of parent folder
 			if (getRect().getHeight() - (*iit)->getRect().mBottom
-				> llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
+				> llround(mCurHeight) + mMaxFolderItemOverlap)
 			{
 				(*iit)->setVisible(FALSE);
 			}
@@ -1757,7 +1790,7 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
 	}
 	if( !handled )
 	{
-		if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
+		if(mIndentation < x && x < mIndentation + mArrowSize + mTextPad)
 		{
 			toggleOpen();
 			handled = TRUE;
@@ -1781,7 +1814,7 @@ BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 	}
 	if( !handled )
 	{
-		if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
+		if(mIndentation < x && x < mIndentation + mArrowSize + mTextPad)
 		{
 			// don't select when user double-clicks plus sign
 			// so as not to contradict single-click behavior
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 5c97407bc1..b7e0091aca 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -60,18 +60,18 @@ public:
 		Optional<time_t>							creation_date;
 		Optional<bool>								allow_open;
 
+        Optional<S32>                               left_pad,
+                                                    icon_pad,
+                                                    icon_width,
+                                                    text_pad,
+                                                    text_pad_right,
+                                                    arrow_size,
+                                                    max_folder_item_overlap;
 		Params();
 	};
 
-	// layout constants
-	static const S32	LEFT_PAD = 5,
-						ICON_PAD = 2,
-						ICON_WIDTH = 16,
-						TEXT_PAD = 1,
-                        DEFAULT_TEXT_PADDING_RIGHT = 4,
-						ARROW_SIZE = 12,
-						MAX_FOLDER_ITEM_OVERLAP = 2;
-	
+
+	static const S32    DEFAULT_LABEL_PADDING_RIGHT = 4;
 	// animation parameters
 	static const F32	FOLDER_CLOSE_TIME_CONSTANT,
 						FOLDER_OPEN_TIME_CONSTANT;
@@ -99,6 +99,14 @@ protected:
 	S32							mDragStartX,
 								mDragStartY;
 
+    S32                         mLeftPad,
+                                mIconPad,
+                                mIconWidth,
+                                mTextPad,
+                                mTextPadRight,
+                                mArrowSize,
+                                mMaxFolderItemOverlap;
+
 	F32							mControlLabelRotation;
 	LLFolderView*				mRoot;
 	bool						mHasVisibleChildren,
@@ -136,6 +144,9 @@ public:
 	// makes sure that this view and it's children are the right size.
 	virtual S32 arrange( S32* width, S32* height );
 	virtual S32 getItemHeight();
+    virtual S32 getLabelXPos();
+    S32 getIconPad();
+    S32 getTextPad();
 
 	// If 'selection' is 'this' then note that otherwise ignore.
 	// Returns TRUE if this item ends up being selected.
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 721abd5892..6860415377 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -109,8 +109,8 @@ void LLConversationViewSession::draw()
 	{
 		LLUIImage* arrow_image = default_params.folder_arrow_image;
 		gl_draw_scaled_rotated_image(
-			mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
-			ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
+			mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
+			mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), sFgColor);
 	}
 
 
@@ -227,7 +227,7 @@ void LLConversationViewSession::draw()
 // virtual
 S32 LLConversationViewSession::arrange(S32* width, S32* height)
 {
-	LLRect rect(getIndentation() + ARROW_SIZE,
+	LLRect rect(getIndentation() + mArrowSize,
 				getLocalRect().mTop,
 				getLocalRect().mRight,
 				getLocalRect().mTop - getItemHeight());
@@ -336,7 +336,7 @@ void LLConversationViewParticipant::initFromParams(const LLConversationViewParti
     applyXUILayout(avatar_icon_params, this);
     LLAvatarIconCtrl * avatarIcon = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_icon_params);
     addChild(avatarIcon);	
-
+    
 	LLButton::Params info_button_params(params.info_button());
     applyXUILayout(info_button_params, this);
 	LLButton * button = LLUICtrlFactory::create<LLButton>(info_button_params);
@@ -381,16 +381,11 @@ void LLConversationViewParticipant::draw()
     const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
     const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
 
-    const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-    const S32 TOP_PAD = default_params.item_top_pad;
-
     const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
     F32 right_x  = 0;
 
-    //TEXT_PAD, TOP_PAD, ICON_PAD and mIndentation are temporary values and will non-const eventually since they don't
-    //apply to every single layout
-    F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-    F32 text_left = (F32)(mAvatarIcon->getRect().mRight + ICON_PAD + mIndentation);
+    F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad;
+    F32 text_left = (F32)getLabelXPos();
     LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
 
     drawHighlight(show_context, filled, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
@@ -448,6 +443,11 @@ void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
     LLFolderViewItem::onMouseEnter(x, y, mask);
 }
 
+S32 LLConversationViewParticipant::getLabelXPos()
+{
+    return mAvatarIcon->getRect().mRight + mIconPad;
+}
+
 // static
 void LLConversationViewParticipant::initChildrenWidths(LLConversationViewParticipant* self)
 {
@@ -465,7 +465,7 @@ void LLConversationViewParticipant::initChildrenWidths(LLConversationViewPartici
 
 void LLConversationViewParticipant::computeLabelRightPadding()
 {
-    mLabelPaddingRight = DEFAULT_TEXT_PADDING_RIGHT;
+    mLabelPaddingRight = DEFAULT_LABEL_PADDING_RIGHT;
     LLView* control;
     S32 ctrl_width;
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 075ad09d5b..5bc4678b7b 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -101,6 +101,8 @@ public:
     void onMouseEnter(S32 x, S32 y, MASK mask);
     void onMouseLeave(S32 x, S32 y, MASK mask);
 
+    /*virtual*/ S32 getLabelXPos();
+
 protected:
 	friend class LLUICtrlFactory;
 	LLConversationViewParticipant( const Params& p );
diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
index 203febbf18..c80e5b168a 100644
--- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
@@ -20,6 +20,13 @@
               folder_indentation="8"
               item_height="20"
               item_top_pad="4"
-              selection_image="Rounded_Square"/>
+              selection_image="Rounded_Square"
+              left_pad="5"
+              icon_pad="2"
+              icon_width="16"
+              text_pad="1"
+              text_pad_right="4"
+              arrow_size="12"
+              max_folder_item_overlap="2"/>
       <item allow_open="false"/>
 </inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
index 7ddcfe3b03..a28d6e0209 100755
--- a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -1,12 +1,19 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <conversation_view_participant
-  folder_arrow_image="ForSale_Badge"
+  folder_arrow_image="Folder_Arrow"
   folder_indentation="0"
   item_height="24" 
-  item_top_pad="4"
+  item_top_pad="0"
   selection_image="Rounded_Square"
   mouse_opaque="true"
   follows="left|top|right"
+  left_pad="0"
+  icon_pad="10"
+  icon_width="20"
+  text_pad="7"
+  text_pad_right="4"
+  arrow_size="12"
+  max_folder_item_overlap="2"
 >
 <avatar_icon
 	 follows="left"
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
index f44731ea3d..b8c39eec1d 100644
--- a/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
@@ -6,4 +6,11 @@
   item_top_pad="4"
   selection_image="Rounded_Square"
   mouse_opaque="true"
-  follows="left|top|right"/>
+  follows="left|top|right"
+  left_pad="5"
+  icon_pad="2"
+  icon_width="16"
+  text_pad="1"
+  text_pad_right="4"
+  arrow_size="12"
+  max_folder_item_overlap="2"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
index 6fa74f403d..bbd53ccb12 100644
--- a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
@@ -7,4 +7,10 @@
   selection_image="Rounded_Square"
   mouse_opaque="true"
   follows="left|top|right"
-  />
+  left_pad="5"
+  icon_pad="2"
+  icon_width="16"
+  text_pad="1"
+  text_pad_right="4"
+  arrow_size="12"
+  max_folder_item_overlap="2"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
index 77d8024cb2..590a4730a9 100644
--- a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
@@ -5,7 +5,13 @@
   item_height="20" 
   item_top_pad="4"
   selection_image="Rounded_Square"
-  >
+  left_pad="5"
+  icon_pad="2"
+  icon_width="16"
+  text_pad="1"
+  text_pad_right="4"
+  arrow_size="12"
+  max_folder_item_overlap="2">
 	<new_badge 
         label="New" 
         label_offset_horiz="-1"
-- 
cgit v1.2.3


From 59a6a23ee0a94a7695679ea8df93bc0c60682262 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 20 Sep 2012 16:33:21 -0700
Subject: CHUI-283: within LLFolderView::scrollToShowItem(), adjusted the
 calculation that scrolls to the selected item. My prior commit changed this
 calculation and adjusted it in this commit to preserve prior behavior.

---
 indra/llui/llfolderview.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index ab4efea4dd..ce1bc5914c 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1654,8 +1654,8 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
 		// get portion of item that we want to see...
 		LLRect item_local_rect = LLRect(item->getIndentation(), 
 										local_rect.getHeight(), 
-                                        //+32 is supposed to include few first characters
-										llmin(item->getLabelXPos() + 32, local_rect.getWidth()), 
+                                        //+40 is supposed to include few first characters
+										llmin(item->getLabelXPos() - item->getIndentation() + 40, local_rect.getWidth()), 
 										llmax(0, local_rect.getHeight() - max_height_to_show));
 
 		LLRect item_doc_rect;
-- 
cgit v1.2.3


From 1107803a5c6da07cd5171f06afc0490f3eca7bf7 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 20 Sep 2012 17:50:58 -0700
Subject: CHUI-340 : WIP : Implement time update and comparison for sessions
 and participants

---
 indra/newview/llconversationmodel.cpp | 44 +++++++++++++++++++++++++++++------
 indra/newview/llconversationmodel.h   | 10 ++++++--
 indra/newview/llparticipantlist.cpp   |  9 +++++--
 3 files changed, 52 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 612744c3e9..b39b997a55 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -167,6 +167,31 @@ void LLConversationItemSession::setParticipantIsModerator(const LLUUID& particip
 	}
 }
 
+// The time of activity of a session is the time of the most recent participation
+const bool LLConversationItemSession::getTime(F64& time) const
+{
+	bool has_time = false;
+	F64 most_recent_time = 0.0;
+	LLConversationItemParticipant* participant = NULL;
+	child_list_t::const_iterator iter;
+	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+	{
+		participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+		F64 participant_time;
+		if (participant->getTime(participant_time))
+		{
+			has_time = true;
+			most_recent_time = llmax(most_recent_time,participant_time);
+		}
+	}
+	if (has_time)
+	{
+		time = most_recent_time;
+	}
+	llinfos << "Merov debug : get time session, uuid = " << mUUID << ", has_time = " << has_time << ", time = " << time << llendl;
+	return has_time;
+}
+
 void LLConversationItemSession::dumpDebugData()
 {
 	llinfos << "Merov debug : session, uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl;
@@ -186,7 +211,8 @@ void LLConversationItemSession::dumpDebugData()
 LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(display_name,uuid,root_view_model),
 	mIsMuted(false),
-	mIsModerator(false)
+	mIsModerator(false),
+	mLastActiveTime(0.0)
 {
 	mConvType = CONV_PARTICIPANT;
 }
@@ -228,8 +254,8 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 		U32 sort_order = getSortOrderParticipants();
 		if (sort_order == LLConversationFilter::SO_DATE)
 		{
-			F32 time_a = 0.0;
-			F32 time_b = 0.0;
+			F64 time_a = 0.0;
+			F64 time_b = 0.0;
 			if (a->getTime(time_a) && b->getTime(time_b))
 			{
 				return (time_a > time_b);
@@ -251,8 +277,8 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 		U32 sort_order = getSortOrderSessions();
 		if (sort_order == LLConversationFilter::SO_DATE)
 		{
-			F32 time_a = 0.0;
-			F32 time_b = 0.0;
+			F64 time_a = 0.0;
+			F64 time_b = 0.0;
 			if (a->getTime(time_a) && b->getTime(time_b))
 			{
 				return (time_a > time_b);
@@ -260,7 +286,10 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 		}
 		else if (sort_order == LLConversationFilter::SO_SESSION_TYPE)
 		{
-			return (type_a < type_b);
+			if (type_a != type_b)
+			{
+				return (type_a < type_b);
+			}
 		}
 	}
 	else
@@ -270,7 +299,8 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 		// Notes: as a consequence, CONV_UNKNOWN (which should never get created...) always come first
 		return (type_a < type_b);
 	}
-	// By default, in all other possible cases (including sort order of type LLConversationFilter::SO_NAME of course), sort by name
+	// By default, in all other possible cases (including sort order of type LLConversationFilter::SO_NAME of course), 
+	// we sort by name
 	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
 	return (compare < 0);
 }
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index dbc04223af..f3f99b5575 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -104,9 +104,9 @@ public:
 	virtual void selectItem(void) { } 
 	virtual void showProperties(void);
 
-	// Methods used in sorting (see LLConversationSort::operator()
+	// Methods used in sorting (see LLConversationSort::operator())
 	EConversationType const getType() const { return mConvType; }
-	virtual const bool getTime(F32& time) const { return false; }
+	virtual const bool getTime(F64& time) const { return false; }
 	virtual const bool getDistanceToAgent(F32& distance) const { return false; }
 	
 	// This method will be called to determine if a drop can be
@@ -152,6 +152,8 @@ public:
 	
 	bool isLoaded() { return mIsLoaded; }
 	
+	virtual const bool getTime(F64& time) const;
+
 	void dumpDebugData();
 
 private:
@@ -169,14 +171,18 @@ public:
 	bool isModerator() {return mIsModerator; }
 	void setIsMuted(bool is_muted) { mIsMuted = is_muted; mNeedsRefresh = true; }
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
+	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); }
 	
 	void onAvatarNameCache(const LLAvatarName& av_name);
 
+	virtual const bool getTime(F64& time) const { time = mLastActiveTime; return (time > 0.1 ? true : false); }
+
 	void dumpDebugData();
 
 private:
 	bool mIsMuted;		// default is false
 	bool mIsModerator;	// default is false
+	F64  mLastActiveTime;
 };
 
 // We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 8bc6bb60cf..9f470a735e 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -591,8 +591,13 @@ bool LLParticipantList::onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> eve
 	const LLSD& evt_data = event->getValue();
 	if ( evt_data.has("id") )
 	{
-		LLUUID id = evt_data["id"];
-		llinfos << "Merov debug : onSpeakerUpdateEvent, session = " << mUUID << ", uuid = " << id << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
+		LLUUID participant_id = evt_data["id"];
+		LLConversationItemParticipant* participant = findParticipant(participant_id);
+		if (participant)
+		{
+			participant->setTimeNow();
+		}
+		llinfos << "Merov debug : onSpeakerUpdateEvent, session = " << mUUID << ", uuid = " << participant_id << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
 	}
 	return true;
 }
-- 
cgit v1.2.3


From fc6bbee3f4ba1abba2956ee92f7ac7ba01d0f59b Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 20 Sep 2012 20:48:20 -0700
Subject: CHUI-340 : WIP : Implement time update on all IM typing cases

---
 indra/newview/llconversationmodel.cpp | 9 +++++++++
 indra/newview/llconversationmodel.h   | 1 +
 indra/newview/llimfloater.cpp         | 4 +++-
 indra/newview/llnearbychat.cpp        | 5 +++--
 indra/newview/llparticipantlist.cpp   | 7 +------
 5 files changed, 17 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index b39b997a55..31f9ca6a32 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -167,6 +167,15 @@ void LLConversationItemSession::setParticipantIsModerator(const LLUUID& particip
 	}
 }
 
+void LLConversationItemSession::setParticipantTimeNow(const LLUUID& participant_id)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		participant->setTimeNow();
+	}
+}
+
 // The time of activity of a session is the time of the most recent participation
 const bool LLConversationItemSession::getTime(F64& time) const
 {
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index f3f99b5575..e2c88785a2 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -149,6 +149,7 @@ public:
 
 	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
 	void setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator);
+	void setParticipantTimeNow(const LLUUID& participant_id);
 	
 	bool isLoaded() { return mIsLoaded; }
 	
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index fbc1b8e7fe..8268764816 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -907,9 +907,11 @@ void LLIMFloater::updateMessages()
 				chat.mText = message;
 			}
 			
-			// Merov debug
+			// Update the participant activity time
+			mParticipantList->setParticipantTimeNow(from_id);
 			llinfos << "Merov debug : LLIMFloater::updateMessages, session = " << mSessionID << ", from = " << msg["from"].asString() << ", uuid = " << msg["from_id"].asString() << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
 
+			// Add the message to the chat log
 			appendMessage(chat);
 			mLastMessageIndex = msg["index"].asInteger();
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index bf47aa06a8..0d52a9e14c 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -233,9 +233,10 @@ void LLNearbyChat::loadHistory()
  			gCacheName->getUUID(legacy_name, from_id);
  		}
 
-		// Merov debug
+		// Update the participant activity time
+		mParticipantList->setParticipantTimeNow(from_id);
 		llinfos << "Merov debug : LLNearbyChat::loadHistory, session = " << mSessionID << ", from = " << msg[IM_FROM].asString() << ", uuid = " << msg[IM_FROM_ID].asString() << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
-
+		
 		LLChat chat;
 		chat.mFromName = from;
 		chat.mFromID = from_id;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 9f470a735e..6283c8f296 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -592,12 +592,7 @@ bool LLParticipantList::onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> eve
 	if ( evt_data.has("id") )
 	{
 		LLUUID participant_id = evt_data["id"];
-		LLConversationItemParticipant* participant = findParticipant(participant_id);
-		if (participant)
-		{
-			participant->setTimeNow();
-		}
-		llinfos << "Merov debug : onSpeakerUpdateEvent, session = " << mUUID << ", uuid = " << participant_id << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
+		setParticipantTimeNow(participant_id);
 	}
 	return true;
 }
-- 
cgit v1.2.3


From 073065d6520a3b438fce3c5c27ee51c6d86ee742 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 21 Sep 2012 17:52:03 +0300
Subject: CHUI-289 ADD. FIX (Newly added conversation is not selected in
 conversation list): Select item which was added from avatar picker

---
 indra/newview/llimconversation.cpp     | 1 +
 indra/newview/llimfloatercontainer.cpp | 4 +++-
 indra/newview/llimfloatercontainer.h   | 2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index a2efe63546..d5bce5a43f 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -54,6 +54,7 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
   , mRefreshTimer(new LLTimer())
+  , mHaveFocus(false)
 {
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4e0fba9502..de1fd58661 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -700,7 +700,7 @@ void LLIMFloaterContainer::repositioningWidgets()
 	}
 }
 
-void LLIMFloaterContainer::setConvItemSelect(LLUUID& session_id)
+void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
 {
 	LLFolderViewItem* widget = mConversationsWidgets[session_id];
 	if (widget && mSelectedSession != session_id)
@@ -763,6 +763,8 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 		participant_view->addToFolder(widget);
 		current_participant_model++;
 	}
+
+	setConvItemSelect(uuid);
 	
 	return;
 }
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 1f526091bb..077ecd192b 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -62,7 +62,7 @@ public:
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
-    void setConvItemSelect(LLUUID& session_id);
+    void setConvItemSelect(const LLUUID& session_id);
 	/*virtual*/ void tabClose();
 
 	static LLFloater* getCurrentVoiceFloater();
-- 
cgit v1.2.3


From 8b63f7f50367f5726d03fb784f5a2f0783470b9c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 21 Sep 2012 19:42:11 +0300
Subject: CHUI-289 ADDITIONAL FIX (Newly added conversation is not selected in
 conversation list): gave more meaningful names to variables

---
 indra/newview/llimconversation.cpp | 10 +++++-----
 indra/newview/llimconversation.h   |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index d5bce5a43f..ca8493f787 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -54,7 +54,7 @@ LLIMConversation::LLIMConversation(const LLUUID& session_id)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
   , mRefreshTimer(new LLTimer())
-  , mHaveFocus(false)
+  , mHasFocus(false)
 {
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
@@ -217,10 +217,10 @@ void LLIMConversation::onFocusReceived()
 
 	LLTransientDockableFloater::onFocusReceived();
 
-    mHasFocus = mHaveFocus;
-    mHaveFocus = true;
+    mHadFocus = mHasFocus;
+    mHasFocus = true;
 
-	if (! mHasFocus)
+	if (! mHadFocus)
 	{
 	    LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
 	    container->setConvItemSelect(mSessionID);
@@ -230,7 +230,7 @@ void LLIMConversation::onFocusReceived()
 void LLIMConversation::onFocusLost()
 {
 	setBackgroundOpaque(false);
-	mHaveFocus = false;
+	mHasFocus = false;
 	LLTransientDockableFloater::onFocusLost();
 }
 
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index e09ba79a6a..bad5eaa99f 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -140,8 +140,8 @@ private:
 
 	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
 
+	bool mHadFocus;
 	bool mHasFocus;
-	bool mHaveFocus;
 };
 
 
-- 
cgit v1.2.3


From 6dd2bf36c52fa00732ed5a3910539f38c91ff173 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 21 Sep 2012 15:27:46 -0700
Subject: CHUI-283: Now the speaker/info icon positions are set based upon
 visibility.'

---
 indra/newview/llconversationview.cpp               | 23 ++++++++++++++++++----
 indra/newview/llconversationview.h                 |  2 +-
 .../en/widgets/conversation_view_participant.xml   |  2 ++
 3 files changed, 22 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 6860415377..26d618e1b3 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -366,7 +366,7 @@ BOOL LLConversationViewParticipant::postBuild()
         sStaticInitialized = true;
     }
 
-    computeLabelRightPadding();
+    updateChildren();
 	return LLFolderViewItem::postBuild();
 }
 
@@ -432,14 +432,14 @@ void LLConversationViewParticipant::onInfoBtnClick()
 void LLConversationViewParticipant::onMouseEnter(S32 x, S32 y, MASK mask)
 {
     mInfoBtn->setVisible(true);
-    computeLabelRightPadding();
+    updateChildren();
     LLFolderViewItem::onMouseEnter(x, y, mask);
 }
 
 void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
 {
     mInfoBtn->setVisible(false);
-    computeLabelRightPadding();
+    updateChildren();
     LLFolderViewItem::onMouseEnter(x, y, mask);
 }
 
@@ -463,12 +463,14 @@ void LLConversationViewParticipant::initChildrenWidths(LLConversationViewPartici
     llassert(index == 0);
 }
 
-void LLConversationViewParticipant::computeLabelRightPadding()
+void LLConversationViewParticipant::updateChildren()
 {
     mLabelPaddingRight = DEFAULT_LABEL_PADDING_RIGHT;
     LLView* control;
     S32 ctrl_width;
+    LLRect controlRect;
 
+    //Cycles through controls starting from right to left
     for (S32 i = 0; i < ALIC_COUNT; ++i)
     {
         control = getItemChildView((EAvatarListItemChildIndex)i);
@@ -476,9 +478,22 @@ void LLConversationViewParticipant::computeLabelRightPadding()
         // skip invisible views
         if (!control->getVisible()) continue;
 
+        //Get current pos/dimensions
+        controlRect = control->getRect();
+
         ctrl_width = sChildrenWidths[i]; // including space between current & left controls
         // accumulate the amount of space taken by the controls
         mLabelPaddingRight += ctrl_width;
+
+        //Reposition visible controls in case adjacent controls to the right are hidden.
+        controlRect.setLeftTopAndSize(
+            getLocalRect().getWidth() - mLabelPaddingRight,
+            controlRect.mTop,
+            controlRect.getWidth(),
+            controlRect.getHeight());
+
+        //Sets the new position
+        control->setShape(controlRect);
     }
 }
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 5bc4678b7b..0b98c34c73 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -127,7 +127,7 @@ private:
     static bool	sStaticInitialized; // this variable is introduced to improve code readability
     static S32 sChildrenWidths[ALIC_COUNT];
     static void initChildrenWidths(LLConversationViewParticipant* self);
-    void computeLabelRightPadding();
+    void updateChildren();
     LLView* getItemChildView(EAvatarListItemChildIndex child_view_index);
 };
 
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
index a28d6e0209..0024decd4c 100755
--- a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -19,7 +19,9 @@
 	 follows="left"
      height="20"
      default_icon_name="Generic_Person"
+	 layout="topleft"
      left="50"
+	 top="2"
      width="20" />
 <info_button
 	 follows="right"
-- 
cgit v1.2.3


From 18f294715822bedaea3bafa9dfec1ee42c12353c Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 21 Sep 2012 16:26:44 -0700
Subject: CHUI-283: Now the mouse over highlight only shows up when hovering
 over a participant. Before there was a bug where the onMouseLeave() function
 was not being called. This prevented the mouse-over-highlight from turning
 off.

---
 indra/newview/llconversationview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 26d618e1b3..394a830e5e 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -440,7 +440,7 @@ void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
 {
     mInfoBtn->setVisible(false);
     updateChildren();
-    LLFolderViewItem::onMouseEnter(x, y, mask);
+    LLFolderViewItem::onMouseLeave(x, y, mask);
 }
 
 S32 LLConversationViewParticipant::getLabelXPos()
-- 
cgit v1.2.3


From b5583906d0cce652f456851732db5b1c19659662 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 21 Sep 2012 18:12:06 -0700
Subject: CHUI-340 : WIP : Fix sorting bugs on time for sessions, simplified
 the update time mechanism and clean up

---
 indra/llui/llfolderviewmodel.h         |  2 +-
 indra/newview/llconversationmodel.cpp  | 53 +++++++++++++++++++++++++---------
 indra/newview/llconversationmodel.h    | 10 +++----
 indra/newview/llimconversation.cpp     |  8 +++++
 indra/newview/llimfloater.cpp          |  4 ---
 indra/newview/llimfloatercontainer.cpp | 15 ++++++++++
 indra/newview/llimfloatercontainer.h   |  1 +
 indra/newview/llnearbychat.cpp         |  4 ---
 indra/newview/llparticipantlist.cpp    |  7 ++++-
 9 files changed, 75 insertions(+), 29 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 22bfc4dfb4..c99fa07c8b 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -226,7 +226,7 @@ public:
 		mParent(NULL),
 		mRootViewModel(root_view_model)
 	{
-		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
+		mChildren.clear();
 	}
 
 	void requestSort() { mSortVersion = -1; }
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 31f9ca6a32..e090d1647f 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -38,7 +38,8 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u
 	mName(display_name),
 	mUUID(uuid),
 	mNeedsRefresh(true),
-	mConvType(CONV_UNKNOWN)
+	mConvType(CONV_UNKNOWN),
+	mLastActiveTime(0.0)
 {
 }
 
@@ -47,7 +48,8 @@ LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInte
 	mName(""),
 	mUUID(uuid),
 	mNeedsRefresh(true),
-	mConvType(CONV_UNKNOWN)
+	mConvType(CONV_UNKNOWN),
+	mLastActiveTime(0.0)
 {
 }
 
@@ -56,7 +58,8 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 	mName(""),
 	mUUID(),
 	mNeedsRefresh(true),
-	mConvType(CONV_UNKNOWN)
+	mConvType(CONV_UNKNOWN),
+	mLastActiveTime(0.0)
 {
 }
 
@@ -167,8 +170,10 @@ void LLConversationItemSession::setParticipantIsModerator(const LLUUID& particip
 	}
 }
 
-void LLConversationItemSession::setParticipantTimeNow(const LLUUID& participant_id)
+void LLConversationItemSession::setTimeNow(const LLUUID& participant_id)
 {
+	mLastActiveTime = LLFrameTimer::getElapsedSeconds();
+	mNeedsRefresh = true;
 	LLConversationItemParticipant* participant = findParticipant(participant_id);
 	if (participant)
 	{
@@ -176,11 +181,11 @@ void LLConversationItemSession::setParticipantTimeNow(const LLUUID& participant_
 	}
 }
 
-// The time of activity of a session is the time of the most recent participation
+// The time of activity of a session is the time of the most recent activity, session and participants included
 const bool LLConversationItemSession::getTime(F64& time) const
 {
-	bool has_time = false;
-	F64 most_recent_time = 0.0;
+	F64 most_recent_time = mLastActiveTime;
+	bool has_time = (most_recent_time > 0.1);
 	LLConversationItemParticipant* participant = NULL;
 	child_list_t::const_iterator iter;
 	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
@@ -197,7 +202,6 @@ const bool LLConversationItemSession::getTime(F64& time) const
 	{
 		time = most_recent_time;
 	}
-	llinfos << "Merov debug : get time session, uuid = " << mUUID << ", has_time = " << has_time << ", time = " << time << llendl;
 	return has_time;
 }
 
@@ -220,8 +224,7 @@ void LLConversationItemSession::dumpDebugData()
 LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(display_name,uuid,root_view_model),
 	mIsMuted(false),
-	mIsModerator(false),
-	mLastActiveTime(0.0)
+	mIsModerator(false)
 {
 	mConvType = CONV_PARTICIPANT;
 }
@@ -265,19 +268,34 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 		{
 			F64 time_a = 0.0;
 			F64 time_b = 0.0;
-			if (a->getTime(time_a) && b->getTime(time_b))
+			bool has_time_a = a->getTime(time_a);
+			bool has_time_b = b->getTime(time_b);
+			if (has_time_a && has_time_b)
 			{
 				return (time_a > time_b);
 			}
+			else if (has_time_a || has_time_b)
+			{
+				// If we have only one time updated, we consider the element with time as the "highest".
+				// That boils down to "has_time_a" if you think about it.
+				return has_time_a;
+			}
+			// If not time available, we'll default to sort by name at the end of this method
 		}
 		else if (sort_order == LLConversationFilter::SO_DISTANCE)
 		{
 			F32 dist_a = 0.0;
 			F32 dist_b = 0.0;
-			if (a->getDistanceToAgent(dist_a) && b->getDistanceToAgent(dist_b))
+			bool has_dist_a = a->getDistanceToAgent(dist_a);
+			bool has_dist_b = b->getDistanceToAgent(dist_b);
+			if (has_dist_a && has_dist_b)
 			{
 				return (dist_a > dist_b);
 			}
+			else if (has_dist_a || has_dist_b)
+			{
+				return has_dist_a;
+			}
 		}
 	}
 	else if ((type_a > LLConversationItem::CONV_PARTICIPANT) && (type_b > LLConversationItem::CONV_PARTICIPANT))
@@ -288,10 +306,19 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 		{
 			F64 time_a = 0.0;
 			F64 time_b = 0.0;
-			if (a->getTime(time_a) && b->getTime(time_b))
+			bool has_time_a = a->getTime(time_a);
+			bool has_time_b = b->getTime(time_b);
+			if (has_time_a && has_time_b)
 			{
 				return (time_a > time_b);
 			}
+			else if (has_time_a || has_time_b)
+			{
+				// If we have only one time updated, we consider the element with time as the "highest".
+				// That boils down to "has_time_a" if you think about it.
+				return has_time_a;
+			}
+			// If not time available, we'll default to sort by name at the end of this method
 		}
 		else if (sort_order == LLConversationFilter::SO_SESSION_TYPE)
 		{
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index e2c88785a2..e67aeb9aca 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -106,7 +106,7 @@ public:
 
 	// Methods used in sorting (see LLConversationSort::operator())
 	EConversationType const getType() const { return mConvType; }
-	virtual const bool getTime(F64& time) const { return false; }
+	virtual const bool getTime(F64& time) const { time = mLastActiveTime; return (time > 0.1); }
 	virtual const bool getDistanceToAgent(F32& distance) const { return false; }
 	
 	// This method will be called to determine if a drop can be
@@ -129,6 +129,7 @@ protected:
 	LLUUID mUUID;		// UUID of the session or the participant
 	EConversationType mConvType;	// Type of conversation item
 	bool mNeedsRefresh;	// Flag signaling to the view that something changed for this item
+	F64  mLastActiveTime;
 };
 
 class LLConversationItemSession : public LLConversationItem
@@ -149,7 +150,7 @@ public:
 
 	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
 	void setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator);
-	void setParticipantTimeNow(const LLUUID& participant_id);
+	void setTimeNow(const LLUUID& participant_id);
 	
 	bool isLoaded() { return mIsLoaded; }
 	
@@ -172,18 +173,15 @@ public:
 	bool isModerator() {return mIsModerator; }
 	void setIsMuted(bool is_muted) { mIsMuted = is_muted; mNeedsRefresh = true; }
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
-	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); }
+	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; }
 	
 	void onAvatarNameCache(const LLAvatarName& av_name);
 
-	virtual const bool getTime(F64& time) const { time = mLastActiveTime; return (time > 0.1 ? true : false); }
-
 	void dumpDebugData();
 
 private:
 	bool mIsMuted;		// default is false
 	bool mIsModerator;	// default is false
-	F64  mLastActiveTime;
 };
 
 // We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index a2efe63546..5425baec6d 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -250,6 +250,14 @@ std::string LLIMConversation::appendTime()
 
 void LLIMConversation::appendMessage(const LLChat& chat, const LLSD &args)
 {
+	// Update the participant activity time
+	LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
+	if (im_box)
+	{
+		im_box->setTimeNow(mSessionID,chat.mFromID);
+	}
+	
+
 	LLChat& tmp_chat = const_cast<LLChat&>(chat);
 
 	if(tmp_chat.mTimeStr.empty())
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 8268764816..43adfdfd08 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -907,10 +907,6 @@ void LLIMFloater::updateMessages()
 				chat.mText = message;
 			}
 			
-			// Update the participant activity time
-			mParticipantList->setParticipantTimeNow(from_id);
-			llinfos << "Merov debug : LLIMFloater::updateMessages, session = " << mSessionID << ", from = " << msg["from"].asString() << ", uuid = " << msg["from_id"].asString() << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
-
 			// Add the message to the chat log
 			appendMessage(chat);
 			mLastMessageIndex = msg["index"].asInteger();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4e0fba9502..f84da25baa 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -710,6 +710,21 @@ void LLIMFloaterContainer::setConvItemSelect(LLUUID& session_id)
 	}
 }
 
+void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
+{
+	conversations_items_map::iterator item_it = mConversationsItems.find(session_id);
+	if (item_it != mConversationsItems.end())
+	{
+		LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(item_it->second);
+		if (item)
+		{
+			item->setTimeNow(participant_id);
+			mConversationViewModel.requestSortAll();
+			mConversationsRoot->arrangeAll();
+		}
+	}
+}
+
 void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 {
 	bool is_nearby_chat = uuid.isNull();
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 1f526091bb..a7a5b8a391 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -124,6 +124,7 @@ private:
 public:
 	void removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
 	void addConversationListItem(const LLUUID& uuid);
+	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 0d52a9e14c..76626bd5a6 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -233,10 +233,6 @@ void LLNearbyChat::loadHistory()
  			gCacheName->getUUID(legacy_name, from_id);
  		}
 
-		// Update the participant activity time
-		mParticipantList->setParticipantTimeNow(from_id);
-		llinfos << "Merov debug : LLNearbyChat::loadHistory, session = " << mSessionID << ", from = " << msg[IM_FROM].asString() << ", uuid = " << msg[IM_FROM_ID].asString() << ", date = " << LLFrameTimer::getElapsedSeconds() << llendl;
-		
 		LLChat chat;
 		chat.mFromName = from;
 		chat.mFromID = from_id;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 6283c8f296..09f2716773 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -34,6 +34,7 @@
 #include "llagent.h"
 
 #include "llimview.h"
+#include "llimfloatercontainer.h"
 #include "llpanelpeoplemenus.h"
 #include "llnotificationsutil.h"
 #include "llparticipantlist.h"
@@ -592,7 +593,11 @@ bool LLParticipantList::onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> eve
 	if ( evt_data.has("id") )
 	{
 		LLUUID participant_id = evt_data["id"];
-		setParticipantTimeNow(participant_id);
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
+		if (im_box)
+		{
+			im_box->setTimeNow(mUUID,participant_id);
+		}
 	}
 	return true;
 }
-- 
cgit v1.2.3


From 552f288a0caea45e30a231478a19f4243d69689c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 21 Sep 2012 20:13:50 -0700
Subject: CHUI-340 : Implement distance computation and update

---
 indra/newview/llconversationmodel.cpp  | 24 +++++++++++++++-----
 indra/newview/llconversationmodel.h    |  7 +++++-
 indra/newview/llimfloatercontainer.cpp | 40 ++++++++++++++++++++++++++++++++++
 indra/newview/llimfloatercontainer.h   |  1 +
 4 files changed, 66 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index e090d1647f..b0d691fa13 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -181,6 +181,16 @@ void LLConversationItemSession::setTimeNow(const LLUUID& participant_id)
 	}
 }
 
+void LLConversationItemSession::setDistance(const LLUUID& participant_id, F64 dist)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		participant->setDistance(dist);
+		mNeedsRefresh = true;
+	}
+}
+
 // The time of activity of a session is the time of the most recent activity, session and participants included
 const bool LLConversationItemSession::getTime(F64& time) const
 {
@@ -224,13 +234,17 @@ void LLConversationItemSession::dumpDebugData()
 LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(display_name,uuid,root_view_model),
 	mIsMuted(false),
-	mIsModerator(false)
+	mIsModerator(false),
+	mDistToAgent(-1.0)
 {
 	mConvType = CONV_PARTICIPANT;
 }
 
 LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
-	LLConversationItem(uuid,root_view_model)
+	LLConversationItem(uuid,root_view_model),
+	mIsMuted(false),
+	mIsModerator(false),
+	mDistToAgent(-1.0)
 {
 	mConvType = CONV_PARTICIPANT;
 }
@@ -284,13 +298,13 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 		}
 		else if (sort_order == LLConversationFilter::SO_DISTANCE)
 		{
-			F32 dist_a = 0.0;
-			F32 dist_b = 0.0;
+			F64 dist_a = 0.0;
+			F64 dist_b = 0.0;
 			bool has_dist_a = a->getDistanceToAgent(dist_a);
 			bool has_dist_b = b->getDistanceToAgent(dist_b);
 			if (has_dist_a && has_dist_b)
 			{
-				return (dist_a > dist_b);
+				return (dist_a < dist_b);
 			}
 			else if (has_dist_a || has_dist_b)
 			{
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index e67aeb9aca..18c5dd1ce1 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -107,7 +107,7 @@ public:
 	// Methods used in sorting (see LLConversationSort::operator())
 	EConversationType const getType() const { return mConvType; }
 	virtual const bool getTime(F64& time) const { time = mLastActiveTime; return (time > 0.1); }
-	virtual const bool getDistanceToAgent(F32& distance) const { return false; }
+	virtual const bool getDistanceToAgent(F64& distance) const { return false; }
 	
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
@@ -151,6 +151,7 @@ public:
 	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
 	void setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator);
 	void setTimeNow(const LLUUID& participant_id);
+	void setDistance(const LLUUID& participant_id, F64 dist);
 	
 	bool isLoaded() { return mIsLoaded; }
 	
@@ -174,14 +175,18 @@ public:
 	void setIsMuted(bool is_muted) { mIsMuted = is_muted; mNeedsRefresh = true; }
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
 	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; }
+	void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; }
 	
 	void onAvatarNameCache(const LLAvatarName& av_name);
 
+	virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
+
 	void dumpDebugData();
 
 private:
 	bool mIsMuted;		// default is false
 	bool mIsModerator;	// default is false
+	F64  mDistToAgent;  // Distance to the agent. A negative (meaningless) value means the distance has not been set.
 };
 
 // We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 3c21794d28..cd56ea6081 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -47,6 +47,7 @@
 #include "llviewercontrol.h"
 #include "llconversationview.h"
 #include "llcallbacklist.h"
+#include "llworld.h"
 
 //
 // LLIMFloaterContainer
@@ -333,6 +334,14 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 void LLIMFloaterContainer::idle(void* user_data)
 {
 	LLIMFloaterContainer* self = static_cast<LLIMFloaterContainer*>(user_data);
+	
+	// Update the distance to agent in the nearby chat session if required
+	// Note: it makes no sense of course to update the distance in other session
+	if (self->mConversationViewModel.getSorter().getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE)
+	{
+		self->setNearbyDistances();
+	}
+	
 	self->mConversationsRoot->update();
 }
 
@@ -725,6 +734,37 @@ void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& pa
 	}
 }
 
+void LLIMFloaterContainer::setNearbyDistances()
+{
+	// Get the nearby chat session: that's the one with uuid nul in mConversationsItems
+	conversations_items_map::iterator item_it = mConversationsItems.find(LLUUID());
+	if (item_it != mConversationsItems.end())
+	{
+		LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(item_it->second);
+		if (item)
+		{
+			// Get the positions of the nearby avatars and their ids
+			std::vector<LLVector3d> positions;
+			uuid_vec_t avatar_ids;
+			LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+			// Get the position of the agent
+			const LLVector3d& me_pos = gAgent.getPositionGlobal();
+			// For each nearby avatar, compute and update the distance
+			int avatar_count = positions.size();
+			for (int i = 0; i < avatar_count; i++)
+			{
+				F64 dist = dist_vec_squared(positions[i], me_pos);
+				item->setDistance(avatar_ids[i],dist);
+			}
+			// Also does it for the agent itself
+			item->setDistance(gAgent.getID(),0.0f);
+			// Request resort
+			mConversationViewModel.requestSortAll();
+			mConversationsRoot->arrangeAll();
+		}
+	}
+}
+
 void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 {
 	bool is_nearby_chat = uuid.isNull();
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 4546029e93..e8d185297c 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -125,6 +125,7 @@ public:
 	void removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
 	void addConversationListItem(const LLUUID& uuid);
 	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
+	void setNearbyDistances();
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
-- 
cgit v1.2.3


From 05bae4d6d78de8165eca397493ce9d0156e3ad12 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 24 Sep 2012 13:27:50 +0300
Subject: CHUI-124 FIXED Tooltips for buttons are added

---
 .../skins/default/xui/en/panel_block_list_sidetray.xml   |  4 ++++
 indra/newview/skins/default/xui/en/panel_people.xml      | 16 ++++++++++++++++
 2 files changed, 20 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index 24f7d44cce..53d0252215 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -43,6 +43,7 @@
           menu_filename="menu_people_blocked_gear.xml"
           menu_position="bottomleft"
           name="blocked_gear_btn"
+          tool_tip="Actions on selected person or object"
           top="3"
           width="31" />
          <menu_button
@@ -57,6 +58,7 @@
           menu_filename="menu_people_blocked_view.xml"
           menu_position="bottomleft"
           name="view_btn"
+          tool_tip="Sort options"
           top_delta="0"
           width="31" />
          <menu_button
@@ -71,6 +73,7 @@
           menu_filename="menu_people_blocked_plus.xml"
           menu_position="bottomleft"
           name="plus_btn"
+          tool_tip="Pick a Resident or an object to block"
           top_delta="0"
           width="31"/>
           <button
@@ -83,6 +86,7 @@
           left_pad="2"
           layout="topleft"
           name="unblock_btn"
+          tool_tip="Remove Resident or object from blocked list"
           top_delta="0"
           width="31"/>
      </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 09156b41b5..7433ad828d 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -116,6 +116,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="7"
                  name="gear_btn"
+                 tool_tip="Actions on selected person"
                  top="3"
                  width="31" />
                 <menu_button
@@ -130,6 +131,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_people_nearby_view.xml"
                  menu_position="bottomleft"
                  name="nearby_view_btn"
+                 tool_tip="View/sort options"
                  top_delta="0"
                  width="31" />
                 <button
@@ -142,6 +144,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="2"
                  name="add_friend_btn"
+                 tool_tip="Offer friendship to a resident"
                  top_delta="0"
                  width="31">
                     <commit_callback
@@ -158,6 +161,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  layout="topleft"
                  name="nearby_del_btn"
+                 tool_tip="Remove selected person as a friend"
                  top_delta="0"
                  width="31">
                     <commit_callback
@@ -264,6 +268,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="8"
                  name="gear_btn"
+                 tool_tip="Actions on selected person"
                  top="3"
                  width="31" />
                 <menu_button
@@ -278,6 +283,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_people_friends_view.xml"
                  menu_position="bottomleft"
                  name="friends_view_btn"
+                 tool_tip="View/sort options"
                  top_delta="0"
                  width="31" />
                 <button
@@ -290,6 +296,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="2"
                  name="friends_add_btn"
+                 tool_tip="Offer friendship to a resident"
                  top_delta="0"
                  width="31">
                     <commit_callback
@@ -305,6 +312,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  layout="topleft"
                  name="friends_del_btn"
+                 tool_tip="Remove selected person as a friend"
                  top_delta="0"
                  width="31">
                     <commit_callback
@@ -419,6 +427,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="8"
                  name="groups_gear_btn"
+                 tool_tip="Actions on selected group"
                  top="3"
                  width="31" />
                 <menu_button
@@ -433,6 +442,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_people_groups_view.xml"
                  menu_position="bottomleft"
                  name="groups_view_btn"
+                 tool_tip="View/sort options"
                  top_delta="0"
                  width="31" />
                 <menu_button
@@ -447,6 +457,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_group_plus.xml"
                  menu_position="bottomleft"
                  name="plus_btn"
+                 tool_tip="Join group/Create new group"
                  top_delta="0"
                  width="31">
                     <validate_callback
@@ -462,6 +473,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  layout="topleft"
                  name="minus_btn"
+                 tool_tip="Leave selected group"
                  top_delta="0"
                  width="31">
                     <commit_callback
@@ -527,6 +539,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="8"
                  name="gear_btn"
+                 tool_tip="Actions on selected person"
                  top="3"
                  width="31" />
                 <menu_button
@@ -541,6 +554,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  menu_filename="menu_people_recent_view.xml"
                  menu_position="bottomleft"
                  name="recent_view_btn"
+                 tool_tip="View/sort options"
                  top_delta="0"
                  width="31" />
                 <button
@@ -553,6 +567,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  layout="topleft"
                  left_pad="2"
                  name="add_friend_btn"
+                 tool_tip="Offer friendship to a resident"
                  top_delta="0"
                  width="31">
                     <commit_callback
@@ -569,6 +584,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                  left_pad="2"
                  layout="topleft"
                  name="recent_del_btn"
+                 tool_tip="Remove selected person as a friend"
                  top_delta="0"
                  width="31">
                     <commit_callback
-- 
cgit v1.2.3


From e0b252fc99968eb54031a8a2bb8216baae5078b2 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 24 Sep 2012 14:52:20 +0300
Subject: CHUI-123 FIXED Tooltips for buttons are added

---
 indra/newview/llimconversation.cpp                          |  1 +
 indra/newview/skins/default/xui/en/floater_im_container.xml |  4 +++-
 indra/newview/skins/default/xui/en/floater_im_session.xml   | 11 +++++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 64f171ce8f..3ca93b1b07 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -424,6 +424,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 	mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat);
 
 	mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon"));
+	mTearOffBtn->setToolTip(getString(!is_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
 
 	mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat);
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 413e66738d..d23ff28fd0 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -62,6 +62,7 @@
                      layout="topleft"
                      left="10"
                      name="sort_btn"
+                     tool_tip="View/sort options"
                      top="5"
                      width="31" />
                     <button
@@ -75,7 +76,7 @@
                      top="5"
                      left_pad="4"
                      name="add_btn"
-                     tool_tip="Add button on the left panel"
+                     tool_tip="Start a new conversation"
                      width="31"/>
                 </layout_panel>
                 <layout_panel
@@ -94,6 +95,7 @@
                      top="5"
                      left="5"
                      name="expand_collapse_btn"
+                     tool_tip="Collapse/Expand this list"
                      width="31" />
                 </layout_panel>
             </layout_stack>
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index d6d48130ab..5c74f7f9bb 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -37,6 +37,12 @@
     <floater.string
      name="multiple_participants_added"
      value="[NAME] were invited to the conversation."/>
+     <floater.string
+     name="tooltip_to_separate_window"
+     value="Move this conversation to a separate window"/>
+     <floater.string
+     name="tooltip_to_main_window"
+     value="Move this conversation back to main window"/>
     <view
         follows="all"
         layout="topleft"
@@ -64,6 +70,7 @@
                  layout="topleft"
                  left="5"
                  name="view_options_btn"
+                 tool_tip="View/sort options"
                  top="5"
                  width="31" />
              <button
@@ -78,6 +85,7 @@
                  top="5"
                  left_pad="4"
                  name="add_btn"
+                 tool_tip="Add someone to this conversation"
                  width="31"/>
              <button
                  follows="top|left"
@@ -90,6 +98,7 @@
                  top="5"
                  left_pad="4"
                  name="voice_call_btn"
+                 tool_tip="Open voice connection"
                  width="31"/>
              <button
                  follows="right|top"
@@ -102,6 +111,7 @@
                  top="5"
                  left="283"
                  name="close_btn"
+                 tool_tip="End this conversation"
                  width="31" />
              <button
                  follows="right|top"
@@ -114,6 +124,7 @@
                  top="5"
                  left_pad="5"
                  name="expand_collapse_btn"
+                 tool_tip="Collapse/Expand this pane"
                  width="31" />
              <button
                  follows="right|top"
-- 
cgit v1.2.3


From a3b36bad821907f9b30891c45e7901b92366be52 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 24 Sep 2012 15:33:59 +0300
Subject: CHUI-309 FIXED Use onRemoveNotification only for "LoadWebPage",
 "ScriptDialog" and "ScriptDialogGroup" notifications

---
 indra/newview/llnotificationscripthandler.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 5dcd84b400..290a81f91c 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -109,7 +109,7 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 
 void LLScriptHandler::onDelete( LLNotificationPtr notification )
 	{
-	if(notification->hasFormElements())
+	if(notification->hasFormElements() && !notification->canShowToast())
 		{
 			LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
 		}
@@ -128,10 +128,11 @@ void LLScriptHandler::onDeleteToast(LLToast* toast)
 	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
 	LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID());
 	
-	if( notification && notification->hasFormElements())
+	if( notification && notification->hasFormElements() && !notification->canShowToast())
 	{
 		LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
 	}
+
 }
 
 
-- 
cgit v1.2.3


From f9e0831ba04f99335bfb494a22435446dc0852de Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 24 Sep 2012 18:57:04 +0300
Subject: CHUI-355 FIXED Nearby chat entries do not appear in torn off nearby
 chat window when opening from a toast: moved setIsSingleInstance() from
 constructor to postBuild() for prevent of a resetting it in buildFromXML();
 implemented correct set of mReuseInstance; changed type of the key of
 LLIMConversation from LLUUID() to LLSD()

---
 indra/llui/llfloater.cpp           | 5 +++++
 indra/llui/llfloater.h             | 7 ++++---
 indra/newview/llimconversation.cpp | 4 ++--
 indra/newview/llimconversation.h   | 2 +-
 indra/newview/llnearbychat.cpp     | 7 +++----
 indra/newview/llnearbychat.h       | 4 ++--
 6 files changed, 17 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 029c47c726..58b17f74a8 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -240,6 +240,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
 	mTitle(p.title),
 	mShortTitle(p.short_title),
 	mSingleInstance(p.single_instance),
+	mIsReuseInitialized(p.reuse_instance.isProvided()),
 	mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default
 	mKey(key),
 	mCanTearOff(p.can_tear_off),
@@ -631,6 +632,10 @@ void LLFloater::setVisible( BOOL visible )
 void LLFloater::setIsSingleInstance(BOOL is_single_instance)
 {
 	mSingleInstance = is_single_instance;
+	if (!mIsReuseInitialized)
+	{
+		mReuseInstance = is_single_instance; // reuse single-instance floaters by default
+	}
 }
 
 
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 4b738f88ea..07b79d5523 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -447,9 +447,10 @@ private:
 	LLUIString		mTitle;
 	LLUIString		mShortTitle;
 	
-	BOOL			mSingleInstance;	// TRUE if there is only ever one instance of the floater
-	bool			mReuseInstance;		// true if we want to hide the floater when we close it instead of destroying it
-	std::string		mInstanceName;		// Store the instance name so we can remove ourselves from the list
+	BOOL			mSingleInstance;	  // TRUE if there is only ever one instance of the floater
+	bool			mReuseInstance;		  // true if we want to hide the floater when we close it instead of destroying it
+    bool            mIsReuseInitialized;  // true if mReuseInstance already set from parameters
+	std::string		mInstanceName;		  // Store the instance name so we can remove ourselves from the list
 	
 	BOOL			mCanTearOff;
 	BOOL			mCanMinimize;
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 3ca93b1b07..2ad7f9b193 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -42,13 +42,13 @@
 
 const F32 REFRESH_INTERVAL = 0.2f;
 
-LLIMConversation::LLIMConversation(const LLUUID& session_id)
+LLIMConversation::LLIMConversation(const LLSD& session_id)
   : LLTransientDockableFloater(NULL, true, session_id)
   ,  mIsP2PChat(false)
   ,  mExpandCollapseBtn(NULL)
   ,  mTearOffBtn(NULL)
   ,  mCloseBtn(NULL)
-  ,  mSessionID(session_id)
+  ,  mSessionID(session_id.asUUID())
   , mParticipantList(NULL)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index bad5eaa99f..c54081d316 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -47,7 +47,7 @@ class LLIMConversation
 public:
 	LOG_CLASS(LLIMConversation);
 
-	LLIMConversation(const LLUUID& session_id);
+	LLIMConversation(const LLSD& session_id);
 	~LLIMConversation();
 
 	// reload all message with new settings of visual modes
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 76626bd5a6..71c4938ae9 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -88,7 +88,7 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
 
 
 LLNearbyChat::LLNearbyChat(const LLSD& llsd)
-:	LLIMConversation(llsd.asUUID()),
+:	LLIMConversation(llsd),
 	//mOutputMonitor(NULL),
 	mSpeakerMgr(NULL),
 	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
@@ -96,16 +96,15 @@ LLNearbyChat::LLNearbyChat(const LLSD& llsd)
     mIsP2PChat = false;
 	mIsNearbyChat = true;
 	setIsChrome(TRUE);
-	mKey = LLSD(LLUUID());
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
 	mSessionID = LLUUID();
-	setName("nearby_chat");
-	setIsSingleInstance(TRUE);
 }
 
+
 //virtual
 BOOL LLNearbyChat::postBuild()
 {
+    setIsSingleInstance(TRUE);
     BOOL result = LLIMConversation::postBuild();
 	mInputEditor->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this));
 	mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 648098113a..da1b58e326 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -45,8 +45,8 @@ class LLNearbyChat
 {
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
-	LLNearbyChat(const LLSD& key = LLSD());
-	~LLNearbyChat() {}
+	LLNearbyChat(const LLSD& key = LLSD(LLUUID()));
+	~LLNearbyChat() {};
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
-- 
cgit v1.2.3


From b28cb6843cdfedbd059ae3961cb528339127fbfd Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 24 Sep 2012 20:59:34 +0300
Subject: CHUI-355 FIXED Nearby chat entries do not appear in torn off nearby
 chat window when opening from a toast: fix for visual studio and XCode

---
 indra/newview/llnearbychat.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index da1b58e326..3987212e4c 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -46,7 +46,7 @@ class LLNearbyChat
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
 	LLNearbyChat(const LLSD& key = LLSD(LLUUID()));
-	~LLNearbyChat() {};
+	~LLNearbyChat() {}
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
-- 
cgit v1.2.3


From 5b0e06108b3c4373c55103dedab3306f06d392c9 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 24 Sep 2012 19:55:31 -0700
Subject: CHUI-340 : Fix dupe items in the conversation model list. Refresh
 when resorting.

---
 indra/llui/llfolderviewmodel.h         | 10 ++++++++++
 indra/newview/llconversationmodel.cpp  |  4 ++--
 indra/newview/llimfloatercontainer.cpp |  2 ++
 indra/newview/llparticipantlist.cpp    |  2 ++
 4 files changed, 16 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index c99fa07c8b..c6030c9b71 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -254,6 +254,16 @@ public:
 
 	virtual void addChild(LLFolderViewModelItem* child) 
 	{ 
+		// Avoid duplicates: bail out if that child is already present in the list
+		// Note: this happens when models are created before views
+		child_list_t::const_iterator iter;
+		for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+		{
+			if (child == *iter)
+			{
+				return;
+			}
+		}
 		mChildren.push_back(child); 
 		child->setParent(this); 
 		dirtyFilter();
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index b0d691fa13..a94d82bf7c 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -217,7 +217,7 @@ const bool LLConversationItemSession::getTime(F64& time) const
 
 void LLConversationItemSession::dumpDebugData()
 {
-	llinfos << "Merov debug : session, uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl;
+	llinfos << "Merov debug : session " << this << ", uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl;
 	LLConversationItemParticipant* participant = NULL;
 	child_list_t::iterator iter;
 	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
@@ -262,7 +262,7 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 
 void LLConversationItemParticipant::dumpDebugData()
 {
-	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
+	llinfos << "Merov debug : participant " << this << ", uuid = " << mUUID << ", name = " << mName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
 }
 
 //
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index cd56ea6081..14d40d4685 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -394,6 +394,8 @@ void LLIMFloaterContainer::draw()
 			}
 			// Reset the need for refresh
 			session_model->resetRefresh();
+			mConversationViewModel.requestSortAll();
+			mConversationsRoot->arrangeAll();
 			// Next participant
 			current_participant_model++;
 		}
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 09f2716773..90226e7fba 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -678,8 +678,10 @@ void LLParticipantList::sort()
 
 void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 {
+	// Do not add if already in there or excluded for some reason
 	if (mExcludeAgent && gAgent.getID() == avatar_id) return;
 	if (mAvatarList && mAvatarList->contains(avatar_id)) return;
+	if (findParticipant(avatar_id)) return;
 
 	bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id);
 
-- 
cgit v1.2.3


From 7ac4d71c43ec746f7bb30e5cedcfdd2c4c7940f7 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 25 Sep 2012 16:39:11 -0700
Subject: CHUI-329 : WIP : Always sort Nearby Chat to be on top of the list

---
 indra/newview/llconversationmodel.cpp | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a94d82bf7c..00cd8ba8f8 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -269,6 +269,7 @@ void LLConversationItemParticipant::dumpDebugData()
 // LLConversationSort
 // 
 
+// Comparison operator: returns "true" is a comes before b, "false" otherwise
 bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
 {
 	LLConversationItem::EConversationType type_a = a->getType();
@@ -276,7 +277,7 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 
 	if ((type_a == LLConversationItem::CONV_PARTICIPANT) && (type_b == LLConversationItem::CONV_PARTICIPANT))
 	{
-		// If both are participants
+		// If both items are participants
 		U32 sort_order = getSortOrderParticipants();
 		if (sort_order == LLConversationFilter::SO_DATE)
 		{
@@ -286,15 +287,15 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 			bool has_time_b = b->getTime(time_b);
 			if (has_time_a && has_time_b)
 			{
+				// Most recent comes first
 				return (time_a > time_b);
 			}
 			else if (has_time_a || has_time_b)
 			{
-				// If we have only one time updated, we consider the element with time as the "highest".
-				// That boils down to "has_time_a" if you think about it.
+				// If we have only one time available, the element with time must come first
 				return has_time_a;
 			}
-			// If not time available, we'll default to sort by name at the end of this method
+			// If no time available, we'll default to sort by name at the end of this method
 		}
 		else if (sort_order == LLConversationFilter::SO_DISTANCE)
 		{
@@ -304,52 +305,63 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 			bool has_dist_b = b->getDistanceToAgent(dist_b);
 			if (has_dist_a && has_dist_b)
 			{
+				// Closest comes first
 				return (dist_a < dist_b);
 			}
 			else if (has_dist_a || has_dist_b)
 			{
+				// If we have only one distance available, the element with it must come first
 				return has_dist_a;
 			}
+			// If no distance available, we'll default to sort by name at the end of this method
 		}
 	}
 	else if ((type_a > LLConversationItem::CONV_PARTICIPANT) && (type_b > LLConversationItem::CONV_PARTICIPANT))
 	{
 		// If both are sessions
 		U32 sort_order = getSortOrderSessions();
-		if (sort_order == LLConversationFilter::SO_DATE)
+		if ((type_a == LLConversationItem::CONV_SESSION_NEARBY) || (type_b == LLConversationItem::CONV_SESSION_NEARBY))
+		{
+			// If one is the nearby session, put nearby session *always* first
+			return (type_a == LLConversationItem::CONV_SESSION_NEARBY);
+		}
+		else if (sort_order == LLConversationFilter::SO_DATE)
 		{
+			// Sort by time
 			F64 time_a = 0.0;
 			F64 time_b = 0.0;
 			bool has_time_a = a->getTime(time_a);
 			bool has_time_b = b->getTime(time_b);
 			if (has_time_a && has_time_b)
 			{
+				// Most recent comes first
 				return (time_a > time_b);
 			}
 			else if (has_time_a || has_time_b)
 			{
-				// If we have only one time updated, we consider the element with time as the "highest".
-				// That boils down to "has_time_a" if you think about it.
+				// If we have only one time available, the element with time must come first
 				return has_time_a;
 			}
-			// If not time available, we'll default to sort by name at the end of this method
+			// If no time available, we'll default to sort by name at the end of this method
 		}
 		else if (sort_order == LLConversationFilter::SO_SESSION_TYPE)
 		{
 			if (type_a != type_b)
 			{
+				// Lowest types come first. See LLConversationItem definition of types
 				return (type_a < type_b);
 			}
+			// If types are identical, we'll default to sort by name at the end of this method
 		}
 	}
 	else
 	{
-		// If one is a participant and the other a session, the session is always "less" than the participant
+		// If one item is a participant and the other a session, the session comes before the participant
 		// so we simply compare the type
 		// Notes: as a consequence, CONV_UNKNOWN (which should never get created...) always come first
-		return (type_a < type_b);
+		return (type_a > type_b);
 	}
-	// By default, in all other possible cases (including sort order of type LLConversationFilter::SO_NAME of course), 
+	// By default, in all other possible cases (including sort order type LLConversationFilter::SO_NAME of course), 
 	// we sort by name
 	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
 	return (compare < 0);
-- 
cgit v1.2.3


From 3502e783b7425ba30d92f66697bafa89ae891e60 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 25 Sep 2012 22:02:44 -0700
Subject: CHUI-342 : Fixed : Use user name and display name correctly. Sort
 according to user names.

---
 indra/llui/llfolderviewitem.cpp       | 2 +-
 indra/newview/llconversationmodel.cpp | 8 ++++----
 indra/newview/llconversationmodel.h   | 3 +++
 3 files changed, 8 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 9632612752..5589c5b166 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -230,7 +230,7 @@ void LLFolderViewItem::refresh()
 
 	mLabel = vmi.getDisplayName();
 
-	setToolTip(mLabel);
+	setToolTip(vmi.getName());
 	mIcon = vmi.getIcon();
 	mIconOpen = vmi.getIconOpen();
 	mIconOverlay = vmi.getIconOverlay();
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 00cd8ba8f8..7d0ffa0788 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -251,8 +251,8 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
 {
-	mName = av_name.mDisplayName;
-	// *TODO : we should also store that one, to be used in the tooltip : av_name.mUsername
+	mName = av_name.mUsername;
+	mDisplayName = av_name.mDisplayName;
 	mNeedsRefresh = true;
 	if (mParent)
 	{
@@ -262,7 +262,7 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 
 void LLConversationItemParticipant::dumpDebugData()
 {
-	llinfos << "Merov debug : participant " << this << ", uuid = " << mUUID << ", name = " << mName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
+	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
 }
 
 //
@@ -363,7 +363,7 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 	}
 	// By default, in all other possible cases (including sort order type LLConversationFilter::SO_NAME of course), 
 	// we sort by name
-	S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+	S32 compare = LLStringUtil::compareDict(a->getName(), b->getName());
 	return (compare < 0);
 }
 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 18c5dd1ce1..30f94d51ae 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -170,6 +170,8 @@ public:
 	LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	virtual ~LLConversationItemParticipant() {}
 	
+	virtual const std::string& getDisplayName() const { return mDisplayName; }
+
 	bool isMuted() { return mIsMuted; }
 	bool isModerator() {return mIsModerator; }
 	void setIsMuted(bool is_muted) { mIsMuted = is_muted; mNeedsRefresh = true; }
@@ -186,6 +188,7 @@ public:
 private:
 	bool mIsMuted;		// default is false
 	bool mIsModerator;	// default is false
+	std::string mDisplayName;
 	F64  mDistToAgent;  // Distance to the agent. A negative (meaningless) value means the distance has not been set.
 };
 
-- 
cgit v1.2.3


From a62a4b60e8a954509a722b96c984b0a798653516 Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Wed, 26 Sep 2012 17:43:47 +0300
Subject: CHUI-347 FIXED drawing selected conversation item background. Moved
 some duplicating pieces of code from LLFolderViewFolder::draw() and 
 LLFolderViewItem::draw() to separate methods to reduce code duplication in
 LLConversationViewSession::draw(). Changed some static variables in
 LLFolderViewItem to static members for using them in derived
 LLConversationViewSession.

---
 indra/llui/llfolderviewitem.cpp      |  95 +++++++++++++++----------
 indra/llui/llfolderviewitem.h        |  16 +++++
 indra/newview/llconversationview.cpp | 131 ++---------------------------------
 3 files changed, 82 insertions(+), 160 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 9632612752..a9da885717 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -44,6 +44,18 @@ static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
 // statics 
 std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
 
+LLUIColor LLFolderViewItem::sFgColor;
+LLUIColor LLFolderViewItem::sHighlightBgColor;
+LLUIColor LLFolderViewItem::sHighlightFgColor;
+LLUIColor LLFolderViewItem::sFocusOutlineColor;
+LLUIColor LLFolderViewItem::sMouseOverColor;
+LLUIColor LLFolderViewItem::sFilterBGColor;
+LLUIColor LLFolderViewItem::sFilterTextColor;
+LLUIColor LLFolderViewItem::sSuffixColor;
+LLUIColor LLFolderViewItem::sLibraryColor;
+LLUIColor LLFolderViewItem::sLinkColor;
+LLUIColor LLFolderViewItem::sSearchStatusColor;
+
 // only integers can be initialized in header
 const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
 const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
@@ -130,10 +142,22 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
     mArrowSize(p.arrow_size),
     mMaxFolderItemOverlap(p.max_folder_item_overlap)
 {
+	sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+	sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+	sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+	sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+	sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+	sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+	sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+	sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
+	sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
+	sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
+	sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+
 	if (mViewModelItem)
 	{
 		mViewModelItem->setFolderViewItem(this);
-}
+	}
 }
 
 BOOL LLFolderViewItem::postBuild()
@@ -624,6 +648,22 @@ BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	return handled;
 }
 
+void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color)
+{
+	//--------------------------------------------------------------------------------//
+	// Draw open folder arrow
+	//
+	const S32 TOP_PAD = default_params.item_top_pad;
+
+	if (hasVisibleChildren() || getViewModelItem()->hasChildren())
+	{
+		LLUIImage* arrow_image = default_params.folder_arrow_image;
+		gl_draw_scaled_rotated_image(
+			mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
+			mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), fg_color);
+	}
+}
+
 void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, 
                                                         const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
 {
@@ -734,18 +774,6 @@ void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y
 
 void LLFolderViewItem::draw()
 {
-	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-    static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
-    static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
-    static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
-    static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);	
-	static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
-	static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
-	static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
-	static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
-	static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
-	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
-	
     const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
     const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
 
@@ -756,17 +784,7 @@ void LLFolderViewItem::draw()
 
     getViewModelItem()->update();
 
-	//--------------------------------------------------------------------------------//
-	// Draw open folder arrow
-	//
-	if (hasVisibleChildren() || getViewModelItem()->hasChildren())
-	{
-		LLUIImage* arrow_image = default_params.folder_arrow_image;
-		gl_draw_scaled_rotated_image(
-			mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
-			mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), sFgColor);
-	}
-
+    drawOpenFolderArrow(default_params, sFgColor);
 
     drawHighlight(show_context, filled, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
 
@@ -877,6 +895,22 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
 {
 }
 
+void LLFolderViewFolder::updateLabelRotation()
+{
+	if (mAutoOpenCountdown != 0.f)
+	{
+		mControlLabelRotation = mAutoOpenCountdown * -90.f;
+	}
+	else if (isOpen())
+	{
+		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
+	}
+	else
+	{
+		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
+	}
+}
+
 // Destroys the object
 LLFolderViewFolder::~LLFolderViewFolder( void )
 {
@@ -1832,18 +1866,7 @@ BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 
 void LLFolderViewFolder::draw()
 {
-	if (mAutoOpenCountdown != 0.f)
-	{
-		mControlLabelRotation = mAutoOpenCountdown * -90.f;
-	}
-	else if (isOpen())
-	{
-		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
-	}
-	else
-	{
-		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
-	}
+	updateLabelRotation();
 
 	LLFolderViewItem::draw();
 
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index b7e0091aca..d4002c3184 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -116,6 +116,19 @@ protected:
 								mAllowOpen,
 								mSelectPending;
 
+	// For now assuming all colors are the same in derived classes.
+	static LLUIColor			sFgColor;
+	static LLUIColor			sHighlightBgColor;
+	static LLUIColor			sHighlightFgColor;
+	static LLUIColor			sFocusOutlineColor;
+	static LLUIColor			sMouseOverColor;
+	static LLUIColor			sFilterBGColor;
+	static LLUIColor			sFilterTextColor;
+	static LLUIColor			sSuffixColor;
+	static LLUIColor			sLibraryColor;
+	static LLUIColor			sLinkColor;
+	static LLUIColor			sSearchStatusColor;
+
 	// this is an internal method used for adding items to folders. A
 	// no-op at this level, but reimplemented in derived classes.
 	virtual void addItem(LLFolderViewItem*) { }
@@ -247,6 +260,7 @@ public:
 
 	//	virtual void handleDropped();
 	virtual void draw();
+	void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
     void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
     void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -274,6 +288,8 @@ protected:
 	LLFolderViewFolder( const LLFolderViewItem::Params& );
 	friend class LLUICtrlFactory;
 
+	void updateLabelRotation();
+
 public:
 	typedef std::list<LLFolderViewItem*> items_t;
 	typedef std::list<LLFolderViewFolder*> folders_t;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 394a830e5e..a4733bb693 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -72,136 +72,19 @@ BOOL LLConversationViewSession::postBuild()
 
 void LLConversationViewSession::draw()
 {
-// *TODO Seth PE: remove the code duplicated from LLFolderViewFolder::draw()
-// ***** LLFolderViewFolder::draw() code begin *****
-	if (mAutoOpenCountdown != 0.f)
-	{
-		mControlLabelRotation = mAutoOpenCountdown * -90.f;
-	}
-	else if (isOpen())
-	{
-		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
-	}
-	else
-	{
-		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
-	}
-// ***** LLFolderViewFolder::draw() code end *****
-
-// *TODO Seth PE: remove the code duplicated from LLFolderViewItem::draw()
-// ***** LLFolderViewItem::draw() code begin *****
-
-	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
-	static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
-	static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+	getViewModelItem()->update();
 
 	const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-	const S32 TOP_PAD = default_params.item_top_pad;
-	const S32 FOCUS_LEFT = 1;
+	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
 
-	getViewModelItem()->update();
+	// update the rotation angle of open folder arrow
+	updateLabelRotation();
 
-	//--------------------------------------------------------------------------------//
-	// Draw open folder arrow
-	//
-	if (hasVisibleChildren() || getViewModelItem()->hasChildren())
-	{
-		LLUIImage* arrow_image = default_params.folder_arrow_image;
-		gl_draw_scaled_rotated_image(
-			mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
-			mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), sFgColor);
-	}
+	drawOpenFolderArrow(default_params, sFgColor);
 
+	// draw highlight for selected items
+	drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
 
-	//--------------------------------------------------------------------------------//
-	// Draw highlight for selected items
-	//
-	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
-	const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
-	const S32 focus_top = getRect().getHeight();
-	const S32 focus_bottom = getRect().getHeight() - mItemHeight;
-	const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
-	if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		LLColor4 bg_color = sHighlightBgColor;
-		if (!mIsCurSelection)
-		{
-			// do time-based fade of extra objects
-			F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
-			if (getRoot() && getRoot()->getShowSingleSelection())
-			{
-				// fading out
-				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
-			}
-			else
-			{
-				// fading in
-				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
-			}
-		}
-		gl_rect_2d(FOCUS_LEFT,
-				   focus_top,
-				   getRect().getWidth() - 2,
-				   focus_bottom,
-				   bg_color, filled);
-		if (mIsCurSelection)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_top,
-					   getRect().getWidth() - 2,
-					   focus_bottom,
-					   sFocusOutlineColor, FALSE);
-		}
-		if (folder_open)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_bottom + 1, // overlap with bottom edge of above rect
-					   getRect().getWidth() - 2,
-					   0,
-					   sFocusOutlineColor, FALSE);
-			if (show_context)
-			{
-				gl_rect_2d(FOCUS_LEFT,
-						   focus_bottom + 1,
-						   getRect().getWidth() - 2,
-						   0,
-						   sHighlightBgColor, TRUE);
-			}
-		}
-	}
-	else if (mIsMouseOverTitle)
-	{
-		gl_rect_2d(FOCUS_LEFT,
-			focus_top,
-			getRect().getWidth() - 2,
-			focus_bottom,
-			sMouseOverColor, FALSE);
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Draw DragNDrop highlight
-	//
-	if (mDragAndDropTarget)
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gl_rect_2d(FOCUS_LEFT,
-				   focus_top,
-				   getRect().getWidth() - 2,
-				   focus_bottom,
-				   sHighlightBgColor, FALSE);
-		if (folder_open)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_bottom + 1, // overlap with bottom edge of above rect
-					   getRect().getWidth() - 2,
-					   0,
-					   sHighlightBgColor, FALSE);
-		}
-		mDragAndDropTarget = FALSE;
-	}
-// ***** LLFolderViewItem::draw() code end *****
 
 	// draw children if root folder, or any other folder that is open or animating to closed state
 	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this)
-- 
cgit v1.2.3


From 976a2f5a442150ef89cff6b39450eabbca956d0f Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Wed, 26 Sep 2012 20:45:18 +0300
Subject: CHUI-344 FIXED (LLConversationViewSession: enable icon update)

- This commit also fixes CHUI-345 CHUI-346
---
 indra/newview/llconversationview.cpp               |  84 ++++++++++++++++++++-
 indra/newview/llconversationview.h                 |  13 +++-
 indra/newview/llnearbychat.cpp                     |   1 +
 indra/newview/lloutputmonitorctrl.cpp              |  20 ++++-
 indra/newview/lloutputmonitorctrl.h                |   3 +
 .../default/textures/icons/nearby_chat_icon.png    | Bin 0 -> 793 bytes
 indra/newview/skins/default/textures/textures.xml  |   2 +
 .../xui/en/panel_conversation_list_item.xml        |  26 ++++++-
 8 files changed, 140 insertions(+), 9 deletions(-)
 create mode 100644 indra/newview/skins/default/textures/icons/nearby_chat_icon.png

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index a4733bb693..ab15e20d89 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -30,10 +30,12 @@
 #include "llconversationview.h"
 
 #include <boost/bind.hpp>
+#include "llagentdata.h"
 #include "llconversationmodel.h"
 #include "llimconversation.h"
 #include "llimfloatercontainer.h"
 #include "llfloaterreg.h"
+#include "llgroupiconctrl.h"
 #include "lluictrlfactory.h"
 
 //
@@ -51,20 +53,79 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	LLFolderViewFolder(p),
 	mContainer(p.container),
 	mItemPanel(NULL),
-	mSessionTitle(NULL)
+	mCallIconLayoutPanel(NULL),
+	mSessionTitle(NULL),
+	mSpeakingIndicator(NULL)
 {
 }
 
+LLConversationViewSession::~LLConversationViewSession()
+{
+	mActiveVoiceChannelConnection.disconnect();
+}
+
 BOOL LLConversationViewSession::postBuild()
 {
 	LLFolderViewItem::postBuild();
 
 	mItemPanel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_conversation_list_item.xml", NULL, LLPanel::child_registry_t::instance());
-
 	addChild(mItemPanel);
 
+	mCallIconLayoutPanel = mItemPanel->getChild<LLPanel>("call_icon_panel");
 	mSessionTitle = mItemPanel->getChild<LLTextBox>("conversation_title");
 
+	mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewSession::onCurrentVoiceSessionChanged, this, _1));
+	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicatorn");
+
+	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+	if (vmi)
+	{
+		switch(vmi->getType())
+		{
+		case LLConversationItem::CONV_PARTICIPANT:
+		case LLConversationItem::CONV_SESSION_1_ON_1:
+		{
+			LLIMModel::LLIMSession* session=  LLIMModel::instance().findIMSession(vmi->getUUID());
+			if (session)
+			{
+				LLAvatarIconCtrl* icon = mItemPanel->getChild<LLAvatarIconCtrl>("avatar_icon");
+				icon->setVisible(true);
+				icon->setValue(session->mOtherParticipantID);
+				mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID);
+				mSpeakingIndicator->setShowParticipantsTalking(true);
+			}
+			break;
+		}
+		case LLConversationItem::CONV_SESSION_AD_HOC:
+		{
+			LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
+			icon->setVisible(true);
+			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID());
+			mSpeakingIndicator->setShowParticipantsTalking(true);
+		}
+		case LLConversationItem::CONV_SESSION_GROUP:
+		{
+			LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
+			icon->setVisible(true);
+			icon->setValue(vmi->getUUID());
+			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID());
+			mSpeakingIndicator->setShowParticipantsTalking(true);
+			break;
+		}
+		case LLConversationItem::CONV_SESSION_NEARBY:
+		{
+			LLIconCtrl* icon = mItemPanel->getChild<LLIconCtrl>("nearby_chat_icon");
+			icon->setVisible(true);
+			mSpeakingIndicator->setSpeakerId(gAgentID);
+			mSpeakingIndicator->setShowParticipantsTalking(true);
+			break;
+		}
+
+		default:
+			break;
+		}
+	}
+
 	refresh();
 
 	return TRUE;
@@ -188,6 +249,25 @@ void LLConversationViewSession::refresh()
 	LLFolderViewFolder::refresh();
 }
 
+void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id)
+{
+	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+
+	if (vmi)
+	{
+		bool is_active = vmi->getUUID() == session_id;
+		bool is_nearby = vmi->getType() == LLConversationItem::CONV_SESSION_NEARBY;
+
+		if (is_nearby)
+		{
+			mSpeakingIndicator->setSpeakerId(is_active ? gAgentID : LLUUID::null);
+		}
+
+		mSpeakingIndicator->switchIndicator(is_active);
+		mCallIconLayoutPanel->setVisible(is_active);
+	}
+}
+
 //
 // Implementation of conversations list participant (avatar) widgets
 //
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 0b98c34c73..dbc7f3b1bb 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -57,7 +57,7 @@ protected:
 	LLIMFloaterContainer* mContainer;
 	
 public:
-	virtual ~LLConversationViewSession( void ) { }
+	virtual ~LLConversationViewSession();
 	virtual void selectItem();	
 
 	/*virtual*/ BOOL postBuild();
@@ -71,8 +71,15 @@ public:
 	virtual void refresh();
 
 private:
-	LLPanel*	mItemPanel;
-	LLTextBox*	mSessionTitle;
+
+	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
+
+	LLPanel*				mItemPanel;
+	LLPanel*				mCallIconLayoutPanel;
+	LLTextBox*				mSessionTitle;
+	LLOutputMonitorCtrl*	mSpeakingIndicator;
+
+	boost::signals2::connection mActiveVoiceChannelConnection;
 };
 
 // Implementation of conversations list participant (avatar) widgets
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 71c4938ae9..75c691d99b 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -110,6 +110,7 @@ BOOL LLNearbyChat::postBuild()
 	mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
 	mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
 	mInputEditor->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this));
+	mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle"));
 
 //	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
 //	mOutputMonitor->setVisible(FALSE);
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 096e714981..d48826779c 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -74,7 +74,8 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
 	mSpeakerId(p.speaker_id),
 	mIsAgentControl(false),
 	mIsSwitchDirty(false),
-	mShouldSwitchOn(false)
+	mShouldSwitchOn(false),
+	mShowParticipantsTalking(false)
 {
 	//static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
 	//static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
@@ -157,6 +158,23 @@ void LLOutputMonitorCtrl::draw()
 		}
 	}
 
+	if ((mPower == 0.f && !mIsTalking) && mShowParticipantsTalking)
+	{
+		std::set<LLUUID> participant_uuids;
+		LLVoiceClient::instance().getParticipantList(participant_uuids);
+		std::set<LLUUID>::const_iterator part_it = participant_uuids.begin();
+
+		F32 power = 0;
+		for (; part_it != participant_uuids.end(); ++part_it)
+		{
+			if (power = LLVoiceClient::instance().getCurrentPower(*part_it))
+			{
+				mPower = power;
+				break;
+			}
+		}
+	}
+
 	LLPointer<LLUIImage> icon;
 	if (mIsMuted)
 	{
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 7b02e84744..44d4d6f64b 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -82,6 +82,8 @@ public:
 
 	void			setIsTalking(bool val) { mIsTalking = val; }
 
+	void			setShowParticipantsTalking(bool show) { mShowParticipantsTalking = show; }
+
 	/**
 	 * Sets avatar UUID to interact with voice channel.
 	 *
@@ -132,6 +134,7 @@ private:
 	bool			mIsAgentControl;
 	bool			mIsMuted;
 	bool			mIsTalking;
+	bool			mShowParticipantsTalking;
 	LLPointer<LLUIImage> mImageMute;
 	LLPointer<LLUIImage> mImageOff;
 	LLPointer<LLUIImage> mImageOn;
diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png
new file mode 100644
index 0000000000..7c3ad40381
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 47b0c12fa0..a124041565 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -363,6 +363,8 @@ with the same filename but different name
   <texture name="NavBar_BG_NoFav_Bevel" file_name="navbar/NavBar_BG_NoFav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
   <texture name="NavBar_BG_NoNav_Bevel" file_name="navbar/NavBar_BG_NoNav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
 
+  <texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" />
+
   <texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" />
 
   <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
index 375ea79ebe..56056ed560 100644
--- a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
@@ -13,13 +13,33 @@
      layout="topleft"
      left="5"
      top="2"
+     visible="false"
      width="20" />
+    <group_icon
+     follows="top|left"
+     height="20"
+     default_icon_name="Generic_Group"
+     layout="topleft"
+     left="5"
+     top="2"
+     visible="false"
+     width="20" />
+    <icon
+     follows="top|left"
+     height="20"
+     image_name="Nearby_chat_icon"
+     layout="topleft"
+     left="5"
+     name="nearby_chat_icon"
+     top="2"
+     visible="false"
+     width="20"/>
     <layout_stack
      animate="false"
      follows="all"
      height="24"
      layout="topleft"
-     left_pad="5"
+     left="30"
      mouse_opaque="false"
      name="conversation_item_stack"
      orientation="horizontal"
@@ -36,7 +56,7 @@
             <icon
              height="20"
              follows="top|right|left"
-             image_name="Conv_toolbar_hang_up"
+             image_name="Conv_toolbar_open_call"
              layout="topleft"
              left="0"
              name="selected_icon"
@@ -70,7 +90,7 @@
 		     layout="topleft"
 		     left_pad="5"
  		     mouse_opaque="true"
- 		     name="speaking_indicator"
+ 		     name="speaking_indicatorn"
  		     visible="false"
  		     width="20" />
         </layout_panel>
-- 
cgit v1.2.3


From 9e1ea5a1652528dead811dee8904ae8a6833d163 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 26 Sep 2012 12:05:27 -0700
Subject: CHUI-364 : WIP : Suppress unused code

---
 indra/newview/llimfloatercontainer.cpp | 50 ----------------------------------
 indra/newview/llimfloatercontainer.h   |  1 -
 2 files changed, 51 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 14d40d4685..e64247cd60 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -661,56 +661,6 @@ void LLIMFloaterContainer::setSortOrder(const LLConversationSort& order)
 	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
 }
 
-void LLIMFloaterContainer::repositioningWidgets()
-{
-	if (!mInitialized)
-	{
-		return;
-	}
-
-	if (!mConversationsPane->isCollapsed())
-	{
-		S32 list_width = (mConversationsPane->getRect()).getWidth();
-		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", list_width);
-	}
-	LLRect panel_rect = mConversationsListPanel->getRect();
-	S32 item_height = 16;
-	int index = 0;
-	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
-		 widget_it != mConversationsWidgets.end();
-		 widget_it++)
-	{
-		LLFolderViewFolder* widget = dynamic_cast<LLFolderViewFolder*>(widget_it->second);
-		widget->setVisible(TRUE);
-		widget->setRect(LLRect(0,
-							   panel_rect.getHeight() - item_height*index,
-							   panel_rect.getWidth(),
-							   panel_rect.getHeight() - item_height*(index+1)));
-		index++;
-		// Reposition the children as well
-		// Merov : This is highly suspiscious but gets the debug hack to work. This needs to be revised though.
-		if (widget->getItemsCount() != 0)
-		{
-			BOOL is_open = widget->isOpen();
-			widget->setOpen(TRUE);
-			LLFolderViewFolder::items_t::const_iterator current = widget->getItemsBegin();
-			LLFolderViewFolder::items_t::const_iterator end = widget->getItemsEnd();
-			while (current != end)
-			{
-				LLFolderViewItem* item = (*current);
-				item->setVisible(TRUE);
-				item->setRect(LLRect(0,
-									   panel_rect.getHeight() - item_height*index,
-									   panel_rect.getWidth(),
-									   panel_rect.getHeight() - item_height*(index+1)));
-				index++;
-				current++;
-			}
-			widget->setOpen(is_open);
-		}
-	}
-}
-
 void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
 {
 	LLFolderViewItem* widget = mConversationsWidgets[session_id];
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index e8d185297c..070feb3273 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -100,7 +100,6 @@ private:
 	void collapseConversationsPane(bool collapse);
 
 	void updateState(bool collapse, S32 delta_width);
-	void repositioningWidgets();
 
 	void onAddButtonClicked();
 	void onAvatarPicked(const uuid_vec_t& ids);
-- 
cgit v1.2.3


From 30ea13381884bca7a07e2bca16e5bde0ccacb530 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 26 Sep 2012 17:30:52 -0700
Subject: CHUI-344 : Fix Mac build issue introduced by previous fix attempt

---
 indra/newview/lloutputmonitorctrl.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index d48826779c..1c412b15f7 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -167,7 +167,8 @@ void LLOutputMonitorCtrl::draw()
 		F32 power = 0;
 		for (; part_it != participant_uuids.end(); ++part_it)
 		{
-			if (power = LLVoiceClient::instance().getCurrentPower(*part_it))
+			power = LLVoiceClient::instance().getCurrentPower(*part_it);
+			if (power)
 			{
 				mPower = power;
 				break;
-- 
cgit v1.2.3


From f7f15900ea4c61c499427a8b6416dc08e9a972f7 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Thu, 27 Sep 2012 17:46:11 +0300
Subject: CHUI-346 ADDITIONAL FIX (LLConversationViewSession: enable current
 voice channel indicator)

- When voice initialized show voice channel indicator for nearby chat session
---
 indra/newview/llconversationview.cpp  | 58 +++++++++++++++++++++++++++++------
 indra/newview/llconversationview.h    |  6 ++++
 indra/newview/lloutputmonitorctrl.cpp |  7 +++--
 indra/newview/lloutputmonitorctrl.h   |  6 ++--
 4 files changed, 61 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index ab15e20d89..c2898d9a47 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -45,6 +45,30 @@ static LLDefaultChildRegistry::Register<LLConversationViewSession> r_conversatio
 
 const LLColor4U DEFAULT_WHITE(255, 255, 255);
 
+class LLNearbyVoiceClientStatusObserver : public LLVoiceClientStatusObserver
+{
+public:
+
+	LLNearbyVoiceClientStatusObserver(LLConversationViewSession* conv)
+	:	conversation(conv)
+	{}
+
+	virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal)
+	{
+		if (conversation
+		   && status != STATUS_JOINING
+		   && status != STATUS_LEFT_CHANNEL
+		   && LLVoiceClient::getInstance()->voiceEnabled()
+		   && LLVoiceClient::getInstance()->isVoiceWorking())
+		{
+			conversation->showVoiceIndicator();
+		}
+	}
+
+private:
+	LLConversationViewSession* conversation;
+};
+
 LLConversationViewSession::Params::Params() :	
 	container()
 {}
@@ -55,13 +79,19 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mItemPanel(NULL),
 	mCallIconLayoutPanel(NULL),
 	mSessionTitle(NULL),
-	mSpeakingIndicator(NULL)
+	mSpeakingIndicator(NULL),
+	mVoiceClientObserver(NULL)
 {
 }
 
 LLConversationViewSession::~LLConversationViewSession()
 {
 	mActiveVoiceChannelConnection.disconnect();
+
+	if(LLVoiceClient::instanceExists() && mVoiceClientObserver)
+	{
+		LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
+	}
 }
 
 BOOL LLConversationViewSession::postBuild()
@@ -91,8 +121,7 @@ BOOL LLConversationViewSession::postBuild()
 				LLAvatarIconCtrl* icon = mItemPanel->getChild<LLAvatarIconCtrl>("avatar_icon");
 				icon->setVisible(true);
 				icon->setValue(session->mOtherParticipantID);
-				mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID);
-				mSpeakingIndicator->setShowParticipantsTalking(true);
+				mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID, true);
 			}
 			break;
 		}
@@ -100,27 +129,28 @@ BOOL LLConversationViewSession::postBuild()
 		{
 			LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
 			icon->setVisible(true);
-			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID());
-			mSpeakingIndicator->setShowParticipantsTalking(true);
+			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
 		}
 		case LLConversationItem::CONV_SESSION_GROUP:
 		{
 			LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
 			icon->setVisible(true);
 			icon->setValue(vmi->getUUID());
-			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID());
-			mSpeakingIndicator->setShowParticipantsTalking(true);
+			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
 			break;
 		}
 		case LLConversationItem::CONV_SESSION_NEARBY:
 		{
 			LLIconCtrl* icon = mItemPanel->getChild<LLIconCtrl>("nearby_chat_icon");
 			icon->setVisible(true);
-			mSpeakingIndicator->setSpeakerId(gAgentID);
-			mSpeakingIndicator->setShowParticipantsTalking(true);
+			mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true);
+			if(LLVoiceClient::instanceExists())
+			{
+				LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
+				LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver);
+			}
 			break;
 		}
-
 		default:
 			break;
 		}
@@ -232,6 +262,14 @@ LLConversationViewParticipant* LLConversationViewSession::findParticipant(const
 	return (iter == getItemsEnd() ? NULL : participant);
 }
 
+void LLConversationViewSession::showVoiceIndicator()
+{
+	if (LLVoiceChannel::getCurrentVoiceChannel()->getSessionID().isNull())
+	{
+		mCallIconLayoutPanel->setVisible(true);
+	}
+}
+
 void LLConversationViewSession::refresh()
 {
 	// Refresh the session view from its model data
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index dbc7f3b1bb..064239eeb1 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -38,6 +38,8 @@ class LLIMFloaterContainer;
 class LLConversationViewSession;
 class LLConversationViewParticipant;
 
+class LLVoiceClientStatusObserver;
+
 // Implementation of conversations list session widgets
 
 class LLConversationViewSession : public LLFolderViewFolder
@@ -68,6 +70,8 @@ public:
 	void setVisibleIfDetached(BOOL visible);
 	LLConversationViewParticipant* findParticipant(const LLUUID& participant_id);
 
+	void showVoiceIndicator();
+
 	virtual void refresh();
 
 private:
@@ -79,6 +83,8 @@ private:
 	LLTextBox*				mSessionTitle;
 	LLOutputMonitorCtrl*	mSpeakingIndicator;
 
+	LLVoiceClientStatusObserver* mVoiceClientObserver;
+
 	boost::signals2::connection mActiveVoiceChannelConnection;
 };
 
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 1c412b15f7..c3cbca68c7 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -75,7 +75,7 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
 	mIsAgentControl(false),
 	mIsSwitchDirty(false),
 	mShouldSwitchOn(false),
-	mShowParticipantsTalking(false)
+	mShowParticipantsSpeaking(false)
 {
 	//static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
 	//static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
@@ -158,7 +158,7 @@ void LLOutputMonitorCtrl::draw()
 		}
 	}
 
-	if ((mPower == 0.f && !mIsTalking) && mShowParticipantsTalking)
+	if ((mPower == 0.f && !mIsTalking) && mShowParticipantsSpeaking)
 	{
 		std::set<LLUUID> participant_uuids;
 		LLVoiceClient::instance().getParticipantList(participant_uuids);
@@ -272,7 +272,7 @@ BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
-void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/)
+void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */)
 {
 	if (speaker_id.isNull() && mSpeakerId.notNull())
 	{
@@ -287,6 +287,7 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
 		LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
 	}
 
+	mShowParticipantsSpeaking = show_other_participants_speaking;
 	mSpeakerId = speaker_id;
 	LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this, session_id);
 
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 44d4d6f64b..1fa6ef41f8 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -82,7 +82,7 @@ public:
 
 	void			setIsTalking(bool val) { mIsTalking = val; }
 
-	void			setShowParticipantsTalking(bool show) { mShowParticipantsTalking = show; }
+	void			setShowParticipantsSpeaking(bool show) { mShowParticipantsSpeaking = show; }
 
 	/**
 	 * Sets avatar UUID to interact with voice channel.
@@ -92,7 +92,7 @@ public:
 	 *		If this parameter is set registered indicator will be shown only in voice channel
 	 *		which has the same session id (EXT-5562).
 	 */
-	void			setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null);
+	void			setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null, bool show_other_participants_speaking = false);
 
 	//called by mute list
 	virtual void onChange();
@@ -134,7 +134,7 @@ private:
 	bool			mIsAgentControl;
 	bool			mIsMuted;
 	bool			mIsTalking;
-	bool			mShowParticipantsTalking;
+	bool			mShowParticipantsSpeaking;
 	LLPointer<LLUIImage> mImageMute;
 	LLPointer<LLUIImage> mImageOff;
 	LLPointer<LLUIImage> mImageOn;
-- 
cgit v1.2.3


From 6daf27cd0f89e324f6fa67792e60bb8452af5adb Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 27 Sep 2012 17:14:15 +0300
Subject: CHUI-352 FIXED (Viewer crash when dropping a worn attachment):
 getting the item's id  before destruction corresponding viewmodel's item

---
 indra/newview/llinventorypanel.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 2a84616ddf..a77b57638f 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -441,8 +441,9 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			handled = true;
 			if (model_item && view_item && viewmodel_item)
 			{
+				const LLUUID& idp = viewmodel_item->getUUID();
 				view_item->destroyView();
-				removeItemID(viewmodel_item->getUUID());
+				removeItemID(idp);
 			}
 			view_item = buildNewViews(item_id);
 			viewmodel_item = 
-- 
cgit v1.2.3


From 483cbd74d78b8fa7ce94e3d3c7d264bcdaa331b5 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 27 Sep 2012 20:09:22 +0300
Subject: CHUI-165 FIXED Add access to Conversation Log and Chat History from
 the People floater.

---
 indra/newview/llavataractions.cpp                              |  6 ++++++
 indra/newview/llavataractions.h                                |  5 +++++
 indra/newview/llpanelpeoplemenus.cpp                           |  1 +
 .../newview/skins/default/xui/en/menu_people_friends_view.xml  |  8 ++++++++
 indra/newview/skins/default/xui/en/menu_people_nearby.xml      | 10 +++++++++-
 5 files changed, 29 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 42a0376774..a76dbcac53 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -897,6 +897,12 @@ void LLAvatarActions::inviteToGroup(const LLUUID& id)
 	}
 }
 
+// static
+void LLAvatarActions::viewChatHistory(const LLUUID& id)
+{
+	LLFloaterReg::showInstance("preview_conversation", id, true);
+}
+
 //== private methods ========================================================================================
 
 // static
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 473b9cecc3..6e60f624ad 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -218,6 +218,11 @@ public:
 	 */
 	static void buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string);
 
+	/**
+	 * Opens the chat history for avatar
+	 */
+	static void viewChatHistory(const LLUUID& id);
+
 	static std::set<LLUUID> getInventorySelectedUUIDs();
 
 private:
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index c9eebe24d3..899771f3b9 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -69,6 +69,7 @@ LLContextMenu* NearbyMenu::createMenu()
 		registrar.add("Avatar.Pay",				boost::bind(&LLAvatarActions::pay,						id));
 		registrar.add("Avatar.BlockUnblock",	boost::bind(&LLAvatarActions::toggleBlock,				id));
 		registrar.add("Avatar.InviteToGroup",	boost::bind(&LLAvatarActions::inviteToGroup,			id));
+		registrar.add("Avatar.Calllog",			boost::bind(&LLAvatarActions::viewChatHistory,			id));
 
 		enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem,	this, _2));
 		enable_registrar.add("Avatar.CheckItem",  boost::bind(&NearbyMenu::checkContextMenuItem,	this, _2));
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
index eab7b8c085..dde9432867 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -40,4 +40,12 @@
      function="CheckControl"
      parameter="FriendsListShowPermissions" />
   </menu_item_check>
+  <menu_item_check name="view_conversation" label="View Conversation Log...">
+    <menu_item_check.on_check
+     function="Floater.Visible"
+     parameter="conversation" />
+    <menu_item_check.on_click
+     function="Floater.Toggle"
+     parameter="conversation" />
+  </menu_item_check>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
index b7c9ab1fe3..8014e81469 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -36,6 +36,14 @@
          parameter="can_call" />
     </menu_item_call>
     <menu_item_separator />
+    <menu_item_call
+     label="View chat history..."
+     layout="topleft"
+     name="Chat history">
+        <menu_item_call.on_click
+         function="Avatar.Calllog" />
+    </menu_item_call>
+    <menu_item_separator />
     <menu_item_call
      label="Add Friend"
      layout="topleft"
@@ -101,5 +109,5 @@
          function="Avatar.EnableItem"
          parameter="can_block" />
     </menu_item_check>
-
+    <menu_item_separator />
 </context_menu>
-- 
cgit v1.2.3


From 78e6b910a5012352ab265e52a78b0d340ac7ce27 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 27 Sep 2012 20:04:26 +0300
Subject: CHUI-370, CHUI-372 FIXED Viewer crash when voice calling another user
 from people panel then opening conversation floater or when starting a IM
 chat when conversation floater has not been previously opened: connecting
 floater to the host postponed until the end of its initialization

---
 indra/newview/llnearbychat.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 75c691d99b..2982f30102 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -122,8 +122,6 @@ BOOL LLNearbyChat::postBuild()
 	// it is used for show the item's name in the conversations list
 	setTitle(LLTrans::getString("NearbyChatTitle"));
 
-	addToHost();
-
 	//for menu
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
@@ -312,6 +310,7 @@ void LLNearbyChat::addToHost()
 // virtual
 void LLNearbyChat::onOpen(const LLSD& key)
 {
+	addToHost();
 	LLIMConversation::onOpen(key);
 	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 }
-- 
cgit v1.2.3


From 3e3735c16b47402d8fc2da8afa6086638fb5b948 Mon Sep 17 00:00:00 2001
From: Paul ProductEngine <pguslisty@productengine.com>
Date: Fri, 28 Sep 2012 15:02:31 +0300
Subject: CHUI-345 ADDITIONAL FIX (LLConversationViewSession: enable speaking
 indicator)

- Clicking on the conversation speaking icon brings up the volume floater for voice conversations
---
 indra/newview/CMakeLists.txt                       |  2 +
 indra/newview/llfloaterchatvoicevolume.cpp         | 26 ++++++++++++
 indra/newview/llfloaterchatvoicevolume.h           | 26 ++++++++++++
 indra/newview/lloutputmonitorctrl.cpp              |  6 ++-
 indra/newview/llviewerfloaterreg.cpp               |  2 +
 .../default/xui/en/floater_voice_chat_volume.xml   | 48 ++++++++++++++++++++++
 6 files changed, 109 insertions(+), 1 deletion(-)
 create mode 100644 indra/newview/llfloaterchatvoicevolume.cpp
 create mode 100644 indra/newview/llfloaterchatvoicevolume.h
 create mode 100644 indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b94c33587b..ec1562a4c1 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -197,6 +197,7 @@ set(viewer_SOURCE_FILES
     llfloaterbuycurrencyhtml.cpp
     llfloaterbuyland.cpp
     llfloatercamera.cpp
+    llfloaterchatvoicevolume.cpp
     llfloatercolorpicker.cpp
     llfloaterconversationlog.cpp
     llfloaterconversationpreview.cpp
@@ -781,6 +782,7 @@ set(viewer_HEADER_FILES
     llfloaterbuycurrencyhtml.h
     llfloaterbuyland.h
     llfloatercamera.h
+    llfloaterchatvoicevolume.h
     llfloatercolorpicker.h
     llfloaterconversationlog.h
     llfloaterconversationpreview.h
diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
new file mode 100644
index 0000000000..d10c3c6504
--- /dev/null
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -0,0 +1,26 @@
+/*
+ * llfloaterchatvoicevolume.cpp
+ *
+ *  Created on: Sep 27, 2012
+ *      Author: pguslisty
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterchatvoicevolume.h"
+
+LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
+: LLInspect(key)
+{
+}
+
+void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
+{
+	LLInspect::onOpen(key);
+	LLUI::positionViewNearMouse(this);
+}
+
+LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
+{
+	LLTransientFloaterMgr::getInstance()->removeControlView(this);
+};
diff --git a/indra/newview/llfloaterchatvoicevolume.h b/indra/newview/llfloaterchatvoicevolume.h
new file mode 100644
index 0000000000..0aeab7874c
--- /dev/null
+++ b/indra/newview/llfloaterchatvoicevolume.h
@@ -0,0 +1,26 @@
+/*
+ * llfloaterchatvoicevolume.h
+ *
+ *  Created on: Sep 27, 2012
+ *      Author: pguslisty
+ */
+
+#ifndef LLFLOATERCHATVOICEVOLUME_H_
+#define LLFLOATERCHATVOICEVOLUME_H_
+
+#include "llinspect.h"
+#include "lltransientfloatermgr.h"
+
+class LLFloaterChatVoiceVolume : public LLInspect, LLTransientFloater
+{
+public:
+
+	LLFloaterChatVoiceVolume(const LLSD& key);
+	virtual ~LLFloaterChatVoiceVolume();
+
+	virtual void onOpen(const LLSD& key);
+
+	/*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
+};
+
+#endif /* LLFLOATERCHATVOICEVOLUME_H_ */
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index c3cbca68c7..4a9a50d96a 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -264,10 +264,14 @@ void LLOutputMonitorCtrl::draw()
 // virtual
 BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	if (mSpeakerId != gAgentID)
+	if (mSpeakerId != gAgentID && !mShowParticipantsSpeaking)
 	{
 		LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId));
 	}
+	else if(mShowParticipantsSpeaking)
+	{
+		LLFloaterReg::showInstance("chat_voice", LLSD());
+	}
 
 	return TRUE;
 }
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 927ee8f380..4cd5ecc754 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -50,6 +50,7 @@
 #include "llfloaterbump.h"
 #include "llfloaterbvhpreview.h"
 #include "llfloatercamera.h"
+#include "llfloaterchatvoicevolume.h"
 #include "llfloaterconversationlog.h"
 #include "llfloaterconversationpreview.h"
 #include "llfloaterdeleteenvpreset.h"
@@ -192,6 +193,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
 
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
+	LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
 	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
 	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
diff --git a/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000..5c71fd3bc6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+
+<floater
+ legacy_header_height="25"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="90"
+ layout="topleft"
+ name="floater_voice_volume"
+ single_instance="true"
+ sound_flags="0"
+ title="VOICE CHAT VOLUME"
+ visible="true"
+ width="245">
+	<slider
+		control_name="AudioLevelVoice"
+		disabled_control="MuteAudio"
+		follows="left|top"
+		height="16"
+		increment="0.025"
+		initial_value="0.5"
+		label="Voice Chat"
+		label_width="50"
+		layout="topleft"
+		left="15"
+		top="50"
+		name="chat_voice_volume"
+		show_text="false"
+		slider_label.halign="right"
+		volume="true"
+		width="200">
+	</slider>
+	<button
+		control_name="MuteVoice"
+		disabled_control="MuteAudio"
+		follows="top|left"
+		height="16"
+		image_selected="AudioMute_Off"
+		image_unselected="Audio_Off"
+		is_toggle="true"
+		layout="topleft"
+		left_pad="5"
+		name="mute_audio"
+		tab_stop="false"
+		width="16" />
+</floater>
\ No newline at end of file
-- 
cgit v1.2.3


From 8b2ed2e2050fcb8836be120902f44417613adb13 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 28 Sep 2012 18:22:00 +0300
Subject: CHUI-370, CHUI-372 ADDITIONAL FIX (Viewer crash when voice calling
 another user from people panel then opening conversation floater or when
 starting a IM chat when conversation floater has not been previously opened):
 fixed nearby chat positioning

---
 indra/newview/llimfloatercontainer.cpp | 1 +
 indra/newview/llnearbychat.cpp         | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)
 mode change 100755 => 100644 indra/newview/llimfloatercontainer.cpp

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
old mode 100755
new mode 100644
index e64247cd60..a74ebdae7a
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -432,6 +432,7 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 			// *TODO: find a way to move this to XML as a default panel or something like that
 			LLSD name("nearby_chat");
 			LLFloaterReg::toggleInstanceOrBringToFront(name);
+			LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat")->addToHost();
 		}
 	}
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 2982f30102..4b35092f2d 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -310,7 +310,6 @@ void LLNearbyChat::addToHost()
 // virtual
 void LLNearbyChat::onOpen(const LLSD& key)
 {
-	addToHost();
 	LLIMConversation::onOpen(key);
 	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 }
-- 
cgit v1.2.3


From 0651e10afff81a6e32828c122753d87b8503a79b Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 28 Sep 2012 11:15:45 -0700
Subject: CHUI-342, CHUI-366 and CHUI-367 : WIP : Allow a NO_TOOLTIP value for
 tooltips, update display/user names and sort on display/user names

---
 indra/llui/llview.cpp                  | 22 ++++++++++++----------
 indra/llui/llview.h                    |  1 +
 indra/newview/llconversationmodel.cpp  | 10 +++++++---
 indra/newview/llconversationmodel.h    |  2 ++
 indra/newview/llimfloatercontainer.cpp | 33 ++++++++++++++++++++++++++++++---
 indra/newview/llimfloatercontainer.h   |  1 +
 6 files changed, 53 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 5c2b3236f6..49e7eaef99 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -870,16 +870,18 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
 	std::string tooltip = getToolTip();
 	if (!tooltip.empty())
 	{
-		// allow "scrubbing" over ui by showing next tooltip immediately
-		// if previous one was still visible
-		F32 timeout = LLToolTipMgr::instance().toolTipVisible() 
-			? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" )
-			: LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
-		LLToolTipMgr::instance().show(LLToolTip::Params()
-			.message(tooltip)
-			.sticky_rect(calcScreenRect())
-			.delay_time(timeout));
-
+		if (tooltip != NO_TOOLTIP_STRING)
+		{
+			// allow "scrubbing" over ui by showing next tooltip immediately
+			// if previous one was still visible
+			F32 timeout = LLToolTipMgr::instance().toolTipVisible() 
+			              ? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" )
+			              : LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
+			LLToolTipMgr::instance().show(LLToolTip::Params()
+			                              .message(tooltip)
+			                              .sticky_rect(calcScreenRect())
+			                              .delay_time(timeout));
+		}
 		handled = TRUE;
 	}
 
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 1c35349510..ba896b65a4 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -67,6 +67,7 @@ const BOOL	NOT_MOUSE_OPAQUE = FALSE;
 
 const U32 GL_NAME_UI_RESERVED = 2;
 
+static const std::string NO_TOOLTIP_STRING = " ";
 
 // maintains render state during traversal of UI tree
 class LLViewDrawContext
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 7d0ffa0788..176c05248d 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -36,6 +36,7 @@
 LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(display_name),
+	mUseNameForSort(true),
 	mUUID(uuid),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
@@ -46,6 +47,7 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u
 LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
+	mUseNameForSort(true),
 	mUUID(uuid),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
@@ -56,6 +58,7 @@ LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInte
 LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
+	mUseNameForSort(true),
 	mUUID(),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
@@ -251,8 +254,9 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
 {
-	mName = av_name.mUsername;
-	mDisplayName = av_name.mDisplayName;
+	mUseNameForSort = !av_name.mUsername.empty();
+	mName = (mUseNameForSort ? av_name.mUsername : NO_TOOLTIP_STRING);
+	mDisplayName = (av_name.mDisplayName.empty() ? mName : av_name.mDisplayName);
 	mNeedsRefresh = true;
 	if (mParent)
 	{
@@ -363,7 +367,7 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 	}
 	// By default, in all other possible cases (including sort order type LLConversationFilter::SO_NAME of course), 
 	// we sort by name
-	S32 compare = LLStringUtil::compareDict(a->getName(), b->getName());
+	S32 compare = LLStringUtil::compareDict((a->useNameForSort() ? a->getName() : a->getDisplayName()), (b->useNameForSort() ? b->getName() : b->getDisplayName()));
 	return (compare < 0);
 }
 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 30f94d51ae..82d4f0a710 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -123,9 +123,11 @@ public:
 	
 	void resetRefresh() { mNeedsRefresh = false; }
 	bool needsRefresh() { return mNeedsRefresh; }
+	bool const useNameForSort() const { return mUseNameForSort; }
 	
 protected:
 	std::string mName;	// Name of the session or the participant
+	bool mUseNameForSort;
 	LLUUID mUUID;		// UUID of the session or the participant
 	EConversationType mConvType;	// Type of conversation item
 	bool mNeedsRefresh;	// Flag signaling to the view that something changed for this item
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index e64247cd60..26b4e6c903 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -158,8 +158,7 @@ BOOL LLIMFloaterContainer::postBuild()
 
 	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
 	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
-	LLAvatarNameCache::addUseDisplayNamesCallback(
-			boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
+	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
 	if (! mMessagesPane->isCollapsed())
 	{
@@ -176,8 +175,11 @@ BOOL LLIMFloaterContainer::postBuild()
 	
 	mInitialized = true;
 
-	// Add callback: we'll take care of view updates on idle
+	// Add callbacks:
+	// We'll take care of view updates on idle
 	gIdleCallbacks.addFunction(idle, this);
+	// When display name option change, we need to reload all participant names
+	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLIMFloaterContainer::processParticipantsStyleUpdate, this));
 
 	return TRUE;
 }
@@ -330,6 +332,31 @@ void LLIMFloaterContainer::setMinimized(BOOL b)
 	}
 }
 
+// Update all participants in the conversation lists
+void LLIMFloaterContainer::processParticipantsStyleUpdate()
+{
+	// On each session in mConversationsItems
+	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	{
+		// Get the current session descriptors
+		LLConversationItem* session_model = it_session->second;
+		// Iterate through each model participant child
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+			// Get the avatar name for this participant id from the cache and update the model
+			LLUUID participant_id = participant_model->getUUID();
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(participant_id,&av_name);
+			participant_model->onAvatarNameCache(av_name);
+			// Next participant
+			current_participant_model++;
+		}
+	}
+}
+
 // static
 void LLIMFloaterContainer::idle(void* user_data)
 {
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 070feb3273..2debc2455b 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -96,6 +96,7 @@ private:
 	void onNewMessageReceived(const LLSD& data);
 
 	void onExpandCollapseButtonClicked();
+	void processParticipantsStyleUpdate();
 
 	void collapseConversationsPane(bool collapse);
 
-- 
cgit v1.2.3


From 166ff2b1b8dc21ad1a88c715a480ce1d2c5c2e07 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 28 Sep 2012 15:08:56 -0700
Subject: CHUI-366 : Completed : Update participants names when the display
 name pref is toggled on and off.

---
 indra/newview/llimfloatercontainer.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 26b4e6c903..45d63ce4f9 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -350,7 +350,13 @@ void LLIMFloaterContainer::processParticipantsStyleUpdate()
 			LLUUID participant_id = participant_model->getUUID();
 			LLAvatarName av_name;
 			LLAvatarNameCache::get(participant_id,&av_name);
-			participant_model->onAvatarNameCache(av_name);
+			// Avoid updating the model though if the cache is still waiting for its first update
+			if (!av_name.mDisplayName.empty())
+			{
+				participant_model->onAvatarNameCache(av_name);
+			}
+			// Bind update to the next cache name signal
+			LLAvatarNameCache::get(participant_id, boost::bind(&LLConversationItemParticipant::onAvatarNameCache, participant_model, _2));
 			// Next participant
 			current_participant_model++;
 		}
@@ -368,7 +374,6 @@ void LLIMFloaterContainer::idle(void* user_data)
 	{
 		self->setNearbyDistances();
 	}
-	
 	self->mConversationsRoot->update();
 }
 
-- 
cgit v1.2.3


From 7fc33cc47fdc080bbc7674cf118011b689ba1485 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 28 Sep 2012 17:30:18 -0700
Subject: CHUI-367 : Completed : Show user name tooltip in all situations so to
 avoid the conversation name showing up

---
 indra/llui/llview.cpp                 | 21 +++++++++------------
 indra/llui/llview.h                   |  2 --
 indra/newview/llconversationmodel.cpp | 10 +++-------
 indra/newview/llconversationmodel.h   |  2 --
 4 files changed, 12 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 49e7eaef99..8323bfc12f 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -870,18 +870,15 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
 	std::string tooltip = getToolTip();
 	if (!tooltip.empty())
 	{
-		if (tooltip != NO_TOOLTIP_STRING)
-		{
-			// allow "scrubbing" over ui by showing next tooltip immediately
-			// if previous one was still visible
-			F32 timeout = LLToolTipMgr::instance().toolTipVisible() 
-			              ? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" )
-			              : LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
-			LLToolTipMgr::instance().show(LLToolTip::Params()
-			                              .message(tooltip)
-			                              .sticky_rect(calcScreenRect())
-			                              .delay_time(timeout));
-		}
+		// allow "scrubbing" over ui by showing next tooltip immediately
+		// if previous one was still visible
+		F32 timeout = LLToolTipMgr::instance().toolTipVisible() 
+		              ? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" )
+		              : LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
+		LLToolTipMgr::instance().show(LLToolTip::Params()
+		                              .message(tooltip)
+		                              .sticky_rect(calcScreenRect())
+		                              .delay_time(timeout));
 		handled = TRUE;
 	}
 
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index ba896b65a4..15b85a6418 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -67,8 +67,6 @@ const BOOL	NOT_MOUSE_OPAQUE = FALSE;
 
 const U32 GL_NAME_UI_RESERVED = 2;
 
-static const std::string NO_TOOLTIP_STRING = " ";
-
 // maintains render state during traversal of UI tree
 class LLViewDrawContext
 {
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 176c05248d..9fa8758d11 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -36,7 +36,6 @@
 LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(display_name),
-	mUseNameForSort(true),
 	mUUID(uuid),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
@@ -47,7 +46,6 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u
 LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
-	mUseNameForSort(true),
 	mUUID(uuid),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
@@ -58,7 +56,6 @@ LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInte
 LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_model) :
 	LLFolderViewModelItemCommon(root_view_model),
 	mName(""),
-	mUseNameForSort(true),
 	mUUID(),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
@@ -254,9 +251,8 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
 {
-	mUseNameForSort = !av_name.mUsername.empty();
-	mName = (mUseNameForSort ? av_name.mUsername : NO_TOOLTIP_STRING);
-	mDisplayName = (av_name.mDisplayName.empty() ? mName : av_name.mDisplayName);
+	mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
+	mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
 	mNeedsRefresh = true;
 	if (mParent)
 	{
@@ -367,7 +363,7 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 	}
 	// By default, in all other possible cases (including sort order type LLConversationFilter::SO_NAME of course), 
 	// we sort by name
-	S32 compare = LLStringUtil::compareDict((a->useNameForSort() ? a->getName() : a->getDisplayName()), (b->useNameForSort() ? b->getName() : b->getDisplayName()));
+	S32 compare = LLStringUtil::compareDict(a->getName(), b->getName());
 	return (compare < 0);
 }
 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 82d4f0a710..30f94d51ae 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -123,11 +123,9 @@ public:
 	
 	void resetRefresh() { mNeedsRefresh = false; }
 	bool needsRefresh() { return mNeedsRefresh; }
-	bool const useNameForSort() const { return mUseNameForSort; }
 	
 protected:
 	std::string mName;	// Name of the session or the participant
-	bool mUseNameForSort;
 	LLUUID mUUID;		// UUID of the session or the participant
 	EConversationType mConvType;	// Type of conversation item
 	bool mNeedsRefresh;	// Flag signaling to the view that something changed for this item
-- 
cgit v1.2.3


From 4a41aa8fad7f4a0c1daab5d159920745a03a5950 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 28 Sep 2012 18:39:55 -0700
Subject: CHUI-345 : Add mandatory license to the files

---
 indra/newview/llfloaterchatvoicevolume.cpp | 26 ++++++++++++++++++++++----
 indra/newview/llfloaterchatvoicevolume.h   | 26 ++++++++++++++++++++++----
 2 files changed, 44 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
index d10c3c6504..3c76a3a43c 100644
--- a/indra/newview/llfloaterchatvoicevolume.cpp
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -1,8 +1,26 @@
-/*
- * llfloaterchatvoicevolume.cpp
+/** 
+ * @file llfloaterchatvoicevolume.cpp
  *
- *  Created on: Sep 27, 2012
- *      Author: pguslisty
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
  */
 
 #include "llviewerprecompiledheaders.h"
diff --git a/indra/newview/llfloaterchatvoicevolume.h b/indra/newview/llfloaterchatvoicevolume.h
index 0aeab7874c..61ad92b6da 100644
--- a/indra/newview/llfloaterchatvoicevolume.h
+++ b/indra/newview/llfloaterchatvoicevolume.h
@@ -1,8 +1,26 @@
-/*
- * llfloaterchatvoicevolume.h
+/** 
+ * @file llfloaterchatvoicevolume.h
  *
- *  Created on: Sep 27, 2012
- *      Author: pguslisty
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
  */
 
 #ifndef LLFLOATERCHATVOICEVOLUME_H_
-- 
cgit v1.2.3


From 507b66aeb1614a1293890ffacbab53ccecc25e20 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 28 Sep 2012 19:40:17 +0300
Subject: CHUI-349 (Crash when clicking on nearby chat toast): removed a faulty
 method LLIMFloater::addToIMContainer; replaced it's calls to calls of its
 correct twin - LLIMFloater::addToHost

---
 indra/newview/llimfloater.cpp          | 47 ++++++++++++----------------------
 indra/newview/llimfloater.h            |  3 +--
 indra/newview/llimfloatercontainer.cpp |  4 +--
 3 files changed, 20 insertions(+), 34 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 43adfdfd08..d11504d312 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -582,13 +582,14 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 		build_names_string(temp_uuids, ui_title);
 		updateSessionName(ui_title, ui_title);
 	}
-    }
+}
 
-//static
-LLIMFloater* LLIMFloater::addToIMContainer(const LLUUID& session_id)
+void LLIMFloater::addToHost(const LLUUID& session_id, const bool force)
 {
-	if (!gIMMgr->hasSession(session_id))
-		return NULL;
+	if (!LLIMConversation::isChatMultiTab() || !gIMMgr->hasSession(session_id))
+	{
+		return;
+	}
 
 	// Test the existence of the floater before we try to create it
 	bool exist = findInstance(session_id);
@@ -612,19 +613,22 @@ LLIMFloater* LLIMFloater::addToIMContainer(const LLUUID& session_id)
 			}
 		}
 
-		if (floater_container && floater_container->getVisible())
+		if (force)
 		{
-			floater->openFloater(floater->getKey());
-			floater->setVisible(TRUE);
-		}
-		else
-		{
-			floater->setVisible(FALSE);
+			if (floater_container && floater_container->getVisible())
+			{
+				floater->openFloater(floater->getKey());
+				floater->setVisible(TRUE);
+			}
+			else
+			{
+				floater->setVisible(FALSE);
+			}
 		}
 	}
-	return floater;
 }
 
+
 //static
 LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 {
@@ -1323,23 +1327,6 @@ void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
 {
 	LLIMFloater::addToHost(session_id);
 }
-void LLIMFloater::addToHost(const LLUUID& session_id)
-	{
-	if (LLIMConversation::isChatMultiTab())
-{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
-		if (!im_box)
-	{
-			im_box = LLIMFloaterContainer::getInstance();
-	}
-
-		if (im_box && !LLIMFloater::findInstance(session_id))
-	{
-			LLIMFloater* new_tab = LLIMFloater::getInstance(session_id);
-			im_box->addFloater(new_tab, FALSE, LLTabContainer::END);
-	}
-	}
-}
 
 boost::signals2::connection LLIMFloater::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb)
 {
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index e4a67a3d56..d444270716 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -71,14 +71,13 @@ public:
 
 	static LLIMFloater* findInstance(const LLUUID& session_id);
 	static LLIMFloater* getInstance(const LLUUID& session_id);
-	static void addToHost(const LLUUID& session_id);
+	static void addToHost(const LLUUID& session_id, const bool force = false);
 
 	// LLFloater overrides
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
 	// Make IM conversion visible and update the message history
 	static LLIMFloater* show(const LLUUID& session_id);
-	static LLIMFloater* addToIMContainer(const LLUUID& session_id);
 
 	// Toggle panel specified by session_id
 	// Returns true iff panel became visible
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index ffbdae305b..ca77f05545 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -86,13 +86,13 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	LLIMFloater::addToIMContainer(session_id);
+	LLIMFloater::addToHost(session_id, true);
 	addConversationListItem(session_id);
 }
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	LLIMFloater::addToIMContainer(session_id);
+	LLIMFloater::addToHost(session_id, true);
 	addConversationListItem(session_id);
 }
 
-- 
cgit v1.2.3


From 14307b099bdb0e7c5b56d052a55e010ecd69b5c3 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 28 Sep 2012 19:06:36 +0300
Subject: CHUI-361 FIXED (Viewer crash when selecting to start IM with user
 from right click menu in people floater ): prevent destruction of
 im_container; suppress warning for the nearby_chat

---
 indra/newview/llimfloatercontainer.cpp                      | 4 ++--
 indra/newview/skins/default/xui/en/floater_im_container.xml | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index ca77f05545..c6f0607b35 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -223,8 +223,8 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
 		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
 	}
 	else
-	{
-		LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id);
+	{   LLUUID avatar_id = session_id.notNull()?
+		    LLIMModel::getInstance()->getOtherParticipantID(session_id) : LLUUID();
 
 		LLAvatarIconCtrl::Params icon_params;
 		icon_params.avatar_id = avatar_id;
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index d23ff28fd0..590ce45c33 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -11,6 +11,7 @@
  save_rect="true"
  save_visibility="true"
  single_instance="true"
+ reuse_instance="true"
  title="CONVERSATIONS"
  width="680">
     <string
-- 
cgit v1.2.3


From d54eded93ba270402349f5f337bbe12339255ece Mon Sep 17 00:00:00 2001
From: Seth ProductEngine <slitovchuk@productengine.com>
Date: Fri, 28 Sep 2012 20:48:24 +0300
Subject: CHUI-357 FIXED moved conversation icon to prevent it being obscured
 when conversations list is minimized. Added minimized mode for
 LLConversationViewSession: this mode is used to move the conversation icon
 within the item when the conversations panel is minimized.

---
 indra/newview/llconversationview.cpp   | 39 ++++++++++++++++++++++++++++------
 indra/newview/llconversationview.h     |  6 ++++++
 indra/newview/llimfloatercontainer.cpp | 20 +++++++++++++++++
 3 files changed, 59 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index c2898d9a47..d4eb551f7a 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -80,7 +80,8 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mCallIconLayoutPanel(NULL),
 	mSessionTitle(NULL),
 	mSpeakingIndicator(NULL),
-	mVoiceClientObserver(NULL)
+	mVoiceClientObserver(NULL),
+	mMinimizedMode(false)
 {
 }
 
@@ -168,15 +169,18 @@ void LLConversationViewSession::draw()
 	const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
 
-	// update the rotation angle of open folder arrow
-	updateLabelRotation();
+	// we don't draw the open folder arrow in minimized mode
+	if (!mMinimizedMode)
+	{
+		// update the rotation angle of open folder arrow
+		updateLabelRotation();
 
-	drawOpenFolderArrow(default_params, sFgColor);
+		drawOpenFolderArrow(default_params, sFgColor);
+	}
 
 	// draw highlight for selected items
 	drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
 
-
 	// draw children if root folder, or any other folder that is open or animating to closed state
 	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this)
 						 || isOpen()
@@ -201,7 +205,8 @@ void LLConversationViewSession::draw()
 // virtual
 S32 LLConversationViewSession::arrange(S32* width, S32* height)
 {
-	LLRect rect(getIndentation() + mArrowSize,
+	S32 h_pad = getIndentation() + mArrowSize;
+	LLRect rect(mMinimizedMode ? getLocalRect().mLeft : h_pad,
 				getLocalRect().mTop,
 				getLocalRect().mRight,
 				getLocalRect().mTop - getItemHeight());
@@ -210,6 +215,16 @@ S32 LLConversationViewSession::arrange(S32* width, S32* height)
 	return LLFolderViewFolder::arrange(width, height);
 }
 
+// virtual
+void LLConversationViewSession::toggleOpen()
+{
+	// conversations should not be opened while in minimized mode
+	if (!mMinimizedMode)
+	{
+		LLFolderViewFolder::toggleOpen();
+	}
+}
+
 void LLConversationViewSession::selectItem()
 {
 	
@@ -231,6 +246,18 @@ void LLConversationViewSession::selectItem()
 	LLFolderViewItem::selectItem();
 }
 
+void LLConversationViewSession::toggleMinimizedMode(bool is_minimized)
+{
+	mMinimizedMode = is_minimized;
+
+	// hide the layout stack which contains all item's child widgets
+	// except for the icon which we display in minimized mode
+	getChild<LLView>("conversation_item_stack")->setVisible(!mMinimizedMode);
+
+	S32 h_pad = getIndentation() + mArrowSize;
+	mItemPanel->translate(mMinimizedMode ? -h_pad : h_pad, 0);
+}
+
 void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
 {
 	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 064239eeb1..c81c70b456 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -67,6 +67,10 @@ public:
 
 	/*virtual*/ S32 arrange(S32* width, S32* height);
 
+	/*virtual*/ void toggleOpen();
+
+	void toggleMinimizedMode(bool is_minimized);
+
 	void setVisibleIfDetached(BOOL visible);
 	LLConversationViewParticipant* findParticipant(const LLUUID& participant_id);
 
@@ -83,6 +87,8 @@ private:
 	LLTextBox*				mSessionTitle;
 	LLOutputMonitorCtrl*	mSpeakingIndicator;
 
+	bool					mMinimizedMode;
+
 	LLVoiceClientStatusObserver* mVoiceClientObserver;
 
 	boost::signals2::connection mActiveVoiceChannelConnection;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c6f0607b35..6f7eb7822a 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -133,6 +133,7 @@ BOOL LLIMFloaterContainer::postBuild()
     p.listener = base_item;
     p.view_model = &mConversationViewModel;
     p.root = NULL;
+    p.use_ellipses = true;
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
 
 	// a scroller for folder view
@@ -532,6 +533,22 @@ void LLIMFloaterContainer::collapseConversationsPane(bool collapse)
 
 	S32 collapsed_width = mConversationsPane->getMinDim();
 	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - collapsed_width);
+
+	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+			widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+		    widget->toggleMinimizedMode(collapse);
+
+		    // force closing all open conversations when collapsing to minimized state
+		    if (collapse)
+		    {
+		    	widget->setOpen(false);
+		    }
+		}
+	}
 }
 
 void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
@@ -806,6 +823,9 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 
 	setConvItemSelect(uuid);
 	
+	// set the widget to minimized mode if conversations pane is collapsed
+	widget->toggleMinimizedMode(mConversationsPane->isCollapsed());
+
 	return;
 }
 
-- 
cgit v1.2.3


From 11a148415e810706f2a1835b6b717a0a062d458f Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 28 Sep 2012 18:22:05 -0700
Subject: CHUI-102: Now the participants and one-on-one conversations have
 right-click-menus. These menus are functional as well, but 'chat history'
 does not yet work.

---
 indra/llui/llfolderview.cpp                        |   5 +-
 indra/llui/llfolderview.h                          |   2 +
 indra/newview/llconversationmodel.cpp              |  44 +++++
 indra/newview/llconversationmodel.h                |  18 +-
 indra/newview/llimfloater.h                        |   1 +
 indra/newview/llimfloatercontainer.cpp             | 192 ++++++++++++++++++++-
 indra/newview/llimfloatercontainer.h               |   5 +
 indra/newview/llinventorypanel.cpp                 |   1 +
 .../skins/default/xui/en/menu_conversation.xml     | 109 ++++++++++++
 9 files changed, 372 insertions(+), 5 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/menu_conversation.xml

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index ce1bc5914c..327a064228 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -138,7 +138,8 @@ LLFolderView::Params::Params()
 	use_label_suffix("use_label_suffix"),
 	allow_multiselect("allow_multiselect", true),
 	show_empty_message("show_empty_message", true),
-	use_ellipses("use_ellipses", false)
+	use_ellipses("use_ellipses", false),
+    options_menu("options_menu", "")
 {
 	folder_indentation = -4;
 }
@@ -228,7 +229,7 @@ LLFolderView::LLFolderView(const Params& p)
 
 
 	// make the popup menu available
-	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
 	if (!menu)
 	{
 		menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 81b0f087e8..260275269d 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -94,6 +94,8 @@ public:
 								use_ellipses,
 								show_item_link_overlays;
 		Mandatory<LLFolderViewModelInterface*>	view_model;
+        Optional<std::string>   options_menu;
+
 
 		Params();
 	};
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 7d0ffa0788..1c4c7aefae 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -28,6 +28,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llconversationmodel.h"
+#include "llmenugl.h"
 
 //
 // Conversation items : common behaviors
@@ -84,6 +85,24 @@ void LLConversationItem::showProperties(void)
 {
 }
 
+void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t&   items)
+{
+    items.push_back(std::string("view_profile"));
+    items.push_back(std::string("im"));
+    items.push_back(std::string("offer_teleport"));
+    items.push_back(std::string("voice_call"));
+    items.push_back(std::string("chat_history"));
+    items.push_back(std::string("separator_chat_history"));
+    items.push_back(std::string("add_friend"));
+    items.push_back(std::string("remove_friend"));
+    items.push_back(std::string("invite_to_group"));
+    items.push_back(std::string("separator_invite_to_group"));
+    items.push_back(std::string("map"));
+    items.push_back(std::string("share"));
+    items.push_back(std::string("pay"));
+    items.push_back(std::string("block_unblock"));
+}
+
 //
 // LLConversationItemSession
 // 
@@ -191,6 +210,22 @@ void LLConversationItemSession::setDistance(const LLUUID& participant_id, F64 di
 	}
 }
 
+void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+    lldebugs << "LLConversationItemParticipant::buildContextMenu()" << llendl;
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+
+    if(this->getType() == CONV_SESSION_1_ON_1)
+    {
+        items.push_back(std::string("close_conversation"));
+        items.push_back(std::string("separator_disconnect_from_voice"));
+        buildParticipantMenuOptions(items);
+    }
+
+    hide_context_entries(menu, items, disabled_items);
+}
+
 // The time of activity of a session is the time of the most recent activity, session and participants included
 const bool LLConversationItemSession::getTime(F64& time) const
 {
@@ -249,6 +284,15 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 	mConvType = CONV_PARTICIPANT;
 }
 
+void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+
+    buildParticipantMenuOptions(items);
+    hide_context_entries(menu, items, disabled_items);
+}
+
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
 {
 	mName = av_name.mUsername;
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 30f94d51ae..43fa66e8e2 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -41,6 +41,8 @@ class LLConversationItemParticipant;
 typedef std::map<LLUUID, LLConversationItem*> conversations_items_map;
 typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
 
+typedef std::vector<std::string> menuentry_vec_t;
+
 // Conversation items: we hold a list of those and create an LLFolderViewItem widget for each  
 // that we tuck into the mConversationsListPanel. 
 class LLConversationItem : public LLFolderViewModelItemCommon
@@ -124,6 +126,8 @@ public:
 	void resetRefresh() { mNeedsRefresh = false; }
 	bool needsRefresh() { return mNeedsRefresh; }
 	
+    void buildParticipantMenuOptions(menuentry_vec_t&   items);
+
 protected:
 	std::string mName;	// Name of the session or the participant
 	LLUUID mUUID;		// UUID of the session or the participant
@@ -155,6 +159,7 @@ public:
 	
 	bool isLoaded() { return mIsLoaded; }
 	
+    void buildContextMenu(LLMenuGL& menu, U32 flags);
 	virtual const bool getTime(F64& time) const;
 
 	void dumpDebugData();
@@ -178,7 +183,8 @@ public:
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
 	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; }
 	void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; }
-	
+
+    void buildContextMenu(LLMenuGL& menu, U32 flags);
 	void onAvatarNameCache(const LLAvatarName& av_name);
 
 	virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
@@ -273,4 +279,14 @@ public:
 private:
 };
 
+// Utility function to hide all entries except those in the list
+// Can be called multiple times on the same menu (e.g. if multiple items
+// are selected).  If "append" is false, then only common enabled items
+// are set as enabled.
+
+//(defined in inventorybridge.cpp)
+void hide_context_entries(LLMenuGL& menu, 
+    const menuentry_vec_t &entries_to_show, 
+    const menuentry_vec_t &disabled_entries);
+
 #endif // LL_LLCONVERSATIONMODEL_H
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index e4a67a3d56..fbaf009939 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -128,6 +128,7 @@ public:
 	static void onIMChicletCreated(const LLUUID& session_id);
 
 	bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
+    LLUUID getOtherParticipantUUID() {return mOtherParticipantUUID;}
 
 	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
 	static floater_showed_signal_t sIMFloaterShowedSignal;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 14d40d4685..b4802c71f9 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -58,8 +58,12 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 	mConversationsRoot(NULL),
 	mInitialized(false)
 {
+    mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLIMFloaterContainer::isActionChecked, this, _2));
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLIMFloaterContainer::onCustomAction,  this, _2));
-	mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLIMFloaterContainer::isActionChecked, this, _2));
+	
+    mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLIMFloaterContainer::checkContextMenuItem,	this, _2));
+    mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLIMFloaterContainer::enableContextMenuItem,	this, _2));
+    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelected, this, _2));
 
 	// Firstly add our self to IMSession observers, so we catch session events
     LLIMMgr::getInstance()->addSessionObserver(this);
@@ -133,7 +137,9 @@ BOOL LLIMFloaterContainer::postBuild()
     p.listener = base_item;
     p.view_model = &mConversationViewModel;
     p.root = NULL;
+    p.options_menu = "menu_conversation.xml";
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
 	// a scroller for folder view
 	LLRect scroller_view_rect = mConversationsListPanel->getRect();
@@ -341,7 +347,7 @@ void LLIMFloaterContainer::idle(void* user_data)
 	{
 		self->setNearbyDistances();
 	}
-	
+
 	self->mConversationsRoot->update();
 }
 
@@ -661,6 +667,188 @@ void LLIMFloaterContainer::setSortOrder(const LLConversationSort& order)
 	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
 }
 
+void LLIMFloaterContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
+{
+    const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList();
+
+    std::set<LLFolderViewItem*>::const_iterator it = selectedItems.begin();
+    const std::set<LLFolderViewItem*>::const_iterator it_end = selectedItems.end();
+    LLConversationItem * conversationItem;
+
+    for (; it != it_end; ++it)
+    {
+        conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem());
+        selected_uuids.push_back(conversationItem->getUUID());
+    }
+}
+void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
+{
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+    LLUUID currentSelectedUUID;
+    LLIMFloater * conversation;
+
+    getSelectedUUIDs(selected_uuids);
+    conversation = LLIMFloater::findInstance(selected_uuids.front());
+    
+    if(conversation && 
+        static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem())->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+    {
+        currentSelectedUUID = conversation->getOtherParticipantUUID();
+    }
+    else
+    {
+        currentSelectedUUID = selected_uuids.front();
+    }
+
+    //Close the selected conversation
+    if(conversation && "close_conversation" == command)
+    {
+        LLFloater::onClickClose(conversation);
+    }
+    else if ("view_profile" == command)
+    {
+        LLAvatarActions::showProfile(currentSelectedUUID);
+    }
+    else if("im" == command)
+    {
+        LLAvatarActions::startIM(currentSelectedUUID);
+    }
+    else if("offer_teleport" == command)
+    {
+        LLAvatarActions::offerTeleport(selected_uuids);
+    }
+    else if("voice_call" == command)
+    {
+        LLAvatarActions::startCall(currentSelectedUUID);
+    }
+    else if("add_friend" == command)
+    {
+        LLAvatarActions::requestFriendshipDialog(currentSelectedUUID);
+    }
+    else if("remove_friend" == command)
+    {
+        LLAvatarActions::removeFriendDialog(currentSelectedUUID);
+    }
+    else if("invite_to_group" == command)
+    {
+        LLAvatarActions::inviteToGroup(currentSelectedUUID);
+    }
+    else if("map" == command)
+    {
+        LLAvatarActions::showOnMap(currentSelectedUUID);
+    }
+    else if("share" == command)
+    {
+        LLAvatarActions::share(currentSelectedUUID);
+    }
+    else if("pay" == command)
+    {
+        LLAvatarActions::pay(currentSelectedUUID);
+    }
+    else if("block_unblock" == command)
+    {
+        LLAvatarActions::toggleBlock(currentSelectedUUID);
+    }
+}
+
+bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
+{
+    std::string item = userdata.asString();
+    uuid_vec_t mUUIDs;
+    getSelectedUUIDs(mUUIDs);
+
+    // Note: can_block and can_delete is used only for one person selected menu
+    // so we don't need to go over all uuids.
+
+    if (item == std::string("can_block"))
+    {
+        const LLUUID& id = mUUIDs.front();
+        return LLAvatarActions::canBlock(id);
+    }
+    else if (item == std::string("can_add"))
+    {
+        // We can add friends if:
+        // - there are selected people
+        // - and there are no friends among selection yet.
+
+        //EXT-7389 - disable for more than 1
+        if(mUUIDs.size() > 1)
+        {
+            return false;
+        }
+
+        bool result = (mUUIDs.size() > 0);
+
+        uuid_vec_t::const_iterator
+            id = mUUIDs.begin(),
+            uuids_end = mUUIDs.end();
+
+        for (;id != uuids_end; ++id)
+        {
+            if ( LLAvatarActions::isFriend(*id) )
+            {
+                result = false;
+                break;
+            }
+        }
+
+        return result;
+    }
+    else if (item == std::string("can_delete"))
+    {
+        // We can remove friends if:
+        // - there are selected people
+        // - and there are only friends among selection.
+
+        bool result = (mUUIDs.size() > 0);
+
+        uuid_vec_t::const_iterator
+            id = mUUIDs.begin(),
+            uuids_end = mUUIDs.end();
+
+        for (;id != uuids_end; ++id)
+        {
+            if ( !LLAvatarActions::isFriend(*id) )
+            {
+                result = false;
+                break;
+            }
+        }
+
+        return result;
+    }
+    else if (item == std::string("can_call"))
+    {
+        return LLAvatarActions::canCall();
+    }
+    else if (item == std::string("can_show_on_map"))
+    {
+        const LLUUID& id = mUUIDs.front();
+
+        return (LLAvatarTracker::instance().isBuddyOnline(id) && is_agent_mappable(id))
+            || gAgent.isGodlike();
+    }
+    else if(item == std::string("can_offer_teleport"))
+    {
+        return LLAvatarActions::canOfferTeleport(mUUIDs);
+    }
+    return false;
+}
+
+bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
+{
+    std::string item = userdata.asString();
+    const LLUUID& id = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem())->getUUID();
+
+    if (item == std::string("is_blocked"))
+    {
+        return LLAvatarActions::isBlocked(id);
+    }
+
+    return false;
+}
+
 void LLIMFloaterContainer::repositioningWidgets()
 {
 	if (!mInitialized)
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index e8d185297c..cc2d0ce6ab 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -111,6 +111,11 @@ private:
 	void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order);
 	void setSortOrder(const LLConversationSort& order);
 
+    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
+    void doToSelected(const LLSD& userdata);
+    bool checkContextMenuItem(const LLSD& userdata);
+    bool enableContextMenuItem(const LLSD& userdata);
+
 	LLButton* mExpandCollapseBtn;
 	LLLayoutPanel* mMessagesPane;
 	LLLayoutPanel* mConversationsPane;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 2a84616ddf..6e692adf2a 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -172,6 +172,7 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
     p.show_empty_message = mShowEmptyMessage;
     p.show_item_link_overlays = mShowItemLinkOverlays;
     p.root = NULL;
+    p.options_menu = "menu_inventory.xml";
 
     return LLUICtrlFactory::create<LLFolderView>(p);
 }
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
new file mode 100644
index 0000000000..94399be61c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ bottom="806"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="menu_conversation_participant"
+ visible="false">
+     <menu_item_call
+     label="Close conversation"
+     layout="topleft"
+     name="close_conversation">
+        <on_click function="Avatar.DoToSelected" parameter="close_conversation"/>
+	 </menu_item_call>
+     <menu_item_call
+     label="Open voice conversation"
+     layout="topleft"
+     name="open_voice_conversation">
+        <on_click function="Avatar.DoToSelected" parameter="open_voice_conversation"/>
+     </menu_item_call>	
+     <menu_item_call
+     label="Disconnect from voice"
+     layout="topleft"
+     name="disconnect_from_voice">
+        <on_click function="Avatar.DoToSelected" parameter="disconnect_from_voice"/>
+    </menu_item_call>	
+	<menu_item_separator layout="topleft" name="separator_disconnect_from_voice"/>	
+    <menu_item_call
+     label="View Profile"
+     layout="topleft"
+     name="view_profile">
+        <on_click function="Avatar.DoToSelected" parameter="view_profile"/>
+    </menu_item_call>
+    <menu_item_call
+     label="IM"
+     layout="topleft"
+     name="im">
+        <on_click function="Avatar.DoToSelected" parameter="im"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Offer teleport"
+     layout="topleft"
+     name="offer_teleport">
+        <on_click function="Avatar.DoToSelected" parameter="offer_teleport"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Voice call"
+     layout="topleft"
+     name="voice_call">
+        <on_click function="Avatar.DoToSelected" parameter="voice_call"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_call" />
+    </menu_item_call>
+    <menu_item_call
+     label="Chat history..."
+     layout="topleft"
+     name="chat_history">
+        <on_click function="Avatar.DoToSelected" parameter="chat_history"/>
+    </menu_item_call>	
+    <menu_item_separator layout="topleft" name="separator_chat_history"/>	
+    <menu_item_call
+     label="Add friend"
+     layout="topleft"
+     name="add_friend">
+        <on_click function="Avatar.DoToSelected" parameter="add_friend"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_add" />
+    </menu_item_call>
+    <menu_item_call
+     label="Remove friend"
+     layout="topleft"
+     name="remove_friend">
+        <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
+        <on_enable function="Avatar.EnableItem" parameter="can_delete" />
+    </menu_item_call>	
+    <menu_item_call
+     label="Invite to group..."
+     layout="topleft"
+     name="invite_to_group">
+        <on_click function="Avatar.DoToSelected" parameter="invite_to_group" />
+    </menu_item_call>
+    <menu_item_separator layout="topleft" name="separator_invite_to_group"/>		
+    <menu_item_call
+     label="Map"
+     layout="topleft"
+     name="map">
+        <on_click function="Avatar.DoToSelected" parameter="map" />
+        <on_enable function="Avatar.EnableItem" parameter="can_show_on_map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Share"
+     layout="topleft"
+     name="share">
+        <on_click function="Avatar.DoToSelected" parameter="share" />
+    </menu_item_call>
+    <menu_item_call
+     label="Pay"
+     layout="topleft"
+     name="pay">
+        <on_click function="Avatar.DoToSelected" parameter="pay" />
+    </menu_item_call>
+    <menu_item_check
+     label="Block / unblock"
+     layout="topleft"
+     name="block_unblock">
+        <on_click function="Avatar.DoToSelected" parameter="block_unblock" />
+		<on_check function="Avatar.CheckItem" parameter="is_blocked" />
+		<on_enable  function="Avatar.EnableItem" parameter="can_block" />
+    </menu_item_check>
+</toggleable_menu>
-- 
cgit v1.2.3


From 5e6f224b5eb3591e9ecea981613cf64a2ce56b8a Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 1 Oct 2012 20:02:28 +0300
Subject: CHUI-368 FIXED Lock icon shown when clicking on items in inventory

---
 indra/llui/llfolderviewitem.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 5639c4d5a3..0b04288950 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -537,7 +537,7 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 		if( (x - mDragStartX) * (x - mDragStartX) + (y - mDragStartY) * (y - mDragStartY) > drag_and_drop_threshold() * drag_and_drop_threshold() 
 			&& root->getCurSelectedItem()
 			&& root->startDrag())
-			{
+		{
 					// RN: when starting drag and drop, clear out last auto-open
 					root->autoOpenTest(NULL);
 					root->setShowSelectionContext(TRUE);
@@ -548,13 +548,13 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 					gFocusMgr.setKeyboardFocus(NULL);
 
 			getWindow()->setCursor(UI_CURSOR_ARROW);
-			return TRUE;
-				}
-		else
+		}
+		else if (x != mDragStartX || y != mDragStartY)
 		{
 			getWindow()->setCursor(UI_CURSOR_NOLOCKED);
-			return TRUE;
 		}
+
+		return TRUE;
 	}
 	else
 	{
-- 
cgit v1.2.3


From 8e1a9e2813da6b9d5c17795b375098fb6a386ee1 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 1 Oct 2012 13:54:53 -0700
Subject: CHUI-102: Cleaned up code after code review.

---
 indra/llui/llfolderview.cpp            | 4 ++++
 indra/llui/llfolderview.h              | 2 +-
 indra/newview/llconversationmodel.cpp  | 1 -
 indra/newview/llconversationmodel.h    | 1 +
 indra/newview/llimfloater.h            | 2 +-
 indra/newview/llimfloatercontainer.cpp | 9 ++++++++-
 6 files changed, 15 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 327a064228..9a4a90206b 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1531,14 +1531,18 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
 		&& menu )
 	{
 		if (mCallbackRegistrar)
+        {
 			mCallbackRegistrar->pushScope();
+        }
 
 		updateMenuOptions(menu);
 	   
 		menu->updateParent(LLMenuGL::sMenuContainer);
 		LLMenuGL::showPopup(this, menu, x, y);
 		if (mCallbackRegistrar)
+        {
 			mCallbackRegistrar->popScope();
+        }
 	}
 	else
 	{
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 260275269d..487391a477 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -94,7 +94,7 @@ public:
 								use_ellipses,
 								show_item_link_overlays;
 		Mandatory<LLFolderViewModelInterface*>	view_model;
-        Optional<std::string>   options_menu;
+        Mandatory<std::string>   options_menu;
 
 
 		Params();
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 1c4c7aefae..f587ef8428 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -28,7 +28,6 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llconversationmodel.h"
-#include "llmenugl.h"
 
 //
 // Conversation items : common behaviors
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 43fa66e8e2..f84fbe39f1 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -285,6 +285,7 @@ private:
 // are set as enabled.
 
 //(defined in inventorybridge.cpp)
+//TODO: Gilbert Linden - Refactor to make this function non-global
 void hide_context_entries(LLMenuGL& menu, 
     const menuentry_vec_t &entries_to_show, 
     const menuentry_vec_t &disabled_entries);
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index fbaf009939..489e430b26 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -128,7 +128,7 @@ public:
 	static void onIMChicletCreated(const LLUUID& session_id);
 
 	bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
-    LLUUID getOtherParticipantUUID() {return mOtherParticipantUUID;}
+    const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;}
 
 	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
 	static floater_showed_signal_t sIMFloaterShowedSignal;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index b4802c71f9..58d2020801 100755
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -689,13 +689,20 @@ void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
     LLIMFloater * conversation;
 
     getSelectedUUIDs(selected_uuids);
+    //Find the conversation floater associated with the selected id
     conversation = LLIMFloater::findInstance(selected_uuids.front());
-    
+
+    //When a one-on-one conversation exists, retrieve the participant id from the conversation floater b/c
+    //selected_uuids.front() does not pertain to the UUID of the person you are having the conversation with.
     if(conversation && 
+           mConversationsRoot && 
+           mConversationsRoot->getCurSelectedItem() && 
+           mConversationsRoot->getCurSelectedItem()->getViewModelItem() &&
         static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem())->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
     {
         currentSelectedUUID = conversation->getOtherParticipantUUID();
     }
+    //Otherwise can get the UUID directly from selected_uuids
     else
     {
         currentSelectedUUID = selected_uuids.front();
-- 
cgit v1.2.3


From 598f5345866c58abdd971935d80f9b53756042c9 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 1 Oct 2012 17:04:13 -0700
Subject: CHUI-102: Right clicking on a group conversation brings up the
 correct menu. The user can now view the group profile, activate the group and
 leave the group.

---
 indra/newview/llconversationmodel.cpp              |  8 ++++
 indra/newview/llimfloatercontainer.cpp             | 48 ++++++++++++++++++----
 indra/newview/llimfloatercontainer.h               |  4 +-
 .../skins/default/xui/en/menu_conversation.xml     | 18 ++++++++
 4 files changed, 69 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 265f77365f..3d1523c874 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -221,6 +221,14 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
         items.push_back(std::string("separator_disconnect_from_voice"));
         buildParticipantMenuOptions(items);
     }
+    else if(this->getType() == CONV_SESSION_GROUP)
+    {
+        items.push_back(std::string("close_conversation"));
+        items.push_back(std::string("separator_disconnect_from_voice"));
+        items.push_back(std::string("group_profile"));
+        items.push_back(std::string("activate_group"));
+        items.push_back(std::string("leave_group"));
+    }
 
     hide_context_entries(menu, items, disabled_items);
 }
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index d25a195f33..b7f83e3c23 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -39,6 +39,7 @@
 #include "llavatariconctrl.h"
 #include "llavatarnamecache.h"
 #include "llcallbacklist.h"
+#include "llgroupactions.h"
 #include "llgroupiconctrl.h"
 #include "llfloateravatarpicker.h"
 #include "llfloaterpreference.h"
@@ -63,7 +64,9 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 	
     mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLIMFloaterContainer::checkContextMenuItem,	this, _2));
     mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLIMFloaterContainer::enableContextMenuItem,	this, _2));
-    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelected, this, _2));
+    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelectedAvatar, this, _2));
+    
+    mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelectedGroup, this, _2));
 
 	// Firstly add our self to IMSession observers, so we catch session events
     LLIMMgr::getInstance()->addSessionObserver(this);
@@ -731,7 +734,20 @@ void LLIMFloaterContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
         selected_uuids.push_back(conversationItem->getUUID());
     }
 }
-void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
+
+const LLConversationItem * LLIMFloaterContainer::getCurSelectedViewModelItem()
+{
+    if(mConversationsRoot && 
+        mConversationsRoot->getCurSelectedItem() && 
+        mConversationsRoot->getCurSelectedItem()->getViewModelItem())
+    {
+        return static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
+    }
+
+    return NULL;
+}
+
+void LLIMFloaterContainer::doToSelectedAvatar(const LLSD& userdata)
 {
     std::string command = userdata.asString();
     uuid_vec_t selected_uuids;
@@ -741,14 +757,11 @@ void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
     getSelectedUUIDs(selected_uuids);
     //Find the conversation floater associated with the selected id
     conversation = LLIMFloater::findInstance(selected_uuids.front());
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
 
     //When a one-on-one conversation exists, retrieve the participant id from the conversation floater b/c
     //selected_uuids.front() does not pertain to the UUID of the person you are having the conversation with.
-    if(conversation && 
-           mConversationsRoot && 
-           mConversationsRoot->getCurSelectedItem() && 
-           mConversationsRoot->getCurSelectedItem()->getViewModelItem() &&
-        static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem())->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+    if(conversation && conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
     {
         currentSelectedUUID = conversation->getOtherParticipantUUID();
     }
@@ -809,6 +822,25 @@ void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
     }
 }
 
+void LLIMFloaterContainer::doToSelectedGroup(const LLSD& userdata)
+{
+    std::string action = userdata.asString();
+    LLUUID selected_group = getCurSelectedViewModelItem()->getUUID();
+
+    if (action == "group_profile")
+    {
+        LLGroupActions::show(selected_group);
+    }
+    else if (action == "activate_group")
+    {
+        LLGroupActions::activate(selected_group);
+    }
+    else if (action == "leave_group")
+    {
+        LLGroupActions::leave(selected_group);
+    }
+}
+
 bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
 {
     std::string item = userdata.asString();
@@ -896,7 +928,7 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
 bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
 {
     std::string item = userdata.asString();
-    const LLUUID& id = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem())->getUUID();
+    const LLUUID& id = getCurSelectedViewModelItem()->getUUID();
 
     if (item == std::string("is_blocked"))
     {
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 49a41e5cdd..9754f04fbe 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -112,7 +112,9 @@ private:
 	void setSortOrder(const LLConversationSort& order);
 
     void getSelectedUUIDs(uuid_vec_t& selected_uuids);
-    void doToSelected(const LLSD& userdata);
+    const LLConversationItem * getCurSelectedViewModelItem();
+    void doToSelectedAvatar(const LLSD& userdata);
+    void doToSelectedGroup(const LLSD& userdata);
     bool checkContextMenuItem(const LLSD& userdata);
     bool enableContextMenuItem(const LLSD& userdata);
 
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 94399be61c..bf834ee9ff 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -25,6 +25,24 @@
         <on_click function="Avatar.DoToSelected" parameter="disconnect_from_voice"/>
     </menu_item_call>	
 	<menu_item_separator layout="topleft" name="separator_disconnect_from_voice"/>	
+    <menu_item_call
+     label="Group Profile"
+     layout="topleft"
+     name="group_profile">
+        <on_click function="Group.DoToSelected" parameter="group_profile"/>
+    </menu_item_call>	
+    <menu_item_call
+     label="Activate Group"
+     layout="topleft"
+     name="activate_group">
+        <on_click function="Group.DoToSelected" parameter="activate_group"/>
+    </menu_item_call>		
+    <menu_item_call
+     label="Leave Group"
+     layout="topleft"
+     name="leave_group">
+        <on_click function="Group.DoToSelected" parameter="leave_group"/>
+    </menu_item_call>			
     <menu_item_call
      label="View Profile"
      layout="topleft"
-- 
cgit v1.2.3


From 1ed2915796f610ced2387f5c76b6d10cc508962f Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 2 Oct 2012 11:09:58 -0700
Subject: CHUI-102: Code cleanup, decoupling code and made specific methods for
 handling menu events for conversations or participants.

---
 indra/newview/llimfloatercontainer.cpp | 113 +++++++++++++++++++++------------
 indra/newview/llimfloatercontainer.h   |   5 +-
 2 files changed, 76 insertions(+), 42 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index b7f83e3c23..ad77a7510c 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -64,7 +64,7 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 	
     mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLIMFloaterContainer::checkContextMenuItem,	this, _2));
     mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLIMFloaterContainer::enableContextMenuItem,	this, _2));
-    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelectedAvatar, this, _2));
+    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelected, this, _2));
     
     mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelectedGroup, this, _2));
 
@@ -747,78 +747,109 @@ const LLConversationItem * LLIMFloaterContainer::getCurSelectedViewModelItem()
     return NULL;
 }
 
-void LLIMFloaterContainer::doToSelectedAvatar(const LLSD& userdata)
-{
-    std::string command = userdata.asString();
-    uuid_vec_t selected_uuids;
-    LLUUID currentSelectedUUID;
-    LLIMFloater * conversation;
-
-    getSelectedUUIDs(selected_uuids);
-    //Find the conversation floater associated with the selected id
-    conversation = LLIMFloater::findInstance(selected_uuids.front());
-    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
-
-    //When a one-on-one conversation exists, retrieve the participant id from the conversation floater b/c
-    //selected_uuids.front() does not pertain to the UUID of the person you are having the conversation with.
-    if(conversation && conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
-    {
-        currentSelectedUUID = conversation->getOtherParticipantUUID();
-    }
-    //Otherwise can get the UUID directly from selected_uuids
-    else
-    {
-        currentSelectedUUID = selected_uuids.front();
-    }
+void LLIMFloaterContainer::doToUsers(const std::string& command, uuid_vec_t selectedIDS)
+{dd
+    LLUUID userID;
+    userID = selectedIDS.front();
 
-    //Close the selected conversation
-    if(conversation && "close_conversation" == command)
-    {
-        LLFloater::onClickClose(conversation);
-    }
-    else if ("view_profile" == command)
+    if ("view_profile" == command)
     {
-        LLAvatarActions::showProfile(currentSelectedUUID);
+        LLAvatarActions::showProfile(userID);
     }
     else if("im" == command)
     {
-        LLAvatarActions::startIM(currentSelectedUUID);
+        LLAvatarActions::startIM(userID);
     }
     else if("offer_teleport" == command)
     {
-        LLAvatarActions::offerTeleport(selected_uuids);
+        LLAvatarActions::offerTeleport(selectedIDS);
     }
     else if("voice_call" == command)
     {
-        LLAvatarActions::startCall(currentSelectedUUID);
+        LLAvatarActions::startCall(userID);
     }
     else if("add_friend" == command)
     {
-        LLAvatarActions::requestFriendshipDialog(currentSelectedUUID);
+        LLAvatarActions::requestFriendshipDialog(userID);
     }
     else if("remove_friend" == command)
     {
-        LLAvatarActions::removeFriendDialog(currentSelectedUUID);
+        LLAvatarActions::removeFriendDialog(userID);
     }
     else if("invite_to_group" == command)
     {
-        LLAvatarActions::inviteToGroup(currentSelectedUUID);
+        LLAvatarActions::inviteToGroup(userID);
     }
     else if("map" == command)
     {
-        LLAvatarActions::showOnMap(currentSelectedUUID);
+        LLAvatarActions::showOnMap(userID);
     }
     else if("share" == command)
     {
-        LLAvatarActions::share(currentSelectedUUID);
+        LLAvatarActions::share(userID);
     }
     else if("pay" == command)
     {
-        LLAvatarActions::pay(currentSelectedUUID);
+        LLAvatarActions::pay(userID);
     }
     else if("block_unblock" == command)
     {
-        LLAvatarActions::toggleBlock(currentSelectedUUID);
+        LLAvatarActions::toggleBlock(userID);
+    }
+}
+
+void LLIMFloaterContainer::doToSelectedParticipant(const std::string& command)
+{
+    uuid_vec_t selected_uuids;
+    getSelectedUUIDs(selected_uuids);
+   
+    doToUsers(command, selected_uuids);
+}
+
+void LLIMFloaterContainer::doToSelectedConversation(const std::string& command)
+{
+    LLUUID participantID;
+
+    //Find the conversation floater associated with the selected id
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+    LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
+
+    if(conversationFloater)
+    {
+        //When a one-on-one conversation exists, retrieve the participant id from the conversation floater b/c
+        //selected_uuids.front() does not pertain to the UUID of the person you are having the conversation with.
+        if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+        {
+            participantID = conversationFloater->getOtherParticipantUUID();
+        }
+
+        //Close the selected conversation
+        if("close_conversation" == command)
+        {
+            LLFloater::onClickClose(conversationFloater);
+        }
+        else
+        {
+            uuid_vec_t selected_uuids;
+            selected_uuids.push_back(participantID);
+            doToUsers(command, selected_uuids);
+        }
+    }
+}
+
+void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
+{
+    std::string command = userdata.asString();
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+
+    if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1 ||
+        conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP)
+    {
+        doToSelectedConversation(command);
+    }
+    else
+    {
+        doToSelectedParticipant(command);
     }
 }
 
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 9754f04fbe..a622ddfc8c 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -113,7 +113,10 @@ private:
 
     void getSelectedUUIDs(uuid_vec_t& selected_uuids);
     const LLConversationItem * getCurSelectedViewModelItem();
-    void doToSelectedAvatar(const LLSD& userdata);
+    void doToSelected(const LLSD& userdata);
+    void doToSelectedConversation(const std::string& command);
+    void doToSelectedParticipant(const std::string& command);
+    void doToUsers(const std::string& command, uuid_vec_t selectedIDS);
     void doToSelectedGroup(const LLSD& userdata);
     bool checkContextMenuItem(const LLSD& userdata);
     bool enableContextMenuItem(const LLSD& userdata);
-- 
cgit v1.2.3


From 7ba6111d9149baea48869c2f30506581d2c6babf Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 2 Oct 2012 21:32:23 +0300
Subject: CHUI-190 (Remove the Voice Settings floater): removed the menu item
 "Communicate > Voice settings" and the FUI button (headphones) from the
 Toybox (Toolbox). I left a floater in the project to be able to reconnect it
 to a different location.

---
 indra/newview/app_settings/commands.xml            | 10 ----------
 indra/newview/skins/default/xui/en/menu_viewer.xml | 10 ----------
 2 files changed, 20 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 51211a8ce5..d4bbd84d0f 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -239,14 +239,4 @@
            is_running_function="Floater.IsOpen"
            is_running_parameters="camera"
            />
-  <command name="voice"
-           available_in_toybox="true"
-           icon="Command_Voice_Icon"
-           label_ref="Command_Voice_Label"
-           tooltip_ref="Command_Voice_Tooltip"
-           execute_function="Floater.ToggleOrBringToFront"
-           execute_parameters="voice_controls"
-           is_running_function="Floater.IsOpen"
-           is_running_parameters="voice_controls"
-           />
 </commands>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index aa131035ed..4bbf253e4a 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -243,16 +243,6 @@
              function="Agent.ToggleMicrophone"
              parameter="speak" />
         </menu_item_check>
-        <menu_item_check
-         label="Voice settings..."
-         name="Nearby Voice">
-            <menu_item_check.on_check
-             function="Floater.Visible"
-             parameter="voice_controls" />
-            <menu_item_check.on_click
-             function="Floater.Toggle"
-             parameter="voice_controls" />
-        </menu_item_check>
         <menu_item_check
          label="Voice morphing..."
          name="ShowVoice"
-- 
cgit v1.2.3


From 9d989feede2dbef934cdc459b4758c024df862d6 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 2 Oct 2012 15:10:12 -0700
Subject: CHUI-102: Now the user can select a conversation and use the
 right-click-menu to enable/disable voice.

---
 indra/newview/llconversationmodel.cpp  | 21 +++++++++++++++++++++
 indra/newview/llconversationmodel.h    |  1 +
 indra/newview/llimfloatercontainer.cpp | 13 +++++++++++--
 3 files changed, 33 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 3d1523c874..a3ec154ac6 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -28,6 +28,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llconversationmodel.h"
+#include "llimview.h" //For LLIMModel
 
 //
 // Conversation items : common behaviors
@@ -224,15 +225,35 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
     else if(this->getType() == CONV_SESSION_GROUP)
     {
         items.push_back(std::string("close_conversation"));
+        addVoiceOptions(items);
         items.push_back(std::string("separator_disconnect_from_voice"));
         items.push_back(std::string("group_profile"));
         items.push_back(std::string("activate_group"));
         items.push_back(std::string("leave_group"));
     }
+    else if(this->getType() == CONV_SESSION_AD_HOC)
+    {
+        items.push_back(std::string("close_conversation"));
+        addVoiceOptions(items);
+    }
 
     hide_context_entries(menu, items, disabled_items);
 }
 
+void LLConversationItemSession::addVoiceOptions(menuentry_vec_t& items)
+{
+    LLVoiceChannel* voice_channel = LLIMModel::getInstance() ? LLIMModel::getInstance()->getVoiceChannel(this->getUUID()) : NULL;
+
+    if(voice_channel != LLVoiceChannel::getCurrentVoiceChannel())
+    {
+        items.push_back(std::string("open_voice_conversation"));
+    }
+    else
+    {
+        items.push_back(std::string("disconnect_from_voice"));
+    }
+}
+
 // The time of activity of a session is the time of the most recent activity, session and participants included
 const bool LLConversationItemSession::getTime(F64& time) const
 {
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index f84fbe39f1..bc72cd96ea 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -160,6 +160,7 @@ public:
 	bool isLoaded() { return mIsLoaded; }
 	
     void buildContextMenu(LLMenuGL& menu, U32 flags);
+    void addVoiceOptions(menuentry_vec_t& items);
 	virtual const bool getTime(F64& time) const;
 
 	void dumpDebugData();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index ad77a7510c..7130926212 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -748,7 +748,7 @@ const LLConversationItem * LLIMFloaterContainer::getCurSelectedViewModelItem()
 }
 
 void LLIMFloaterContainer::doToUsers(const std::string& command, uuid_vec_t selectedIDS)
-{dd
+{
     LLUUID userID;
     userID = selectedIDS.front();
 
@@ -828,6 +828,14 @@ void LLIMFloaterContainer::doToSelectedConversation(const std::string& command)
         {
             LLFloater::onClickClose(conversationFloater);
         }
+        else if("open_voice_conversation" == command)
+        {
+            gIMMgr->startCall(conversationItem->getUUID());
+        }
+        else if("disconnect_from_voice" == command)
+        {
+            gIMMgr->endCall(conversationItem->getUUID());
+        }
         else
         {
             uuid_vec_t selected_uuids;
@@ -843,7 +851,8 @@ void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
     const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
 
     if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1 ||
-        conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP)
+        conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP ||
+        conversationItem->getType() == LLConversationItem::CONV_SESSION_AD_HOC)
     {
         doToSelectedConversation(command);
     }
-- 
cgit v1.2.3


From ed9ade7d50b699ac60eb69a979ea32a60eefa630 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 2 Oct 2012 17:03:46 -0700
Subject: CHUI-102: Now the options menu (right-click menu) for a
 participant/conversation will open the 'Chat history' dialog when selected.

---
 indra/newview/llconversationmodel.cpp              |  4 ++-
 indra/newview/llimfloatercontainer.cpp             |  8 +++++
 .../skins/default/xui/en/menu_conversation.xml     | 36 +++++++++++-----------
 3 files changed, 29 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a3ec154ac6..5fc305da81 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -226,7 +226,8 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
     {
         items.push_back(std::string("close_conversation"));
         addVoiceOptions(items);
-        items.push_back(std::string("separator_disconnect_from_voice"));
+        items.push_back(std::string("chat_history"));
+        items.push_back(std::string("separator_chat_history"));
         items.push_back(std::string("group_profile"));
         items.push_back(std::string("activate_group"));
         items.push_back(std::string("leave_group"));
@@ -235,6 +236,7 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
     {
         items.push_back(std::string("close_conversation"));
         addVoiceOptions(items);
+        items.push_back(std::string("chat_history"));
     }
 
     hide_context_entries(menu, items, disabled_items);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 7130926212..11aecde6e2 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -768,6 +768,10 @@ void LLIMFloaterContainer::doToUsers(const std::string& command, uuid_vec_t sele
     {
         LLAvatarActions::startCall(userID);
     }
+    else if("chat_history" == command)
+    {
+        LLAvatarActions::viewChatHistory(userID);
+    }
     else if("add_friend" == command)
     {
         LLAvatarActions::requestFriendshipDialog(userID);
@@ -836,6 +840,10 @@ void LLIMFloaterContainer::doToSelectedConversation(const std::string& command)
         {
             gIMMgr->endCall(conversationItem->getUUID());
         }
+        else if("chat_history" == command)
+        {
+            LLAvatarActions::viewChatHistory(conversationItem->getUUID());
+        }
         else
         {
             uuid_vec_t selected_uuids;
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index bf834ee9ff..912ff811d9 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -25,24 +25,6 @@
         <on_click function="Avatar.DoToSelected" parameter="disconnect_from_voice"/>
     </menu_item_call>	
 	<menu_item_separator layout="topleft" name="separator_disconnect_from_voice"/>	
-    <menu_item_call
-     label="Group Profile"
-     layout="topleft"
-     name="group_profile">
-        <on_click function="Group.DoToSelected" parameter="group_profile"/>
-    </menu_item_call>	
-    <menu_item_call
-     label="Activate Group"
-     layout="topleft"
-     name="activate_group">
-        <on_click function="Group.DoToSelected" parameter="activate_group"/>
-    </menu_item_call>		
-    <menu_item_call
-     label="Leave Group"
-     layout="topleft"
-     name="leave_group">
-        <on_click function="Group.DoToSelected" parameter="leave_group"/>
-    </menu_item_call>			
     <menu_item_call
      label="View Profile"
      layout="topleft"
@@ -124,4 +106,22 @@
 		<on_check function="Avatar.CheckItem" parameter="is_blocked" />
 		<on_enable  function="Avatar.EnableItem" parameter="can_block" />
     </menu_item_check>
+	<menu_item_call
+     label="Group Profile"
+     layout="topleft"
+     name="group_profile">
+        <on_click function="Group.DoToSelected" parameter="group_profile"/>
+    </menu_item_call>	
+    <menu_item_call
+     label="Activate Group"
+     layout="topleft"
+     name="activate_group">
+        <on_click function="Group.DoToSelected" parameter="activate_group"/>
+    </menu_item_call>		
+    <menu_item_call
+     label="Leave Group"
+     layout="topleft"
+     name="leave_group">
+        <on_click function="Group.DoToSelected" parameter="leave_group"/>
+    </menu_item_call>
 </toggleable_menu>
-- 
cgit v1.2.3


From 7e1fbd1a897e3238a101f1db2d155f0493beaac5 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 2 Oct 2012 17:56:01 -0700
Subject: CHUI-102: Code review, just changed function
 getCurSelectedViewModelItem() to have a single return statement.

---
 indra/newview/llimfloatercontainer.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 11aecde6e2..a33fc2c57e 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -737,14 +737,16 @@ void LLIMFloaterContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
 
 const LLConversationItem * LLIMFloaterContainer::getCurSelectedViewModelItem()
 {
+    LLConversationItem * conversationItem = NULL;
+
     if(mConversationsRoot && 
         mConversationsRoot->getCurSelectedItem() && 
         mConversationsRoot->getCurSelectedItem()->getViewModelItem())
     {
-        return static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
+        conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
     }
 
-    return NULL;
+    return conversationItem;
 }
 
 void LLIMFloaterContainer::doToUsers(const std::string& command, uuid_vec_t selectedIDS)
-- 
cgit v1.2.3


From a8159facdeb478abf094d8ba8ad229c0e282f9f6 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 2 Oct 2012 19:36:46 +0300
Subject: CHUI-374 FIXED (Nearby chat is torn off and cannot be docked if
 nearby chat is received while conversation floater is closed) Nearby_chat is
 created only after the creation of the im_container

---
 indra/newview/llimfloater.cpp          | 28 +++++++++++++++-------------
 indra/newview/llimfloatercontainer.cpp | 11 ++++++++---
 indra/newview/llnearbychat.cpp         | 16 +++++++++++++++-
 indra/newview/llnearbychat.h           |  5 +++++
 indra/newview/llnearbychathandler.cpp  |  1 +
 indra/newview/llviewerfloaterreg.cpp   |  2 +-
 6 files changed, 45 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index d11504d312..99337bd5f3 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -111,23 +111,25 @@ void LLIMFloater::onClickCloseBtn()
 {
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
 
-	if (session == NULL)
+	if (session != NULL)
 	{
-		llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl;
-		return;
-	}
+		bool is_call_with_chat = session->isGroupSessionType()
+				|| session->isAdHocSessionType() || session->isP2PSessionType();
 
-	bool is_call_with_chat = session->isGroupSessionType()
-			|| session->isAdHocSessionType() || session->isP2PSessionType();
+		LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
 
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-	if (is_call_with_chat && voice_channel != NULL
-			&& voice_channel->isActive())
+		if (is_call_with_chat && voice_channel != NULL
+				&& voice_channel->isActive())
+		{
+			LLSD payload;
+			payload["session_id"] = mSessionID;
+			LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+			return;
+		}
+	}
+	else
 	{
-		LLSD payload;
-		payload["session_id"] = mSessionID;
-		LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+		llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl;
 		return;
 	}
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index a33fc2c57e..237748179c 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -463,21 +463,26 @@ void LLIMFloaterContainer::tabClose()
 }
 
 void LLIMFloaterContainer::setVisible(BOOL visible)
-{
+{	LLNearbyChat* nearby_chat;
 	if (visible)
 	{
 		// Make sure we have the Nearby Chat present when showing the conversation container
-		LLIMConversation* nearby_chat = LLFloaterReg::findTypedInstance<LLIMConversation>("nearby_chat");
+		nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
 		if (nearby_chat == NULL)
 		{
 			// If not found, force the creation of the nearby chat conversation panel
 			// *TODO: find a way to move this to XML as a default panel or something like that
 			LLSD name("nearby_chat");
 			LLFloaterReg::toggleInstanceOrBringToFront(name);
-			LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat")->addToHost();
 		}
 	}
 
+	nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
+	if (nearby_chat && !nearby_chat->isHostSet())
+	{
+		nearby_chat->addToHost();
+	}
+
 	// We need to show/hide all the associated conversations that have been torn off
 	// (and therefore, are not longer managed by the multifloater),
 	// so that they show/hide with the conversations manager.
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 4b35092f2d..b96b486868 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -91,7 +91,8 @@ LLNearbyChat::LLNearbyChat(const LLSD& llsd)
 :	LLIMConversation(llsd),
 	//mOutputMonitor(NULL),
 	mSpeakerMgr(NULL),
-	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
+	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT),
+	mIsHostSet(false)
 {
     mIsP2PChat = false;
 	mIsNearbyChat = true;
@@ -100,6 +101,12 @@ LLNearbyChat::LLNearbyChat(const LLSD& llsd)
 	mSessionID = LLUUID();
 }
 
+//static
+LLNearbyChat* LLNearbyChat::buildFloater(const LLSD& key)
+{
+    LLFloaterReg::getInstance("im_container");
+    return new LLNearbyChat(key);
+}
 
 //virtual
 BOOL LLNearbyChat::postBuild()
@@ -304,9 +311,16 @@ void LLNearbyChat::addToHost()
 				setHost(NULL);
 			}
 		}
+
+		mIsHostSet = true;
 	}
 }
 
+bool LLNearbyChat::isHostSet()
+{
+    return mIsHostSet;
+}
+
 // virtual
 void LLNearbyChat::onOpen(const LLSD& key)
 {
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 3987212e4c..93168ba96a 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -48,6 +48,8 @@ public:
 	LLNearbyChat(const LLSD& key = LLSD(LLUUID()));
 	~LLNearbyChat() {}
 
+	static LLNearbyChat* buildFloater(const LLSD& key);
+
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 
@@ -76,6 +78,8 @@ public:
 	static void startChat(const char* line);
 	static void stopChat();
 
+	bool isHostSet();
+
 	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
 	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
 
@@ -117,6 +121,7 @@ private:
 	LLHandle<LLView>	mPopupMenuHandle;
 	std::vector<LLChat> mMessageArchive;
 
+    bool mIsHostSet;
 };
 
 #endif
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index f3e17ea61b..7834f6d320 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -487,6 +487,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	if(chat_msg.mText.empty())
 		return;//don't process empty messages
 
+    LLFloaterReg::getInstance("im_container");
 	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
 
 	// Build notification data 
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 4cd5ecc754..c751550523 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -194,7 +194,7 @@ void LLViewerFloaterReg::registerFloaters()
 
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
 	LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
-	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChat>);
+	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLNearbyChat::buildFloater);
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
 	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
 
-- 
cgit v1.2.3


From 4a25ce8b9d5d56b160d0d13c4681cd916c4ea4e0 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 2 Oct 2012 22:34:44 -0700
Subject: CHUI-341 : Implement the use of LLEventStream and LLEventPump to
 signal conversation model changes, picked by LLIMFloaterContainer. Suppress
 pooling on draw().

---
 indra/newview/llconversationmodel.cpp  | 16 +++++++++++++
 indra/newview/llconversationmodel.h    |  2 ++
 indra/newview/llimfloatercontainer.cpp | 41 +++++++++++++++++++++++++---------
 indra/newview/llimfloatercontainer.h   |  3 +++
 4 files changed, 52 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 9fa8758d11..1057dbaf31 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -27,6 +27,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llevents.h"
 #include "llconversationmodel.h"
 
 //
@@ -63,6 +64,18 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 {
 }
 
+void LLConversationItem::postEvent(const std::string& event_type)
+{
+	LLSD event;
+	event["pump"] = "ConversationModelEvent";
+	LLSD payload;
+	payload["type"] = event_type;
+	payload["name"] = getName();
+	payload["uuid"] = getUUID();
+	event["payload"] = payload;
+	LLEventPumps::instance().obtain("ConversationsEvents").post(event);
+}
+
 // Virtual action callbacks
 void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
 {
@@ -111,12 +124,14 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
 	addChild(participant);
 	mIsLoaded = true;
 	mNeedsRefresh = true;
+	postEvent("add_participant");
 }
 
 void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
 {
 	removeChild(participant);
 	mNeedsRefresh = true;
+	postEvent("remove_participant");
 }
 
 void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
@@ -254,6 +269,7 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
 	mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
 	mNeedsRefresh = true;
+	postEvent("update_participant");
 	if (mParent)
 	{
 		mParent->requestSort();
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 30f94d51ae..97e5b0fc31 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -124,6 +124,8 @@ public:
 	void resetRefresh() { mNeedsRefresh = false; }
 	bool needsRefresh() { return mNeedsRefresh; }
 	
+	void postEvent(const std::string& event_type);
+	
 protected:
 	std::string mName;	// Name of the session or the participant
 	LLUUID mUUID;		// UUID of the session or the participant
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 6f7eb7822a..8642eaf5e1 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -49,6 +49,7 @@
 #include "llcallbacklist.h"
 #include "llworld.h"
 
+#include "llsdserialize.h"
 //
 // LLIMFloaterContainer
 //
@@ -56,6 +57,7 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 :	LLMultiFloater(seed),
 	mExpandCollapseBtn(NULL),
 	mConversationsRoot(NULL),
+	mStream("ConversationsEvents"),
 	mInitialized(false)
 {
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLIMFloaterContainer::onCustomAction,  this, _2));
@@ -136,6 +138,9 @@ BOOL LLIMFloaterContainer::postBuild()
     p.use_ellipses = true;
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
 
+	// Add listener to conversation model events
+	mStream.listen("ConversationsRefresh", boost::bind(&LLIMFloaterContainer::onConversationModelEvent, this, _1));
+
 	// a scroller for folder view
 	LLRect scroller_view_rect = mConversationsListPanel->getRect();
 	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
@@ -378,18 +383,29 @@ void LLIMFloaterContainer::idle(void* user_data)
 	self->mConversationsRoot->update();
 }
 
-void LLIMFloaterContainer::draw()
+bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 {
-	// CHUI Notes
-	// Currently, the model is not responsible for creating the view which is a good thing. This means that
+	// For debug only
+	//std::ostringstream llsd_value;
+	//llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
+	//llinfos << "Merov debug : onConversationModelEvent, event = " << llsd_value.str() << llendl;
+	// end debug
+	
+	// Note: In conversations, the model is not responsible for creating the view which is a good thing. This means that
 	// the model could change substantially and the view could decide to echo only a portion of this model.
 	// Consequently, the participant views need to be created either by the session view or by the container panel.
-	// For the moment, we create them here (which makes for complicated code...) to conform to the pattern
-	// implemented in llinventorypanel.cpp (see LLInventoryPanel::buildNewViews()).
-	// The best however would be to have an observer on the model so that we would not pool on each draw to know
-	// if the view needs refresh. The current implementation (testing for change on draw) is less
-	// efficient perf wise than a listener/observer scheme. We will implement that shortly.
-	
+	// For the moment, we create them here to conform to the pattern implemented in llinventorypanel.cpp 
+	// (see LLInventoryPanel::buildNewViews()).
+
+	// Note: For the moment, we're not very smart about the event paramter and we just refresh the whole set of views/widgets
+	// according to the current state of the whole model.
+	// We should at least analyze the event payload and do things differently for a handful of useful cases:
+	// - add session or participant
+	// - remove session or participant
+	// - update session or participant (e.g. rename, change sort order, etc...)
+	// see LLConversationItem::postEvent() for the payload formatting.
+	// *TODO: Add handling for various event signatures (add, remove, update, resort)
+
 	// On each session in mConversationsItems
 	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
 	{
@@ -418,7 +434,7 @@ void LLIMFloaterContainer::draw()
 				participant_view->setVisible(TRUE);
 			}
 			else
-			// Else, see if it needs refresh
+				// Else, see if it needs refresh
 			{
 				if (participant_model->needsRefresh())
 				{
@@ -434,6 +450,11 @@ void LLIMFloaterContainer::draw()
 		}
 	}
 	
+	return false;
+}
+
+void LLIMFloaterContainer::draw()
+{
 	if (mTabContainer->getTabCount() == 0)
 	{
 		// Do not close the container when every conversation is torn off because the user
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 2debc2455b..8e953025bc 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -31,6 +31,7 @@
 #include <vector>
 
 #include "llimview.h"
+#include "llevents.h"
 #include "llfloater.h"
 #include "llmultifloater.h"
 #include "llavatarpropertiesprocessor.h"
@@ -130,6 +131,7 @@ public:
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
 	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+	bool onConversationModelEvent(const LLSD& event);
 
 	// Conversation list data
 	LLPanel* mConversationsListPanel;	// This is the main widget we add conversation widget to
@@ -137,6 +139,7 @@ private:
 	conversations_widgets_map mConversationsWidgets;
 	LLConversationViewModel mConversationViewModel;
 	LLFolderView* mConversationsRoot;
+	LLEventStream mStream; 
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H
-- 
cgit v1.2.3


From 2c15f6eca629e65c9c87dc87e4da59718aada039 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 3 Oct 2012 13:30:17 +0300
Subject: CHUI-354 FIXED getIconOverlay() is added for LLItemBridge

---
 indra/newview/llinventorybridge.cpp | 9 +++++++++
 indra/newview/llinventorybridge.h   | 1 +
 2 files changed, 10 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 72c54e5ce2..139713b96e 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1531,6 +1531,15 @@ LLUIImagePtr LLItemBridge::getIcon() const
 	return LLInventoryIcon::getIcon(LLInventoryIcon::ICONNAME_OBJECT);
 }
 
+LLUIImagePtr LLItemBridge::getIconOverlay() const
+{
+	if (getItem() && getItem()->getIsLinkType())
+	{
+		return LLUI::getUIImage("Inv_Link");
+	}
+	return NULL;
+}
+
 PermissionMask LLItemBridge::getPermissionMask() const
 {
 	LLViewerInventoryItem* item = getItem();
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 6beccf19ae..b33972167c 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -228,6 +228,7 @@ public:
 	virtual BOOL isItemCopyable() const;
 	virtual bool hasChildren() const { return FALSE; }
 	virtual BOOL isUpToDate() const { return TRUE; }
+	virtual LLUIImagePtr getIconOverlay() const;
 
 	LLViewerInventoryItem* getItem() const;
 
-- 
cgit v1.2.3


From bb2f48cb93a142deed863287d009017177e6a0be Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 3 Oct 2012 13:55:09 +0300
Subject: CHUI-301 FIXED Tooltips for buttons are added

---
 indra/newview/skins/default/xui/en/floater_conversation_log.xml        | 2 ++
 .../newview/skins/default/xui/en/panel_conversation_log_list_item.xml  | 3 +++
 2 files changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index 12d17e6b37..c9c52e5ce5 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -49,6 +49,7 @@
           menu_filename="menu_conversation_log_view.xml"
           menu_position="bottomleft"
           name="conversation_view_btn"
+          tool_tip="View/sort options"
           top="3"
           width="31" />
         <menu_button
@@ -61,6 +62,7 @@
           layout="topleft"
           left_pad="2"
           name="conversations_gear_btn"
+          tool_tip="Actions on selected person or group"
           top="3"
           width="31" />
     </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
index 8a58eb1ca6..78d4c174d2 100644
--- a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
@@ -35,6 +35,7 @@
      image_name="Conv_toolbar_open_call"
      mouse_opaque="true"
      name="voice_session_icon"
+     tool_tip="Included a voice conversation"
      top="2"
      visible="false"
      width="20" />
@@ -46,6 +47,7 @@
      image_name="Conv_log_inbox"
      mouse_opaque="false"
      name="unread_ims_icon"
+     tool_tip="Messages arrived while you were logged out"
      top="2"
      visible="false"
      width="20" />
@@ -92,6 +94,7 @@
      width="110"/>
     <button
      name="delete_btn"
+     tool_tip="Remove this entry"
      layout="topleft"
      follows="top|right"
      image_unselected="Conv_toolbar_close"
-- 
cgit v1.2.3


From 7535d3b5daa235540bbd5f0e784fc3fba484d614 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 3 Oct 2012 14:07:01 +0300
Subject: CHUI-322 FIXED Call SideTray.PanelPeopleTab with
 parameter="blocked_panel" instead of Communicate.BlockList

---
 indra/newview/llviewermenu.cpp                     | 16 ++--------------
 indra/newview/skins/default/xui/en/menu_viewer.xml |  3 ++-
 2 files changed, 4 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index a993d195b5..6da9296ea3 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3466,7 +3466,8 @@ class LLTogglePanelPeopleTab : public view_listener_t
 
 		if (   panel_name == "friends_panel"
 			|| panel_name == "groups_panel"
-			|| panel_name == "nearby_panel")
+			|| panel_name == "nearby_panel"
+			|| panel_name == "blocked_panel")
 		{
 			return togglePeoplePanel(panel_name, param);
 		}
@@ -5490,16 +5491,6 @@ void toggle_debug_menus(void*)
 // 	gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects...");
 // }
 //
-
-class LLCommunicateBlockList : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
-		return true;
-	}
-};
-
 class LLWorldSetHomeLocation : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -8290,9 +8281,6 @@ void initialize_menus()
 	// Me > Movement
 	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
 	
-	// Communicate
-	view_listener_t::addMenu(new LLCommunicateBlockList(), "Communicate.BlockList");
-	
 	// World menu
 	view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
 	view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 4bbf253e4a..88b30c8272 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -294,7 +294,8 @@
          label="Block List"
          name="Block List">
             <menu_item_call.on_click
-              function="Communicate.BlockList" />
+              function="SideTray.PanelPeopleTab"
+              parameter="blocked_panel" />
         </menu_item_call>
     </menu>
     <menu
-- 
cgit v1.2.3


From 7f3f5cc408d7b36478c7dd707e32f921c1e1b720 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 3 Oct 2012 16:56:27 +0300
Subject: CHUI-378 FIXED (Conversation floater is not opened if call initiated
 and accepted with conversation floater closed - goes to voice settings
 floater): added open conversation floater on the voice channel's changing

---
 indra/newview/llappviewer.cpp          |  3 ++-
 indra/newview/llcallfloater.cpp        |  3 ++-
 indra/newview/llcallfloater.h          |  4 ++--
 indra/newview/llimfloatercontainer.cpp | 10 ++++++++++
 indra/newview/llimfloatercontainer.h   |  4 ++--
 5 files changed, 18 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 08a1a237f5..6b15e4b21a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -42,6 +42,7 @@
 #include "llagentcamera.h"
 #include "llagentlanguage.h"
 #include "llagentwearables.h"
+#include "llimfloatercontainer.h"
 #include "llwindow.h"
 #include "llviewerstats.h"
 #include "llviewerstatsrecorder.h"
@@ -1204,7 +1205,7 @@ bool LLAppViewer::mainLoop()
 
 	LLVoiceChannel::initClass();
 	LLVoiceClient::getInstance()->init(gServicePump);
-	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1), true);
+	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLIMFloaterContainer::onCurrentChannelChanged, _1), true);
 	LLTimer frameTimer,idleTimer;
 	LLTimer debugTime;
 	LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index 38b755004c..e767609d74 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -364,7 +364,8 @@ void LLCallFloater::onAvatarListRefreshed()
 }
 
 // static
-void LLCallFloater::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
+// This entry point now disable, but left for later use.
+void LLCallFloater::onCurrentChannelChanged(const LLUUID& /*session_id*/)
 {
 	LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
 
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
index 181c92276d..e1c7b3f43a 100644
--- a/indra/newview/llcallfloater.h
+++ b/indra/newview/llcallfloater.h
@@ -74,7 +74,7 @@ public:
 	 */
 	/*virtual*/ void onParticipantsChanged();
 
-	static void sOnCurrentChannelChanged(const LLUUID& session_id);
+	static void onCurrentChannelChanged(const LLUUID& session_id);
 
 private:
 	typedef enum e_voice_controls_type
@@ -260,7 +260,7 @@ private:
 	 *
 	 * Is used to ignore voice channel changed callback for the same channel.
 	 *
-	 * @see sOnCurrentChannelChanged()
+	 * @see onCurrentChannelChanged()
 	 */
 	static LLVoiceChannel* sCurrentVoiceChannel;
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 237748179c..5a323583b8 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -114,6 +114,16 @@ void LLIMFloaterContainer::sessionRemoved(const LLUUID& session_id)
 	removeConversationListItem(session_id);
 }
 
+// static
+void LLIMFloaterContainer::onCurrentChannelChanged(const LLUUID& session_id)
+{
+    if (session_id != LLUUID::null)
+    {
+    	LLIMFloater::show(session_id);
+    }
+}
+
+
 BOOL LLIMFloaterContainer::postBuild()
 {
 	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index a622ddfc8c..081c733884 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -66,11 +66,11 @@ public:
 	/*virtual*/ void tabClose();
 
 	static LLFloater* getCurrentVoiceFloater();
-
 	static LLIMFloaterContainer* findInstance();
-
 	static LLIMFloaterContainer* getInstance();
 
+	static void onCurrentChannelChanged(const LLUUID& session_id);
+
 	virtual void setMinimized(BOOL b);
 
 	void collapseMessagesPane(bool collapse);
-- 
cgit v1.2.3


From 9c3bbd378332a3dca8c58d0e3e351fd038e3f61b Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 3 Oct 2012 14:31:13 -0700
Subject: CHUI-102: Now the options enabled in the one-on-one conversation menu
 are the same as the participants menu. In prior commits the one-on-one
 conversations menu was not enabling/disabling the proper menu options.

---
 indra/newview/llimfloatercontainer.cpp | 75 +++++++++++++++++++---------------
 indra/newview/llimfloatercontainer.h   |  6 +--
 2 files changed, 46 insertions(+), 35 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 5a323583b8..4af170b3db 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -764,10 +764,29 @@ const LLConversationItem * LLIMFloaterContainer::getCurSelectedViewModelItem()
     return conversationItem;
 }
 
-void LLIMFloaterContainer::doToUsers(const std::string& command, uuid_vec_t selectedIDS)
+void LLIMFloaterContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
 {
-    LLUUID userID;
-    userID = selectedIDS.front();
+    //Find the conversation floater associated with the selected id
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+
+    if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
+    {
+        getSelectedUUIDs(selected_uuids);
+    }
+    //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
+    else if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+    {
+        LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
+        LLUUID participantID = conversationFloater->getOtherParticipantUUID();
+        selected_uuids.push_back(participantID);
+    }    
+}
+
+void LLIMFloaterContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
+{
+    if(selectedIDS.size() > 0)
+{
+        const LLUUID userID = selectedIDS.front();
 
     if ("view_profile" == command)
     {
@@ -818,32 +837,16 @@ void LLIMFloaterContainer::doToUsers(const std::string& command, uuid_vec_t sele
         LLAvatarActions::toggleBlock(userID);
     }
 }
-
-void LLIMFloaterContainer::doToSelectedParticipant(const std::string& command)
-{
-    uuid_vec_t selected_uuids;
-    getSelectedUUIDs(selected_uuids);
-   
-    doToUsers(command, selected_uuids);
 }
 
-void LLIMFloaterContainer::doToSelectedConversation(const std::string& command)
+void LLIMFloaterContainer::doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS)
 {
-    LLUUID participantID;
-
     //Find the conversation floater associated with the selected id
     const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
     LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
 
     if(conversationFloater)
     {
-        //When a one-on-one conversation exists, retrieve the participant id from the conversation floater b/c
-        //selected_uuids.front() does not pertain to the UUID of the person you are having the conversation with.
-        if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
-        {
-            participantID = conversationFloater->getOtherParticipantUUID();
-        }
-
         //Close the selected conversation
         if("close_conversation" == command)
         {
@@ -863,9 +866,7 @@ void LLIMFloaterContainer::doToSelectedConversation(const std::string& command)
         }
         else
         {
-            uuid_vec_t selected_uuids;
-            selected_uuids.push_back(participantID);
-            doToUsers(command, selected_uuids);
+            doToParticipants(command, selectedIDS);
         }
     }
 }
@@ -874,16 +875,17 @@ void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
 {
     std::string command = userdata.asString();
     const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+    uuid_vec_t selected_uuids;
+
+    getParticipantUUIDs(selected_uuids);
 
-    if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1 ||
-        conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP ||
-        conversationItem->getType() == LLConversationItem::CONV_SESSION_AD_HOC)
+    if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
     {
-        doToSelectedConversation(command);
+        doToParticipants(command, selected_uuids);
     }
     else
     {
-        doToSelectedParticipant(command);
+        doToSelectedConversation(command, selected_uuids);
     }
 }
 
@@ -910,7 +912,12 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
 {
     std::string item = userdata.asString();
     uuid_vec_t mUUIDs;
-    getSelectedUUIDs(mUUIDs);
+    getParticipantUUIDs(mUUIDs);
+
+    if(mUUIDs.size() <= 0)
+    {
+        return false;
+    }
 
     // Note: can_block and can_delete is used only for one person selected menu
     // so we don't need to go over all uuids.
@@ -932,7 +939,7 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
             return false;
         }
 
-        bool result = (mUUIDs.size() > 0);
+        bool result = true;
 
         uuid_vec_t::const_iterator
             id = mUUIDs.begin(),
@@ -993,11 +1000,15 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
 bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
 {
     std::string item = userdata.asString();
-    const LLUUID& id = getCurSelectedViewModelItem()->getUUID();
+    uuid_vec_t mUUIDs;
+    getParticipantUUIDs(mUUIDs);
 
+    if(mUUIDs.size() > 0 )
+    {
     if (item == std::string("is_blocked"))
     {
-        return LLAvatarActions::isBlocked(id);
+            return LLAvatarActions::isBlocked(mUUIDs.front());
+        }
     }
 
     return false;
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 081c733884..76e468f979 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -113,10 +113,10 @@ private:
 
     void getSelectedUUIDs(uuid_vec_t& selected_uuids);
     const LLConversationItem * getCurSelectedViewModelItem();
+    void getParticipantUUIDs(uuid_vec_t& selected_uuids);
     void doToSelected(const LLSD& userdata);
-    void doToSelectedConversation(const std::string& command);
-    void doToSelectedParticipant(const std::string& command);
-    void doToUsers(const std::string& command, uuid_vec_t selectedIDS);
+    void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS);
+    void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
     void doToSelectedGroup(const LLSD& userdata);
     bool checkContextMenuItem(const LLSD& userdata);
     bool enableContextMenuItem(const LLSD& userdata);
-- 
cgit v1.2.3


From efd8910069a01d8440e45f350979054f88e794cb Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 4 Oct 2012 00:57:43 +0300
Subject: CHUI-331 FIXED (Resizing conversation list when message panel is
 collapsed does not resize list)

---
 indra/llui/lllayoutstack.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 4c730286da..be6d359c9a 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -767,7 +767,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 			{	// freeze new size as fraction
 				F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
 					? MAX_FRACTIONAL_SIZE
-					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim() - 1) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
 				fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
 				fraction_remaining -= panelp->mFractionalSize;
 				panelp->mFractionalSize = new_fractional_size;
-- 
cgit v1.2.3


From f2510ca0d629a2cd6cd85588698672f5a0c4e64a Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 4 Oct 2012 02:26:48 +0300
Subject: CHUI-165 FIXED Add access to Conversation Log and Chat History from
 the People floater: the 'View Chat History' action was updated;

---
 indra/newview/llavataractions.cpp | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index a76dbcac53..248685b964 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -42,6 +42,7 @@
 #include "llappviewer.h"		// for gLastVersionChannel
 #include "llcachename.h"
 #include "llcallingcard.h"		// for LLAvatarTracker
+#include "llconversationlog.h"
 #include "llfloateravatarpicker.h"	// for LLFloaterAvatarPicker
 #include "llfloatergroupinvite.h"
 #include "llfloatergroups.h"
@@ -900,7 +901,17 @@ void LLAvatarActions::inviteToGroup(const LLUUID& id)
 // static
 void LLAvatarActions::viewChatHistory(const LLUUID& id)
 {
-	LLFloaterReg::showInstance("preview_conversation", id, true);
+	const std::vector<LLConversation>& conversations = LLConversationLog::instance().getConversations();
+	std::vector<LLConversation>::const_iterator iter = conversations.begin();
+
+	for (; iter != conversations.end(); ++iter)
+	{
+		if (iter->getParticipantID() == id)
+		{
+			LLFloaterReg::showInstance("preview_conversation", iter->getSessionID(), true);
+			break;
+		}
+	}
 }
 
 //== private methods ========================================================================================
-- 
cgit v1.2.3


From bd64c483639ae33518609398fce7c51ddc73dae7 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 3 Oct 2012 16:46:46 -0700
Subject: CHUI-358 : Fixed the removal of participants as they leave
 conversations. Used the event mechanism for this.

---
 indra/newview/llconversationmodel.cpp  | 18 ++++++++----------
 indra/newview/llconversationmodel.h    |  2 +-
 indra/newview/llimfloatercontainer.cpp | 31 +++++++++++++++++++++++++------
 3 files changed, 34 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 1057dbaf31..7ddb725fb1 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -64,15 +64,13 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 {
 }
 
-void LLConversationItem::postEvent(const std::string& event_type)
+void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemParticipant* participant)
 {
 	LLSD event;
-	event["pump"] = "ConversationModelEvent";
-	LLSD payload;
-	payload["type"] = event_type;
-	payload["name"] = getName();
-	payload["uuid"] = getUUID();
-	event["payload"] = payload;
+	event["type"] = event_type;
+	event["session_uuid"] = getUUID();
+	event["participant_name"] = participant->getName();
+	event["participant_uuid"] = participant->getUUID();
 	LLEventPumps::instance().obtain("ConversationsEvents").post(event);
 }
 
@@ -124,14 +122,14 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
 	addChild(participant);
 	mIsLoaded = true;
 	mNeedsRefresh = true;
-	postEvent("add_participant");
+	postEvent("add_participant", participant);
 }
 
 void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
 {
 	removeChild(participant);
 	mNeedsRefresh = true;
-	postEvent("remove_participant");
+	postEvent("remove_participant", participant);
 }
 
 void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
@@ -269,7 +267,7 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
 	mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
 	mNeedsRefresh = true;
-	postEvent("update_participant");
+	postEvent("update_participant", this);
 	if (mParent)
 	{
 		mParent->requestSort();
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 97e5b0fc31..32280f3293 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -124,7 +124,7 @@ public:
 	void resetRefresh() { mNeedsRefresh = false; }
 	bool needsRefresh() { return mNeedsRefresh; }
 	
-	void postEvent(const std::string& event_type);
+	void postEvent(const std::string& event_type, LLConversationItemParticipant* participant);
 	
 protected:
 	std::string mName;	// Name of the session or the participant
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 8642eaf5e1..e58154b2a2 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -391,21 +391,39 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	//llinfos << "Merov debug : onConversationModelEvent, event = " << llsd_value.str() << llendl;
 	// end debug
 	
-	// Note: In conversations, the model is not responsible for creating the view which is a good thing. This means that
-	// the model could change substantially and the view could decide to echo only a portion of this model.
+	// Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
+	// the model could change substantially and the view could echo only a portion of this model (though currently the 
+	// conversation view does echo the conversation model 1 to 1).
 	// Consequently, the participant views need to be created either by the session view or by the container panel.
-	// For the moment, we create them here to conform to the pattern implemented in llinventorypanel.cpp 
+	// For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp 
 	// (see LLInventoryPanel::buildNewViews()).
 
-	// Note: For the moment, we're not very smart about the event paramter and we just refresh the whole set of views/widgets
+	// Note: For the moment, we're not very smart about the event parameter and we just refresh the whole set of views/widgets
 	// according to the current state of the whole model.
-	// We should at least analyze the event payload and do things differently for a handful of useful cases:
+	// We should at least analyze the event payload and do things differently for a handful of cases:
 	// - add session or participant
 	// - remove session or participant
 	// - update session or participant (e.g. rename, change sort order, etc...)
-	// see LLConversationItem::postEvent() for the payload formatting.
+	// Please see LLConversationItem::postEvent() for the payload formatting.
 	// *TODO: Add handling for various event signatures (add, remove, update, resort)
 
+	std::string type = event.get("type").asString();
+	if (type == "remove_participant")
+	{
+		LLUUID session_id = event.get("session_uuid").asUUID();
+		LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
+		LLUUID participant_id = event.get("participant_uuid").asUUID();
+		LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+		if (participant_view)
+		{
+			session_view->extractItem(participant_view);
+			delete participant_view;
+			session_view->refresh();
+			mConversationsRoot->arrangeAll();
+		}
+	}
+	else 
+	{
 	// On each session in mConversationsItems
 	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
 	{
@@ -449,6 +467,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 			current_participant_model++;
 		}
 	}
+	}
 	
 	return false;
 }
-- 
cgit v1.2.3


From 5d846e141464f02a1d896ffa82d639f973f8044b Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 3 Oct 2012 19:06:33 -0700
Subject: CHUI-341 : Fixed. Took Nat's review comments into account.

---
 indra/newview/llconversationmodel.cpp  | 7 ++-----
 indra/newview/llimfloatercontainer.cpp | 2 ++
 2 files changed, 4 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 0f29ffe77f..3c111c919a 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -28,6 +28,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llevents.h"
+#include "llsdutil.h"
 #include "llconversationmodel.h"
 #include "llimview.h" //For LLIMModel
 
@@ -67,11 +68,7 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 
 void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemParticipant* participant)
 {
-	LLSD event;
-	event["type"] = event_type;
-	event["session_uuid"] = getUUID();
-	event["participant_name"] = participant->getName();
-	event["participant_uuid"] = participant->getUUID();
+	LLSD event(LLSDMap("type", event_type)("session_uuid", getUUID())("participant_name",participant->getName())("participant_uuid",participant->getUUID()));
 	LLEventPumps::instance().obtain("ConversationsEvents").post(event);
 }
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 36c39f5717..78bd90fb96 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -79,6 +79,8 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 
 LLIMFloaterContainer::~LLIMFloaterContainer()
 {
+	mStream.stopListening("ConversationsRefresh");
+
 	gIdleCallbacks.deleteFunction(idle, this);
 
 	mNewMessageConnection.disconnect();
-- 
cgit v1.2.3


From 8013e645603d1075b848ef91178af0fa3f9dc38c Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 4 Oct 2012 14:30:16 +0300
Subject: CHUI-313 FIXED "Conversations", "Conversations Log" menu items are
 added

---
 indra/newview/skins/default/xui/en/menu_viewer.xml | 25 ++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 88b30c8272..c805b6db42 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -218,8 +218,18 @@
      label="Communicate"
      name="Communicate"
      tear_off="true">
-        <menu_item_check
-         label="Chat..."
+       <menu_item_check
+         label="Conversations..."
+         name="Conversations">
+            <menu_item_check.on_check
+             function="Floater.IsOpen"
+             parameter="im_container" />
+            <menu_item_check.on_click
+             function="Floater.ToggleOrBringToFront"
+             parameter="im_container" />
+	</menu_item_check>
+	<menu_item_check
+         label="Nearby Chat..."
          name="Nearby Chat"
          shortcut="control|H"
          use_mac_ctrl="true">
@@ -243,6 +253,17 @@
              function="Agent.ToggleMicrophone"
              parameter="speak" />
         </menu_item_check>
+        <menu_item_check
+         label="Conversations Log..."
+         name="ConversationsLog">
+            <menu_item_check.on_check
+             function="Floater.Visible"
+             parameter="conversation" />
+            <menu_item_check.on_click
+             function="Floater.Toggle"
+             parameter="conversation" />
+        </menu_item_check>
+        <menu_item_separator/>
         <menu_item_check
          label="Voice morphing..."
          name="ShowVoice"
-- 
cgit v1.2.3


From 050146ce5ef889d254624ee456f04703fce357d3 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 4 Oct 2012 14:53:36 +0300
Subject: CHUI-327 FIXED Set "left" property for chat_history element

---
 indra/newview/skins/default/xui/en/floater_im_session.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 5c74f7f9bb..8cd0463de8 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -246,7 +246,7 @@
          parse_highlights="true"
          parse_urls="true"
        	 width="230"
-       	 left="0">
+       	 left="5">
         </chat_history>
             </layout_panel>
            </layout_stack>
-- 
cgit v1.2.3


From 06a7bd27cb07bd692d02604dcce735122456be6b Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 4 Oct 2012 17:13:10 +0300
Subject: CHUI-331 FIXED (Resizing conversation list when message panel is
 collapsed does not resize list)    *fixed missing parentheses from last push

---
 indra/llui/lllayoutstack.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index be6d359c9a..1f2496a8e7 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -767,7 +767,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 			{	// freeze new size as fraction
 				F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
 					? MAX_FRACTIONAL_SIZE
-					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim() - 1) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+					: llclamp(total_visible_fraction * (F32)(new_dim - (panelp->getRelevantMinDim() - 1)) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
 				fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
 				fraction_remaining -= panelp->mFractionalSize;
 				panelp->mFractionalSize = new_fractional_size;
-- 
cgit v1.2.3


From f533a251553d95045ab7c1d37a149004cd1e2ef0 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 4 Oct 2012 20:36:04 -0700
Subject: CHUI-381 : Implement add_participant and update_participant events
 handling.

---
 indra/newview/llconversationmodel.cpp  | 12 +++--
 indra/newview/llconversationmodel.h    |  2 +-
 indra/newview/llimfloatercontainer.cpp | 86 +++++++++++++---------------------
 indra/newview/llimfloatercontainer.h   |  2 +-
 4 files changed, 42 insertions(+), 60 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 3c111c919a..b2b768bf9a 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -66,9 +66,11 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 {
 }
 
-void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemParticipant* participant)
+void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
 {
-	LLSD event(LLSDMap("type", event_type)("session_uuid", getUUID())("participant_name",participant->getName())("participant_uuid",participant->getUUID()));
+	LLUUID session_id = (session ? session->getUUID() : LLUUID());
+	LLUUID participant_id = (participant ? participant->getUUID() : LLUUID());
+	LLSD event(LLSDMap("type", event_type)("session_uuid", session_id)("participant_uuid", participant_id));
 	LLEventPumps::instance().obtain("ConversationsEvents").post(event);
 }
 
@@ -138,14 +140,14 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
 	addChild(participant);
 	mIsLoaded = true;
 	mNeedsRefresh = true;
-	postEvent("add_participant", participant);
+	postEvent("add_participant", this, participant);
 }
 
 void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
 {
 	removeChild(participant);
 	mNeedsRefresh = true;
-	postEvent("remove_participant", participant);
+	postEvent("remove_participant", this, participant);
 }
 
 void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
@@ -338,11 +340,11 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
 	mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
 	mNeedsRefresh = true;
-	postEvent("update_participant", this);
 	if (mParent)
 	{
 		mParent->requestSort();
 	}
+	postEvent("update_participant", dynamic_cast<LLConversationItemSession*>(mParent), this);
 }
 
 void LLConversationItemParticipant::dumpDebugData()
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 7218cdf25a..d5f7e1a56b 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -126,7 +126,7 @@ public:
 	void resetRefresh() { mNeedsRefresh = false; }
 	bool needsRefresh() { return mNeedsRefresh; }
 	
-	void postEvent(const std::string& event_type, LLConversationItemParticipant* participant);
+	void postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant);
 	
     void buildParticipantMenuOptions(menuentry_vec_t&   items);
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 78bd90fb96..4022ebdf5b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -58,7 +58,7 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 :	LLMultiFloater(seed),
 	mExpandCollapseBtn(NULL),
 	mConversationsRoot(NULL),
-	mStream("ConversationsEvents"),
+	mConversationsEventStream("ConversationsEvents"),
 	mInitialized(false)
 {
     mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLIMFloaterContainer::isActionChecked, this, _2));
@@ -79,7 +79,7 @@ LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
 
 LLIMFloaterContainer::~LLIMFloaterContainer()
 {
-	mStream.stopListening("ConversationsRefresh");
+	mConversationsEventStream.stopListening("ConversationsRefresh");
 
 	gIdleCallbacks.deleteFunction(idle, this);
 
@@ -160,7 +160,7 @@ BOOL LLIMFloaterContainer::postBuild()
     mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
 	// Add listener to conversation model events
-	mStream.listen("ConversationsRefresh", boost::bind(&LLIMFloaterContainer::onConversationModelEvent, this, _1));
+	mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLIMFloaterContainer::onConversationModelEvent, this, _1));
 
 	// a scroller for folder view
 	LLRect scroller_view_rect = mConversationsListPanel->getRect();
@@ -419,22 +419,20 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	// For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp 
 	// (see LLInventoryPanel::buildNewViews()).
 
-	// Note: For the moment, we're not very smart about the event parameter and we just refresh the whole set of views/widgets
-	// according to the current state of the whole model.
-	// We should at least analyze the event payload and do things differently for a handful of cases:
-	// - add session or participant
-	// - remove session or participant
-	// - update session or participant (e.g. rename, change sort order, etc...)
-	// Please see LLConversationItem::postEvent() for the payload formatting.
-	// *TODO: Add handling for various event signatures (add, remove, update, resort)
-
 	std::string type = event.get("type").asString();
+	LLUUID session_id = event.get("session_uuid").asUUID();
+	LLUUID participant_id = event.get("participant_uuid").asUUID();
+
+	LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
+	if (!session_view)
+	{
+		// We skip events that are not associated to a session
+		return false;
+	}
+	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+
 	if (type == "remove_participant")
 	{
-		LLUUID session_id = event.get("session_uuid").asUUID();
-		LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
-		LLUUID participant_id = event.get("participant_uuid").asUUID();
-		LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
 		if (participant_view)
 		{
 			session_view->extractItem(participant_view);
@@ -443,52 +441,34 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 			mConversationsRoot->arrangeAll();
 		}
 	}
-	else 
-	{
-	// On each session in mConversationsItems
-	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	else if (type == "add_participant")
 	{
-		// Get the current session descriptors
-		LLConversationItem* session_model = it_session->second;
-		LLUUID session_id = it_session->first;
-		LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
-		// If the session model has been changed, refresh the corresponding view
-		if (session_model->needsRefresh())
+		if (!participant_view)
 		{
-			session_view->refresh();
-		}
-		// Iterate through each model participant child
-		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
-		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
-		while (current_participant_model != end_participant_model)
-		{
-			LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
-			LLUUID participant_id = participant_model->getUUID();
-			LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
-			// Is there a corresponding view? If not create it
-			if (!participant_view)
-			{
-				participant_view = createConversationViewParticipant(participant_model);
-				participant_view->addToFolder(session_view);
-				participant_view->setVisible(TRUE);
-			}
-			else
-				// Else, see if it needs refresh
+			LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
+			if (session_model)
 			{
-				if (participant_model->needsRefresh())
+				LLConversationItemParticipant* participant_model = session_model->findParticipant(participant_id);
+				if (participant_model)
 				{
-					participant_view->refresh();
+					participant_view = createConversationViewParticipant(participant_model);
+					participant_view->addToFolder(session_view);
+					participant_view->setVisible(TRUE);
 				}
 			}
-			// Reset the need for refresh
-			session_model->resetRefresh();
-			mConversationViewModel.requestSortAll();
-			mConversationsRoot->arrangeAll();
-			// Next participant
-			current_participant_model++;
+
 		}
 	}
+	else if (type == "update_participant")
+	{
+		if (participant_view)
+		{
+			participant_view->refresh();
+		}
 	}
+
+	mConversationViewModel.requestSortAll();
+	mConversationsRoot->arrangeAll();
 	
 	return false;
 }
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 832e67ae23..ceb054dfa3 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -149,7 +149,7 @@ private:
 	conversations_widgets_map mConversationsWidgets;
 	LLConversationViewModel mConversationViewModel;
 	LLFolderView* mConversationsRoot;
-	LLEventStream mStream; 
+	LLEventStream mConversationsEventStream; 
 };
 
 #endif // LL_LLIMFLOATERCONTAINER_H
-- 
cgit v1.2.3


From aeeeae2690c9ea612667ed46021e17cb083510e5 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 5 Oct 2012 12:51:31 -0700
Subject: CHUI-364 : Fixed. Do not render participants widgets when closing a
 conversation handle.

---
 indra/newview/llconversationview.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index d4eb551f7a..416e6da2da 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -181,10 +181,8 @@ void LLConversationViewSession::draw()
 	// draw highlight for selected items
 	drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
 
-	// draw children if root folder, or any other folder that is open or animating to closed state
-	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this)
-						 || isOpen()
-						 || mCurHeight != mTargetHeight;
+	// Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap.
+	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen();
 
 	for (folders_t::iterator iter = mFolders.begin();
 		iter != mFolders.end();)
-- 
cgit v1.2.3


From db452823e5cc615225f3f163d827954447cf9bd8 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 5 Oct 2012 20:28:11 -0700
Subject: CHUI-194 : WIP : Update the ad-hoc conversation line item title, add
 a new update_session event. Still some clean up to do.

---
 indra/newview/llavataractions.cpp      | 22 +++++++++++++++
 indra/newview/llavataractions.h        |  8 ++++++
 indra/newview/llconversationmodel.cpp  | 49 +++++++++++++++++++++++++++++++---
 indra/newview/llconversationmodel.h    |  1 +
 indra/newview/llimfloater.cpp          | 30 ++-------------------
 indra/newview/llimfloatercontainer.cpp |  9 +++++--
 6 files changed, 86 insertions(+), 33 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 248685b964..50697d1885 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -714,6 +714,28 @@ void LLAvatarActions::buildResidentsString(const std::vector<LLAvatarName> avata
 	}
 }
 
+// static
+void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string)
+{
+	std::vector<LLAvatarName> avatar_names;
+	uuid_vec_t::const_iterator it = avatar_uuids.begin();
+	for (; it != avatar_uuids.end(); ++it)
+	{
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(*it, &av_name))
+		{
+			avatar_names.push_back(av_name);
+		}
+	}
+	
+	// We should check whether the vector is not empty to pass the assertion
+	// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
+	if (!avatar_names.empty())
+	{
+		LLAvatarActions::buildResidentsString(avatar_names, residents_string);
+	}
+}
+
 //static
 std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
 {
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 6e60f624ad..e7cef587c2 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -218,6 +218,14 @@ public:
 	 */
 	static void buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string);
 
+	/**
+	 * Builds a string of residents' display names separated by "words_separator" string.
+	 *
+	 * @param avatar_uuids - a vector of given avatar uuids from which resulting string is built
+	 * @param residents_string - the resulting string
+	 */
+	static void buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string);
+
 	/**
 	 * Opens the chat history for avatar
 	 */
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index b2b768bf9a..15824704fd 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -27,6 +27,8 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llavatarnamecache.h"
+#include "llavataractions.h"
 #include "llevents.h"
 #include "llsdutil.h"
 #include "llconversationmodel.h"
@@ -140,9 +142,48 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
 	addChild(participant);
 	mIsLoaded = true;
 	mNeedsRefresh = true;
+	updateParticipantName(participant);
 	postEvent("add_participant", this, participant);
 }
 
+void LLConversationItemSession::updateParticipantName(LLConversationItemParticipant* participant)
+{
+	// We modify the session name only in the case of an ad-hoc session, exit otherwise (nothing to do)
+	if (getType() != CONV_SESSION_AD_HOC)
+	{
+		return;
+	}
+	// Avoid changing the default name if no participant present yet
+	if (mChildren.size() == 0)
+	{
+		return;
+	}
+	// Build a string containing the participants names and check if ready for display (we don't want "(waiting)" in there)
+	// *TODO: Further factor out common code with LLIMFloater::onParticipantsListChanged()
+	bool all_names_resolved = true;
+	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
+	child_list_t::iterator iter = mChildren.begin();
+	while (iter != mChildren.end())
+	{
+		LLConversationItemParticipant* current_participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+		temp_uuids.push_back(current_participant->getUUID());
+		LLAvatarName av_name;
+        if (!LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
+        {
+			all_names_resolved = false;
+			break;
+		}
+		iter++;
+	}
+	if (all_names_resolved)
+	{
+		std::string new_session_name;
+		LLAvatarActions::buildResidentsString(temp_uuids, new_session_name);
+		renameItem(new_session_name);
+		postEvent("update_session", this, NULL);
+	}
+}
+
 void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
 {
 	removeChild(participant);
@@ -340,11 +381,13 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
 	mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
 	mNeedsRefresh = true;
-	if (mParent)
+	LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+	if (parent_session)
 	{
-		mParent->requestSort();
+		parent_session->requestSort();
+		parent_session->updateParticipantName(this);
 	}
-	postEvent("update_participant", dynamic_cast<LLConversationItemSession*>(mParent), this);
+	postEvent("update_participant", parent_session, this);
 }
 
 void LLConversationItemParticipant::dumpDebugData()
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index d5f7e1a56b..1d082852f5 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -149,6 +149,7 @@ public:
     LLPointer<LLUIImage> getIcon() const { return NULL; }
 	void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; }
 	void addParticipant(LLConversationItemParticipant* participant);
+	void updateParticipantName(LLConversationItemParticipant* participant);
 	void removeParticipant(LLConversationItemParticipant* participant);
 	void removeParticipant(const LLUUID& participant_id);
 	void clearParticipants();
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 99337bd5f3..467f48600a 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -60,10 +60,6 @@
 #include "llnotificationmanager.h"
 #include "llautoreplace.h"
 
-/// Helper function to resolve resident names from given uuids
-/// and form a string of names separated by "words_separator".
-static void build_names_string(const uuid_vec_t& uuids, std::string& names_string);
-
 floater_showed_signal_t LLIMFloater::sIMFloaterShowedSignal;
 
 LLIMFloater::LLIMFloater(const LLUUID& session_id)
@@ -476,7 +472,7 @@ void LLIMFloater::addP2PSessionParticipants(const LLSD& notification, const LLSD
 void LLIMFloater::sendParticipantsAddedNotification(const uuid_vec_t& uuids)
 {
 	std::string names_string;
-	build_names_string(uuids, names_string);
+	LLAvatarActions::buildResidentsString(uuids, names_string);
 	LLStringUtil::format_map_t args;
 	args["[NAME]"] = names_string;
 
@@ -581,7 +577,7 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 	if (all_names_resolved)
 	{
 		std::string ui_title;
-		build_names_string(temp_uuids, ui_title);
+		LLAvatarActions::buildResidentsString(temp_uuids, ui_title);
 		updateSessionName(ui_title, ui_title);
 	}
 }
@@ -1334,25 +1330,3 @@ boost::signals2::connection LLIMFloater::setIMFloaterShowedCallback(const floate
 {
 	return LLIMFloater::sIMFloaterShowedSignal.connect(cb);
 }
-
-// static
-void build_names_string(const uuid_vec_t& uuids, std::string& names_string)
-{
-	std::vector<LLAvatarName> avatar_names;
-	uuid_vec_t::const_iterator it = uuids.begin();
-	for (; it != uuids.end(); ++it)
-	{
-		LLAvatarName av_name;
-		if (LLAvatarNameCache::get(*it, &av_name))
-		{
-			avatar_names.push_back(av_name);
-		}
-	}
-
-	// We should check whether the vector is not empty to pass the assertion
-	// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
-	if (!avatar_names.empty())
-	{
-		LLAvatarActions::buildResidentsString(avatar_names, names_string);
-	}
-}
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4022ebdf5b..7c5aaa7d0f 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -466,7 +466,11 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 			participant_view->refresh();
 		}
 	}
-
+	else if (type == "update_session")
+	{
+		session_view->refresh();
+	}
+	
 	mConversationViewModel.requestSortAll();
 	mConversationsRoot->arrangeAll();
 	
@@ -1111,7 +1115,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	removeConversationListItem(uuid,false);
 
 	// Create a conversation session model
-	LLConversationItem* item = NULL;
+	LLConversationItemSession* item = NULL;
 	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
 	if (speaker_manager)
 	{
@@ -1123,6 +1127,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 		return;
 	}
 	item->renameItem(display_name);
+	item->updateParticipantName(NULL);
 	
 	mConversationsItems[uuid] = item;
 
-- 
cgit v1.2.3


From 698cfc2811a6ce976a153a1a0d87d31c56dd52ec Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 8 Oct 2012 15:19:00 +0300
Subject: CHUI-390 FIXED Selecting Chat History option from right click menu on
 a conversation name does not open chat history viewer

---
 indra/newview/llimfloatercontainer.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 7c5aaa7d0f..94e7f1000b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -888,7 +888,13 @@ void LLIMFloaterContainer::doToSelectedConversation(const std::string& command,
         }
         else if("chat_history" == command)
         {
-            LLAvatarActions::viewChatHistory(conversationItem->getUUID());
+			const LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(conversationItem->getUUID());
+
+			if (NULL != session)
+			{
+				const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
+				LLFloaterReg::showInstance("preview_conversation", session_id, true);
+			}
         }
         else
         {
-- 
cgit v1.2.3


From 93e36340ec895a44d0b0bc73157fe23279883863 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 8 Oct 2012 22:20:58 +0300
Subject: CHUI-331 (Resizing conversation list when message panel is collapsed
 does not resize list)     fixed

---
 indra/newview/llimfloatercontainer.cpp | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 94e7f1000b..5f111b39d4 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -553,12 +553,25 @@ void LLIMFloaterContainer::collapseMessagesPane(bool collapse)
 		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
 	}
 
+	// Save left pane rectangle before collapsing/expanding right pane.
+	LLRect prevRect = mConversationsPane->getRect();
+
 	// Show/hide the messages pane.
 	mConversationsStack->collapsePanel(mMessagesPane, collapse);
 
+	if (!collapse)
+	{
+		// Make sure layout is updated before resizing conversation pane.
+		mConversationsStack->updateLayout();
+	}
+
 	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+	if (!collapse)
+	{
+		// Restore conversation's pane previous width after expanding messages pane.
+		mConversationsPane->setTargetDim(prevRect.getWidth());
+	}
 }
-
 void LLIMFloaterContainer::collapseConversationsPane(bool collapse)
 {
 	if (mConversationsPane->isCollapsed() == collapse)
-- 
cgit v1.2.3


From 0d619bcdc1fbb7869a6376749b0bd46b1d40c91e Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 8 Oct 2012 18:20:37 -0700
Subject: CHUI-147 : Sort the residents names when getting a resident string
 list

---
 indra/newview/llavataractions.cpp     | 8 ++++----
 indra/newview/llavataractions.h       | 2 +-
 indra/newview/llconversationmodel.cpp | 4 +++-
 3 files changed, 8 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 50697d1885..3326103d03 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -697,15 +697,15 @@ namespace action_give_inventory
 }
 
 // static
-void LLAvatarActions::buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string)
+void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string)
 {
 	llassert(avatar_names.size() > 0);
-
+	
+	std::sort(avatar_names.begin(), avatar_names.end());
 	const std::string& separator = LLTrans::getString("words_separator");
 	for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
 	{
-		LLAvatarName av_name = *it;
-		residents_string.append(av_name.mDisplayName);
+		residents_string.append((*it).mDisplayName);
 		if	(++it == avatar_names.end())
 		{
 			break;
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index e7cef587c2..6e1198cd09 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -216,7 +216,7 @@ public:
 	 * @param avatar_names - a vector of given avatar names from which resulting string is built
 	 * @param residents_string - the resulting string
 	 */
-	static void buildResidentsString(const std::vector<LLAvatarName> avatar_names, std::string& residents_string);
+	static void buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string);
 
 	/**
 	 * Builds a string of residents' display names separated by "words_separator" string.
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 15824704fd..29e7ac4e12 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -159,7 +159,6 @@ void LLConversationItemSession::updateParticipantName(LLConversationItemParticip
 		return;
 	}
 	// Build a string containing the participants names and check if ready for display (we don't want "(waiting)" in there)
-	// *TODO: Further factor out common code with LLIMFloater::onParticipantsListChanged()
 	bool all_names_resolved = true;
 	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
 	child_list_t::iterator iter = mChildren.begin();
@@ -170,6 +169,9 @@ void LLConversationItemSession::updateParticipantName(LLConversationItemParticip
 		LLAvatarName av_name;
         if (!LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
         {
+			// If the name is not in the cache yet, bail out
+			// Note: we don't bind ourselves to the LLAvatarNameCache event as we are called by
+			// onAvatarNameCache() which is itself attached to the same event.
 			all_names_resolved = false;
 			break;
 		}
-- 
cgit v1.2.3


From 1db55ab6da9f6fcc9f51d4c09ed5fa2b88afd7c4 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 9 Oct 2012 12:07:35 -0700
Subject: CHUI-393 : Suppress the sort participants by distance from you menu
 item. Kept the code around.

---
 indra/newview/skins/default/xui/en/menu_participant_view.xml | 11 -----------
 1 file changed, 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index 0043c14479..6fa0707eea 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -59,17 +59,6 @@
          function="IMFloaterContainer.Check"
          parameter="sort_participants_by_recent" />
     </menu_item_check>
-    <menu_item_check
-     label="Sort participants by distance from you"
-     layout="topleft"
-     name="sort_participants_by_distance">
-        <on_click
-         function="IMFloaterContainer.Action"
-         parameter="sort_participants_by_distance" />
-        <on_check
-         function="IMFloaterContainer.Check"
-         parameter="sort_participants_by_distance" />
-    </menu_item_check>
     <menu_item_separator
      layout="topleft" />
     <menu_item_call
-- 
cgit v1.2.3


From ad371c2cfd9d39a4d615cb709b8f85fada0154c6 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 9 Oct 2012 20:31:15 -0700
Subject: CHUI-375 : Fixed default parameters changed in methods profile but
 not in binding calls.

---
 indra/llui/llui.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 41a948e545..f43409a1ff 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1629,10 +1629,10 @@ void LLUI::initClass(const settings_map_t& settings,
 	LLUICtrl::CommitCallbackRegistry::Registrar& reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar();
 
 	// Callbacks for associating controls with floater visibility:
-	reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD()));
-	reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD()));
-	reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(), FALSE));
-	reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD()));
+	reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD(LLUUID())));
+	reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD(LLUUID())));
+	reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(LLUUID()), FALSE));
+	reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD(LLUUID())));
 	
 	// Button initialization callback for toggle buttons
 	reg.add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
@@ -1647,8 +1647,8 @@ void LLUI::initClass(const settings_map_t& settings,
 	reg.add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
 	
 	// Used by menus along with Floater.Toggle to display visibility as a check-mark
-	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD()));
-	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.IsOpen", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD()));
+	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD(LLUUID())));
+	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.IsOpen", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD(LLUUID())));
 
 	// Parse the master list of commands
 	LLCommandManager::load();
-- 
cgit v1.2.3


From 8b4423d428a0a209711eb18cc003d9ca4970e17a Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Wed, 10 Oct 2012 20:04:56 +0300
Subject: CHUI-377 (Icons in message panel out of position when nearby chat
 conversation selected)         FIXED

---
 indra/newview/llimconversation.cpp | 33 ++++++++++++++++++++++-----------
 indra/newview/llimconversation.h   |  2 ++
 2 files changed, 24 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 2ad7f9b193..3b334df189 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -393,7 +393,7 @@ void LLIMConversation::updateHeaderAndToolbar()
 	// prevent start conversation before its container
     LLIMFloaterContainer::getInstance();
 
-	bool is_torn_off = !getHost();
+	bool is_torn_off = checkIfTornOff();
 	if (!is_torn_off)
 	{
 		hideAllStandardButtons();
@@ -505,16 +505,7 @@ void LLIMConversation::onSlide(LLIMConversation* self)
 /*virtual*/
 void LLIMConversation::onOpen(const LLSD& key)
 {
-	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
-    bool is_hosted = !!host_floater;
-	if (is_hosted)
-	{
-		// Show the messages pane when opening a floater hosted in the Conversations
-		host_floater->collapseMessagesPane(false);
-	}
-
-	setTornOff(!is_hosted);
-	updateHeaderAndToolbar();
+	checkIfTornOff();
 }
 
 // virtual
@@ -546,3 +537,23 @@ bool LLIMConversation::isChatMultiTab()
 	// Restart is required in order to change chat window type.
 	return true;
 }
+
+bool LLIMConversation::checkIfTornOff()
+{
+	bool isTorn = !getHost();
+	if (!isTorn)
+	{
+		LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
+
+		// Show the messages pane when opening a floater hosted in the Conversations
+		host_floater->collapseMessagesPane(false);
+	}
+	
+	if (isTorn != isTornOff())
+	{
+		setTornOff(isTorn);
+		updateHeaderAndToolbar();
+	}
+
+	return isTorn;
+}
\ No newline at end of file
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index c54081d316..0960d6db88 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -138,6 +138,8 @@ private:
 	 */
 	void reshapeChatHistory();
 
+	bool checkIfTornOff();
+
 	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
 
 	bool mHadFocus;
-- 
cgit v1.2.3


From 82e5649fba22f7fa0cb4744f632aa836f0855f85 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 11 Oct 2012 14:06:35 +0300
Subject: CHUI-377 (Icons in message panel out of position when nearby chat
 conversation selected)         Fixed bug with collapsing messages pane

---
 indra/newview/llimconversation.cpp | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 3b334df189..9f3c6d0f3d 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -505,7 +505,12 @@ void LLIMConversation::onSlide(LLIMConversation* self)
 /*virtual*/
 void LLIMConversation::onOpen(const LLSD& key)
 {
-	checkIfTornOff();
+	if (!checkIfTornOff())
+	{
+		LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
+		// Show the messages pane when opening a floater hosted in the Conversations
+		host_floater->collapseMessagesPane(false);
+	}
 }
 
 // virtual
@@ -541,13 +546,6 @@ bool LLIMConversation::isChatMultiTab()
 bool LLIMConversation::checkIfTornOff()
 {
 	bool isTorn = !getHost();
-	if (!isTorn)
-	{
-		LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
-
-		// Show the messages pane when opening a floater hosted in the Conversations
-		host_floater->collapseMessagesPane(false);
-	}
 	
 	if (isTorn != isTornOff())
 	{
@@ -556,4 +554,4 @@ bool LLIMConversation::checkIfTornOff()
 	}
 
 	return isTorn;
-}
\ No newline at end of file
+}
-- 
cgit v1.2.3


From 0ff5a0c8ceebfab0d786aaf027c7c548170afe8d Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 11 Oct 2012 19:58:26 +0300
Subject: CHUI-356 FIXED Call notifyObserverSessionIDUpdated() only after
 initing IM floater with new session id

---
 indra/newview/llimview.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b45903835a..a604c884ca 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -643,6 +643,12 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
 	{
 		session->sessionInitReplyReceived(new_session_id);
 
+		LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
+		if (im_floater)
+		{
+			im_floater->sessionInitReplyReceived(new_session_id);
+		}
+
 		if (old_session_id != new_session_id)
 		{
 			mId2SessionMap.erase(old_session_id);
@@ -651,12 +657,6 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
 			gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
 		}
 
-		LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
-		if (im_floater)
-		{
-			im_floater->sessionInitReplyReceived(new_session_id);
-		}
-
 		// auto-start the call on session initialization?
 		if (session->mStartCallOnInitialize)
 		{
-- 
cgit v1.2.3


From 8aa424128ad06567f4c32c6672dc63d9b2111efa Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 11 Oct 2012 10:38:34 -0700
Subject: CHUI-380: Before code review changes. Now the user selects a
 conversation or participant of a conversation the correct chat floater will
 appear. Focus will be redirected to the chat input text box automatically
 allowing the user to type into the input text box.

---
 indra/newview/llconversationview.cpp | 28 ++++++++++++++++++++++++---
 indra/newview/llconversationview.h   |  1 +
 indra/newview/llimfloater.cpp        | 37 +++++++++++++++++++++---------------
 indra/newview/llimfloater.h          |  1 +
 indra/newview/llnearbychat.cpp       | 20 +++++++++++++++++++
 indra/newview/llnearbychat.h         |  2 +-
 6 files changed, 70 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index d4eb551f7a..112c38d8b8 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -32,6 +32,8 @@
 #include <boost/bind.hpp>
 #include "llagentdata.h"
 #include "llconversationmodel.h"
+#include "llimfloater.h"
+#include "llnearbychat.h"
 #include "llimconversation.h"
 #include "llimfloatercontainer.h"
 #include "llfloaterreg.h"
@@ -407,21 +409,41 @@ void LLConversationViewParticipant::draw()
     static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 
     const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
-    const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
 
     const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
     F32 right_x  = 0;
 
     F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad;
     F32 text_left = (F32)getLabelXPos();
-    LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
+    LLColor4 color = mIsSelected ? sHighlightFgColor : sFgColor;
 
-    drawHighlight(show_context, filled, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+    drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
     drawLabel(font, text_left, y, color, right_x);
 
     LLView::draw();
 }
 
+void LLConversationViewParticipant::selectItem()
+{
+    LLConversationItem* vmi = this->getParentFolder() ? static_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
+    
+    if(vmi)
+    {
+        //When null, show the nearby chat conversation floater
+        if(vmi->getUUID().isNull())
+        {
+            LLNearbyChat* nearbyChat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
+            nearbyChat->show();
+        }
+        //Otherwise, show the IM conversation floater
+        else
+        {
+            LLIMFloater::show(vmi->getUUID());
+        }
+    }
+
+    LLFolderViewItem::selectItem();
+}
 
 void LLConversationViewParticipant::refresh()
 {
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index c81c70b456..bd95387bbe 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -113,6 +113,7 @@ public:
 	};
 	
     virtual ~LLConversationViewParticipant( void ) { }
+    void selectItem();	
     bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
     virtual void refresh();
     void addToFolder(LLFolderViewFolder* folder);
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 99337bd5f3..990b9c45f9 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -719,6 +719,27 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 	}
 }
 
+void LLIMFloater::setFocus(BOOL focusFlag)
+{
+    LLTransientDockableFloater::setFocus(focusFlag);
+
+    BOOL is_minimized = focusFlag && isChatMultiTab()
+        ? LLIMFloaterContainer::getInstance()->isMinimized()
+        : !focusFlag;
+
+    //Redirect focus to input editor
+    if (!is_minimized && mChatHistory && mInputEditor)
+    {
+        //only if floater was construced and initialized from xml
+        updateMessages();
+        //prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781)
+        if (!isChatMultiTab() || hasFocus())
+        {
+            mInputEditor->setFocus(TRUE);
+        }
+    }
+}
+
 void LLIMFloater::setVisible(BOOL visible)
 {
 	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
@@ -734,21 +755,6 @@ void LLIMFloater::setVisible(BOOL visible)
 		channel->redrawToasts();
 	}
 
-	BOOL is_minimized = visible && isChatMultiTab()
-		? LLIMFloaterContainer::getInstance()->isMinimized()
-		: !visible;
-
-	if (!is_minimized && mChatHistory && mInputEditor)
-	{
-		//only if floater was construced and initialized from xml
-		updateMessages();
-		//prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781)
-		if (!isChatMultiTab() || hasFocus())
-		{
-			mInputEditor->setFocus(TRUE);
-		}
-	}
-
 	if(!visible)
 	{
 		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
@@ -761,6 +767,7 @@ void LLIMFloater::setVisible(BOOL visible)
 	if (visible && isInVisibleChain())
 	{
 		sIMFloaterShowedSignal(mSessionID);
+        setFocus(TRUE);
 	}
 }
 
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 5ed1d1ab35..26daf00afd 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -65,6 +65,7 @@ public:
 
 	// LLView overrides
 	/*virtual*/ BOOL postBuild();
+    /*virtual*/ void setFocus(BOOL focusFlag);
 	/*virtual*/ void setVisible(BOOL visible);
 	/*virtual*/ BOOL getVisible();
 	// Check typing timeout timer.
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index b96b486868..e0778afd86 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -271,11 +271,31 @@ void LLNearbyChat::removeScreenChat()
 	}
 }
 
+void LLNearbyChat::setFocus(BOOL focusFlag)
+{
+    LLTransientDockableFloater::setFocus(focusFlag);
+
+    BOOL is_minimized = focusFlag && isChatMultiTab()
+        ? LLIMFloaterContainer::getInstance()->isMinimized()
+        : !focusFlag;
+
+    //Redirect focus to input editor
+    if (!is_minimized && mChatHistory && mInputEditor)
+    {
+        //prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781)
+        if (!isChatMultiTab() || hasFocus())
+        {
+            mInputEditor->setFocus(TRUE);
+        }
+    }
+}
+
 void	LLNearbyChat::setVisible(BOOL visible)
 {
 	if(visible)
 	{
 		removeScreenChat();
+        setFocus(TRUE);
 	}
 
 	LLIMConversation::setVisible(visible);
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 93168ba96a..7ada4daea8 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -52,7 +52,7 @@ public:
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
-
+    /*virtual*/ void setFocus(BOOL focusFlag);
 	/*virtual*/ void	setVisible(BOOL visible);
 
 	void loadHistory();
-- 
cgit v1.2.3


From 375f380ea388b37c34ace9570822d0c117b3d2f1 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 11 Oct 2012 12:17:46 -0700
Subject: CHUI-380: Code cleanup after code review.

---
 indra/newview/llimfloater.cpp  | 13 ++-----------
 indra/newview/llnearbychat.cpp | 12 ++----------
 2 files changed, 4 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 990b9c45f9..a1ed1e0b01 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -723,20 +723,11 @@ void LLIMFloater::setFocus(BOOL focusFlag)
 {
     LLTransientDockableFloater::setFocus(focusFlag);
 
-    BOOL is_minimized = focusFlag && isChatMultiTab()
-        ? LLIMFloaterContainer::getInstance()->isMinimized()
-        : !focusFlag;
-
     //Redirect focus to input editor
-    if (!is_minimized && mChatHistory && mInputEditor)
+    if (focusFlag)
     {
-        //only if floater was construced and initialized from xml
         updateMessages();
-        //prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781)
-        if (!isChatMultiTab() || hasFocus())
-        {
-            mInputEditor->setFocus(TRUE);
-        }
+        mInputEditor->setFocus(TRUE);
     }
 }
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index e0778afd86..a0ddc9b52b 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -275,18 +275,10 @@ void LLNearbyChat::setFocus(BOOL focusFlag)
 {
     LLTransientDockableFloater::setFocus(focusFlag);
 
-    BOOL is_minimized = focusFlag && isChatMultiTab()
-        ? LLIMFloaterContainer::getInstance()->isMinimized()
-        : !focusFlag;
-
     //Redirect focus to input editor
-    if (!is_minimized && mChatHistory && mInputEditor)
+    if (focusFlag)
     {
-        //prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781)
-        if (!isChatMultiTab() || hasFocus())
-        {
-            mInputEditor->setFocus(TRUE);
-        }
+        mInputEditor->setFocus(TRUE);
     }
 }
 
-- 
cgit v1.2.3


From f4b10aaebbaf8eb66d41ffa703f6ed7b909ba7e7 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 11 Oct 2012 17:48:39 -0700
Subject: CHUI-380: Fixing a bug that occurred when right clicking nearby chat
 and then right clicking a participant under a conversation. This would result
 in both the participant and conversation to be highlighted. Still a work in
 progress. This change involves introducing an old bug CHUI 289 and finding a
 different approach to solving it.

---
 indra/newview/llconversationview.cpp |  2 +-
 indra/newview/llimconversation.cpp   |  4 ++--
 indra/newview/llimfloater.cpp        |  5 ++++-
 indra/newview/llnearbychat.cpp       | 15 ++++++++-------
 4 files changed, 15 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index f9a3a05e59..70f2446752 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -415,7 +415,7 @@ void LLConversationViewParticipant::draw()
     F32 text_left = (F32)getLabelXPos();
     LLColor4 color = mIsSelected ? sHighlightFgColor : sFgColor;
 
-    drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+    drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
     drawLabel(font, text_left, y, color, right_x);
 
     LLView::draw();
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 9f3c6d0f3d..2027f79eea 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -222,8 +222,8 @@ void LLIMConversation::onFocusReceived()
 
 	if (! mHadFocus)
 	{
-	    LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
-	    container->setConvItemSelect(mSessionID);
+	//    LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
+	//    container->setConvItemSelect(mSessionID);
 	}
 }
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index a8add9c6ab..e4032738a7 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -725,6 +725,7 @@ void LLIMFloater::setFocus(BOOL focusFlag)
         updateMessages();
         mInputEditor->setFocus(TRUE);
     }
+    
 }
 
 void LLIMFloater::setVisible(BOOL visible)
@@ -754,8 +755,10 @@ void LLIMFloater::setVisible(BOOL visible)
 	if (visible && isInVisibleChain())
 	{
 		sIMFloaterShowedSignal(mSessionID);
-        setFocus(TRUE);
+        
 	}
+
+    setFocus(visible);
 }
 
 BOOL LLIMFloater::getVisible()
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a0ddc9b52b..a89ae4a2dc 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -274,23 +274,24 @@ void LLNearbyChat::removeScreenChat()
 void LLNearbyChat::setFocus(BOOL focusFlag)
 {
     LLTransientDockableFloater::setFocus(focusFlag);
-
+    
     //Redirect focus to input editor
     if (focusFlag)
     {
         mInputEditor->setFocus(TRUE);
     }
+    
 }
 
 void	LLNearbyChat::setVisible(BOOL visible)
 {
-	if(visible)
-	{
-		removeScreenChat();
-        setFocus(TRUE);
-	}
-
 	LLIMConversation::setVisible(visible);
+
+    if(visible)
+    {
+        removeScreenChat();
+    }
+    setFocus(visible);
 }
 
 
-- 
cgit v1.2.3


From 9aa03f0bf284bbfa3f50883351c6e39f7ffa41c5 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Fri, 12 Oct 2012 14:29:44 +0300
Subject: CHUI-402 (Double-click on conversation participant should begin IM
 session)

---
 indra/newview/llimfloatercontainer.cpp | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 5f111b39d4..0f44d42780 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -142,6 +142,9 @@ BOOL LLIMFloaterContainer::postBuild()
 	
 	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
 
+	// Open IM session with selected participant on double click event
+	mConversationsListPanel->setDoubleClickCallback(boost::bind(&LLIMFloaterContainer::doToSelected, this, LLSD("im")));
+
 	// Create the root model and view for all conversation sessions
 	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
 
-- 
cgit v1.2.3


From 19c5b35a86dbe641fe397baf9a8194d78e440af8 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Fri, 12 Oct 2012 20:10:13 +0300
Subject: CHUI-385 FIXED All user's do not receive ad hoc messages after adding
 a user to a conversation

---
 indra/newview/llimfloatercontainer.cpp | 15 ++++++++++-----
 indra/newview/llimfloatercontainer.h   |  4 ++--
 indra/newview/llimview.cpp             |  9 ++++++---
 3 files changed, 18 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 0f44d42780..2248699e5e 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -109,8 +109,7 @@ void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 
 void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
 {
-	removeConversationListItem(old_session_id);
-	addConversationListItem(new_session_id);
+	addConversationListItem(new_session_id, removeConversationListItem(old_session_id));
 }
 
 void LLIMFloaterContainer::sessionRemoved(const LLUUID& session_id)
@@ -1118,7 +1117,7 @@ void LLIMFloaterContainer::setNearbyDistances()
 	}
 }
 
-void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
+void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
 {
 	bool is_nearby_chat = uuid.isNull();
 	
@@ -1173,7 +1172,10 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 		current_participant_model++;
 	}
 
-	setConvItemSelect(uuid);
+	if (isWidgetSelected)
+	{
+		setConvItemSelect(uuid);
+	}
 	
 	// set the widget to minimized mode if conversations pane is collapsed
 	widget->toggleMinimizedMode(mConversationsPane->isCollapsed());
@@ -1181,17 +1183,19 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid)
 	return;
 }
 
-void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
+bool LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
 {
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
+	bool isWidgetSelected = false;
 	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(uuid);
 	if (widget_it != mConversationsWidgets.end())
 	{
 		LLFolderViewItem* widget = widget_it->second;
 		if (widget)
 		{
+			isWidgetSelected = widget->isSelected();
 			widget->destroyView();
 		}
 	}
@@ -1211,6 +1215,7 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 			widget->selectItem();
 		}
 	}
+	return isWidgetSelected;
 }
 
 LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index ceb054dfa3..5c11577154 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -133,8 +133,8 @@ private:
 
 	// Conversation list implementation
 public:
-	void removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
-	void addConversationListItem(const LLUUID& uuid);
+	bool removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
+	void addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
 	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
 	void setNearbyDistances();
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a604c884ca..aa5b9ce006 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -643,6 +643,12 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
 	{
 		session->sessionInitReplyReceived(new_session_id);
 
+		if (old_session_id != new_session_id)
+		{
+			mId2SessionMap.erase(old_session_id);
+			mId2SessionMap[new_session_id] = session;
+		}
+
 		LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
 		if (im_floater)
 		{
@@ -651,9 +657,6 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
 
 		if (old_session_id != new_session_id)
 		{
-			mId2SessionMap.erase(old_session_id);
-			mId2SessionMap[new_session_id] = session;
-
 			gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
 		}
 
-- 
cgit v1.2.3


From 48c7e2cee70996048b0974c6cdda67cdea11a32c Mon Sep 17 00:00:00 2001
From: "Jeff (Gioffredo Linden)" <gioffredo@lindenlab.com>
Date: Fri, 12 Oct 2012 18:14:57 -0400
Subject: Expose Chat history to VITA by adding getValue method to
 llchathistory object

---
 indra/newview/llchathistory.cpp | 8 ++++++++
 indra/newview/llchathistory.h   | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 3636f9e9d2..deb658c489 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -596,6 +596,14 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
 	mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
 }
 
+LLSD LLChatHistory::getValue()
+{
+  LLSD* text=new LLSD(); 
+  text->assign(mEditor->getText());
+  return *text;
+    
+}
+
 LLChatHistory::~LLChatHistory()
 {
 	this->clear();
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index 990c52f31b..fa88483fcd 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -103,7 +103,7 @@ class LLChatHistory : public LLUICtrl
 
 	public:
 		~LLChatHistory();
-
+		LLSD getVlue();   
 		void initFromParams(const Params&);
 
 		/**
-- 
cgit v1.2.3


From 5f4fbffc82ae755235ead5e1b5883cc909e77e77 Mon Sep 17 00:00:00 2001
From: "Jeff (Gioffredo Linden)" <gioffredo@lindenlab.com>
Date: Fri, 12 Oct 2012 20:30:06 -0400
Subject: Fix typo

---
 indra/newview/llchathistory.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index fa88483fcd..effdd75911 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -103,7 +103,7 @@ class LLChatHistory : public LLUICtrl
 
 	public:
 		~LLChatHistory();
-		LLSD getVlue();   
+		LLSD getValue();   
 		void initFromParams(const Params&);
 
 		/**
-- 
cgit v1.2.3


From d7d0416547958792517a9b739b370e51c717fb23 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 12 Oct 2012 20:15:57 -0700
Subject: CHUI-380: (In progress) Refactoring needed to fix focusing issues
 when selecting an existing conversation item. This commit resolves
 re-introducing bug CHUI-289. Will code review and cleanup code in next
 commit.

---
 indra/llkdu/llimagej2ckdu.cpp          |  4 ++--
 indra/newview/llchiclet.h              |  1 +
 indra/newview/llchicletbar.h           |  1 +
 indra/newview/llconversationlog.h      |  1 +
 indra/newview/llconversationview.cpp   |  6 ++++--
 indra/newview/llimconversation.cpp     | 11 -----------
 indra/newview/llimconversation.h       |  3 ---
 indra/newview/llimfloatercontainer.cpp | 19 +++++++++++++++++++
 indra/newview/llimfloatercontainer.h   |  3 +++
 indra/newview/llimview.cpp             | 13 +++++++++++++
 indra/newview/llimview.h               |  2 ++
 indra/newview/llsyswellwindow.h        |  1 +
 12 files changed, 47 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index cf88de12b4..db75b6e003 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -166,12 +166,12 @@ void LLKDUMessageWarning::put_text(const kdu_uint16 *s)
 
 void LLKDUMessageError::put_text(const char *s)
 {
-	llinfos << "KDU Error: " << s << llendl;
+	//llinfos << "KDU Error: " << s << llendl;
 }
 
 void LLKDUMessageError::put_text(const kdu_uint16 *s)
 {
-	llinfos << "KDU Error: " << s << llendl;
+	//llinfos << "KDU Error: " << s << llendl;
 }
 
 void LLKDUMessageError::flush(bool end_of_message)
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index f51d7b622c..3a52b0a67b 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -874,6 +874,7 @@ class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
 	friend class LLUICtrlFactory;
 public:
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
+    /*virtual*/ void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h
index 7d0d904810..0589a9fccc 100644
--- a/indra/newview/llchicletbar.h
+++ b/indra/newview/llchicletbar.h
@@ -51,6 +51,7 @@ public:
 
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+    /*virtual*/ void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 373406aa6f..70f04b21c8 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -124,6 +124,7 @@ public:
 
 	// LLIMSessionObserver triggers
 	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+    virtual void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; // Stub
 	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
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 70f2446752..637f30635e 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -424,8 +424,10 @@ void LLConversationViewParticipant::draw()
 void LLConversationViewParticipant::selectItem()
 {
     LLConversationItem* vmi = this->getParentFolder() ? static_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
-    
-    if(vmi)
+    LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
+
+    //Only execute when switching floaters (conversations)
+    if(vmi && vmi->getUUID() != container->getSelectedSession())
     {
         //When null, show the nearby chat conversation floater
         if(vmi->getUUID().isNull())
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 2027f79eea..bd2a2419a8 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -54,7 +54,6 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
   , mRefreshTimer(new LLTimer())
-  , mHasFocus(false)
 {
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
@@ -216,21 +215,11 @@ void LLIMConversation::onFocusReceived()
 	}
 
 	LLTransientDockableFloater::onFocusReceived();
-
-    mHadFocus = mHasFocus;
-    mHasFocus = true;
-
-	if (! mHadFocus)
-	{
-	//    LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
-	//    container->setConvItemSelect(mSessionID);
-	}
 }
 
 void LLIMConversation::onFocusLost()
 {
 	setBackgroundOpaque(false);
-	mHasFocus = false;
 	LLTransientDockableFloater::onFocusLost();
 }
 
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 0960d6db88..603e0d0197 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -141,9 +141,6 @@ private:
 	bool checkIfTornOff();
 
 	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
-
-	bool mHadFocus;
-	bool mHasFocus;
 };
 
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 5f111b39d4..0250854f36 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -101,6 +101,11 @@ void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::str
 	addConversationListItem(session_id);
 }
 
+void LLIMFloaterContainer::sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+    doSomething(session_id);
+}
+
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
 	LLIMFloater::addToHost(session_id, true);
@@ -1069,6 +1074,19 @@ void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
 	}
 }
 
+void LLIMFloaterContainer::doSomething(const LLUUID& session_id)
+{
+    LLConversationItem* vmi = static_cast<LLConversationItem*>(mConversationsRoot->getCurSelectedItem()->getParentFolder()->getViewModelItem());
+
+    if(session_id != vmi->getUUID())
+    {
+        mSelectedSession = session_id;
+        LLFolderViewItem* widget = mConversationsWidgets[session_id];
+        (widget->getRoot())->setSelection(widget, FALSE, FALSE);
+    }
+}
+
+
 void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
 {
 	conversations_items_map::iterator item_it = mConversationsItems.find(session_id);
@@ -1204,6 +1222,7 @@ void LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 		conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
 		if (widget_it != mConversationsWidgets.end())
 		{
+            mSelectedSession = widget_it->first;
 			LLFolderViewItem* widget = widget_it->second;
 			widget->selectItem();
 		}
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index ceb054dfa3..da134c498f 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -64,6 +64,7 @@ public:
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
     void setConvItemSelect(const LLUUID& session_id);
+    void doSomething(const LLUUID& session_id);
 	/*virtual*/ void tabClose();
 
 	static LLFloater* getCurrentVoiceFloater();
@@ -81,11 +82,13 @@ public:
 
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+    /*virtual*/ void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
 
 	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
+    LLUUID getSelectedSession() { return mSelectedSession; }
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a604c884ca..e75db1b7af 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2654,6 +2654,11 @@ LLUUID LLIMMgr::addSession(
 	{
 		LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids, voice);
 	}
+    else
+    {
+        std::string session_name = LLIMModel::getInstance()->getName(session_id);
+        LLIMMgr::getInstance()->notifyObserverSessionAlreadyAdded(session_id, session_name, other_participant_id);
+    }
 
 	//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
 	if (!new_session) return session_id;
@@ -2956,6 +2961,14 @@ void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::st
 	}
 }
 
+void LLIMMgr::notifyObserverSessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+    for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+    {
+        (*it)->sessionAlreadyAdded(session_id, name, other_participant_id);
+    }
+}
+
 void LLIMMgr::notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id)
 {
 	for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 82cfa394a6..a34359eb00 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -303,6 +303,7 @@ class LLIMSessionObserver
 public:
 	virtual ~LLIMSessionObserver() {}
 	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+    virtual void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
 	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) = 0;
 	virtual void sessionRemoved(const LLUUID& session_id) = 0;
 	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) = 0;
@@ -469,6 +470,7 @@ private:
 	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
 
 	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+    void notifyObserverSessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
 	void notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id);
 	void notifyObserverSessionRemoved(const LLUUID& session_id);
 	void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 6be12711ac..302007c9aa 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -171,6 +171,7 @@ public:
 
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+    /*virtual*/ void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-- 
cgit v1.2.3


From f609f4cca3a91c8d6ea7c55b61d0b2cfd29be6b7 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Mon, 15 Oct 2012 13:55:12 +0300
Subject: CHUI-400 FIXED Disable "Activate Group" menu item if selected group
 is the active group

---
 indra/newview/llimfloatercontainer.cpp                   | 6 ++++++
 indra/newview/skins/default/xui/en/menu_conversation.xml | 1 +
 2 files changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 2248699e5e..16751a6ea1 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -961,6 +961,12 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
     uuid_vec_t mUUIDs;
     getParticipantUUIDs(mUUIDs);
 
+    if(item == std::string("can_activate_group"))
+    {
+    	LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
+    	return gAgent.getGroupID() != selected_group_id;
+    }
+
     if(mUUIDs.size() <= 0)
     {
         return false;
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 912ff811d9..682d70e4f0 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -117,6 +117,7 @@
      layout="topleft"
      name="activate_group">
         <on_click function="Group.DoToSelected" parameter="activate_group"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_activate_group" />
     </menu_item_call>		
     <menu_item_call
      label="Leave Group"
-- 
cgit v1.2.3


From 5a5df259ffc23a6289d25deac906047a7356fb42 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 15 Oct 2012 13:58:21 -0700
Subject: CHUI-380: Final commit for this issue. After code review changed some
 method names to be more accurate. Also using dynamic_cast instead of
 static_cast for safety.

---
 indra/llkdu/llimagej2ckdu.cpp          |  4 ++--
 indra/newview/llchiclet.h              |  2 +-
 indra/newview/llchicletbar.h           |  2 +-
 indra/newview/llconversationlog.h      |  2 +-
 indra/newview/llimfloatercontainer.cpp | 24 ++++++++++++++++--------
 indra/newview/llimfloatercontainer.h   |  4 ++--
 indra/newview/llimview.cpp             |  8 +++++---
 indra/newview/llimview.h               |  5 +++--
 indra/newview/llsyswellwindow.h        |  2 +-
 9 files changed, 32 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index db75b6e003..cf88de12b4 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -166,12 +166,12 @@ void LLKDUMessageWarning::put_text(const kdu_uint16 *s)
 
 void LLKDUMessageError::put_text(const char *s)
 {
-	//llinfos << "KDU Error: " << s << llendl;
+	llinfos << "KDU Error: " << s << llendl;
 }
 
 void LLKDUMessageError::put_text(const kdu_uint16 *s)
 {
-	//llinfos << "KDU Error: " << s << llendl;
+	llinfos << "KDU Error: " << s << llendl;
 }
 
 void LLKDUMessageError::flush(bool end_of_message)
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 3a52b0a67b..6395f5b694 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -874,7 +874,7 @@ class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
 	friend class LLUICtrlFactory;
 public:
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
-    /*virtual*/ void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
+    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h
index 0589a9fccc..a9a5b61ae7 100644
--- a/indra/newview/llchicletbar.h
+++ b/indra/newview/llchicletbar.h
@@ -51,7 +51,7 @@ public:
 
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-    /*virtual*/ void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
+    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 70f04b21c8..b92cf0f5e2 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -124,7 +124,7 @@ public:
 
 	// LLIMSessionObserver triggers
 	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-    virtual void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; // Stub
+    virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; // Stub
 	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
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 0250854f36..c8897c1f92 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -101,9 +101,9 @@ void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::str
 	addConversationListItem(session_id);
 }
 
-void LLIMFloaterContainer::sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-    doSomething(session_id);
+    setItemSelect(session_id);
 }
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
@@ -1064,6 +1064,7 @@ bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
     return false;
 }
 
+//Will select only the conversation item
 void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
 {
 	LLFolderViewItem* widget = mConversationsWidgets[session_id];
@@ -1074,15 +1075,22 @@ void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
 	}
 }
 
-void LLIMFloaterContainer::doSomething(const LLUUID& session_id)
+//Will select the conversation/participant item
+void LLIMFloaterContainer::setItemSelect(const LLUUID& session_id)
 {
-    LLConversationItem* vmi = static_cast<LLConversationItem*>(mConversationsRoot->getCurSelectedItem()->getParentFolder()->getViewModelItem());
 
-    if(session_id != vmi->getUUID())
+    if(mConversationsRoot->getCurSelectedItem() && mConversationsRoot->getCurSelectedItem()->getParentFolder())
     {
-        mSelectedSession = session_id;
-        LLFolderViewItem* widget = mConversationsWidgets[session_id];
-        (widget->getRoot())->setSelection(widget, FALSE, FALSE);
+        //Retreive the conversation id. When a participant is selected, then have to to get the converation id from the parent.
+        LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(mConversationsRoot->getCurSelectedItem()->getParentFolder()->getViewModelItem());
+
+        //Will allow selection/highlighting of the conversation/participant
+        if(session_id != vmi->getUUID())
+        {
+            mSelectedSession = session_id;
+            LLFolderViewItem* widget = mConversationsWidgets[session_id];
+            (widget->getRoot())->setSelection(widget, FALSE, FALSE);
+        }
     }
 }
 
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index da134c498f..c9da213f8c 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -64,7 +64,7 @@ public:
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
     void setConvItemSelect(const LLUUID& session_id);
-    void doSomething(const LLUUID& session_id);
+    void setItemSelect(const LLUUID& session_id);
 	/*virtual*/ void tabClose();
 
 	static LLFloater* getCurrentVoiceFloater();
@@ -82,7 +82,7 @@ public:
 
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-    /*virtual*/ void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e75db1b7af..eea59c223a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2650,14 +2650,16 @@ LLUUID LLIMMgr::addSession(
 		}
 	}
 
+    //Notify observers that a session was added
 	if (new_session)
 	{
 		LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids, voice);
 	}
+    //Notifies observers that the session was already added
     else
     {
         std::string session_name = LLIMModel::getInstance()->getName(session_id);
-        LLIMMgr::getInstance()->notifyObserverSessionAlreadyAdded(session_id, session_name, other_participant_id);
+        LLIMMgr::getInstance()->notifyObserverSessionActivated(session_id, session_name, other_participant_id);
     }
 
 	//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
@@ -2961,11 +2963,11 @@ void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::st
 	}
 }
 
-void LLIMMgr::notifyObserverSessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLIMMgr::notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
     for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
     {
-        (*it)->sessionAlreadyAdded(session_id, name, other_participant_id);
+        (*it)->sessionActivated(session_id, name, other_participant_id);
     }
 }
 
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index a34359eb00..00b67f520c 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -303,7 +303,7 @@ class LLIMSessionObserver
 public:
 	virtual ~LLIMSessionObserver() {}
 	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
-    virtual void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+    virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
 	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) = 0;
 	virtual void sessionRemoved(const LLUUID& session_id) = 0;
 	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) = 0;
@@ -470,7 +470,8 @@ private:
 	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
 
 	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-    void notifyObserverSessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+    //Triggers when a session has already been added
+    void notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
 	void notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id);
 	void notifyObserverSessionRemoved(const LLUUID& session_id);
 	void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 302007c9aa..378d5e0aa2 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -171,7 +171,7 @@ public:
 
 	// LLIMSessionObserver observe triggers
 	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-    /*virtual*/ void sessionAlreadyAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
+    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
 	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-- 
cgit v1.2.3


From 815884e0d49620db8f9f60fc629a26ad2c666749 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 15 Oct 2012 14:27:47 -0700
Subject: MAINT-1551 : WIP : Trace IM messaging in and out.

---
 indra/newview/lleventpoll.cpp    | 38 +++++++++++++++++++++++---------------
 indra/newview/llimfloater.cpp    |  4 +++-
 indra/newview/llimview.cpp       |  7 +++++++
 indra/newview/llspeakers.cpp     |  4 ++++
 indra/newview/llvoicechannel.cpp |  2 ++
 5 files changed, 39 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 4f4d9a40b4..1cf3de8ef0 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -37,6 +37,7 @@
 #include "llviewerregion.h"
 #include "message.h"
 #include "lltrans.h"
+#include "llsdserialize.h"
 
 namespace
 {
@@ -109,14 +110,14 @@ namespace
 		const std::string& pollURL, const LLHost& sender)
 	{
 		LLHTTPClient::ResponderPtr result = new LLEventPollResponder(pollURL, sender);
-		llinfos	<< "LLEventPollResponder::start <" << sCount << "> "
+		llinfos	<< "Merov debug : LLEventPollResponder::start <" << sCount << "> "
 				<< pollURL << llendl;
 		return result;
 	}
 
 	void LLEventPollResponder::stop()
 	{
-		llinfos	<< "LLEventPollResponder::stop	<" << mCount <<	"> "
+		llinfos	<< "Merov debug : LLEventPollResponder::stop	<" << mCount <<	"> "
 				<< mPollURL	<< llendl;
 		// there should	be a way to	stop a LLHTTPClient	request	in progress
 		mDone =	true;
@@ -134,17 +135,17 @@ namespace
 		LLViewerRegion *regionp = gAgent.getRegion();
 		if (!regionp)
 		{
-			llerrs << "LLEventPoll initialized before region is added." << llendl;
+			llinfos << "Merov debug : LLEventPoll initialized before region is added." << llendl;
 		}
 		mSender = sender.getIPandPort();
-		llinfos << "LLEventPoll initialized with sender " << mSender << llendl;
+		llinfos << "Merov debug : LLEventPoll initialized with sender " << mSender << llendl;
 		makeRequest();
 	}
 
 	LLEventPollResponder::~LLEventPollResponder()
 	{
 		stop();
-		lldebugs <<	"LLEventPollResponder::~Impl <" <<	mCount << "> "
+		llinfos <<	"Merov debug : LLEventPollResponder::~Impl <" <<	mCount << "> "
 				 <<	mPollURL <<	llendl;
 	}
 
@@ -154,6 +155,7 @@ namespace
 									const LLChannelDescriptors& channels,
 									const LLIOPipe::buffer_ptr_t& buffer)
 	{
+		llinfos << "Merov debug : LLEventPollResponder::completedRaw, status = " << status << ", reason = " << reason << llendl;
 		if (status == HTTP_BAD_GATEWAY)
 		{
 			// These errors are not parsable as LLSD, 
@@ -172,8 +174,12 @@ namespace
 		request["ack"] = mAcknowledge;
 		request["done"]	= mDone;
 		
-		lldebugs <<	"LLEventPollResponder::makeRequest	<" << mCount <<	"> ack = "
-				 <<	LLSDXMLStreamer(mAcknowledge) << llendl;
+		llinfos <<	"Merov debug : viewer->sim : LLEventPollResponder::makeRequest	<" << mCount 
+				<<	"> ack = " <<	LLSDXMLStreamer(mAcknowledge) 
+				<< ", error = " << mErrorCount
+				<< ", sender = " << mSender
+				<< ", url = " << mPollURL
+				<< ", done = " << mDone << llendl;
 		LLHTTPClient::post(mPollURL, request, this);
 	}
 
@@ -183,12 +189,14 @@ namespace
 		LLSD message;
 		message["sender"] = mSender;
 		message["body"] = content["body"];
+		llinfos << "Merov debug : sim->viewer : LLEventPollResponder::handleMessage, msg_name = " << msg_name << ", message = " << LLSDOStreamer<LLSDNotationFormatter>(message) << llendl;
 		LLMessageSystem::dispatch(msg_name, message);
 	}
 
 	//virtual
 	void LLEventPollResponder::error(U32 status, const	std::string& reason)
 	{
+		llinfos << "Merov debug : LLEventPollResponder::error, status = " << status << ", reason = " << reason << llendl;
 		if (mDone) return;
 
 		// A HTTP_BAD_GATEWAY (502) error is our standard timeout response
@@ -207,11 +215,11 @@ namespace
 										+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
 									, this);
 
-			llwarns << "Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl;
+			llinfos << "Merov debug : Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl;
 		}
 		else
 		{
-			llwarns <<	"LLEventPollResponder::error: <" << mCount << "> got "
+			llinfos <<	"Merov debug : LLEventPollResponder::error: <" << mCount << "> got "
 					<<	status << ": " << reason
 					<<	(mDone ? " -- done"	: "") << llendl;
 			stop();
@@ -227,7 +235,7 @@ namespace
 			// continue running.
 			if(gAgent.getRegion() && gAgent.getRegion()->getHost().getIPandPort() == mSender)
 			{
-				llwarns << "Forcing disconnect due to stalled main region event poll."  << llendl;
+				llinfos << "Merov debug : Forcing disconnect due to stalled main region event poll."  << llendl;
 				LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
 			}
 		}
@@ -236,8 +244,8 @@ namespace
 	//virtual
 	void LLEventPollResponder::result(const LLSD& content)
 	{
-		lldebugs <<	"LLEventPollResponder::result <" << mCount	<< ">"
-				 <<	(mDone ? " -- done"	: "") << llendl;
+		llinfos <<	"Merov debug : LLEventPollResponder::result <" << mCount	<< "> "
+				 <<	(mDone ? " -- done"	: "") << ", content = " << LLSDOStreamer<LLSDNotationFormatter>(content) << llendl;
 		
 		if (mDone) return;
 
@@ -246,7 +254,7 @@ namespace
 		if (!content.get("events") ||
 			!content.get("id"))
 		{
-			llwarns << "received event poll with no events or id key" << llendl;
+			llinfos << "Merov debug : received event poll with no events or id key" << llendl;
 			makeRequest();
 			return;
 		}
@@ -256,11 +264,11 @@ namespace
 
 		if(mAcknowledge.isUndefined())
 		{
-			llwarns << "LLEventPollResponder: id undefined" << llendl;
+			llinfos << "Merov debug : LLEventPollResponder: id undefined" << llendl;
 		}
 		
 		// was llinfos but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
-		lldebugs  << "LLEventPollResponder::completed <" <<	mCount << "> " << events.size() << "events (id "
+		llinfos  << "Merov debug : LLEventPollResponder::completed <" <<	mCount << "> " << events.size() << "events (id "
 				 <<	LLSDXMLStreamer(mAcknowledge) << ")" << llendl;
 		
 		LLSD::array_const_iterator i = events.beginArray();
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 467f48600a..47e091a57c 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -59,6 +59,7 @@
 #include "llviewerchat.h"
 #include "llnotificationmanager.h"
 #include "llautoreplace.h"
+#include "llsdserialize.h"
 
 floater_showed_signal_t LLIMFloater::sIMFloaterShowedSignal;
 
@@ -1208,11 +1209,12 @@ BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 			}
 			data["method"] = "invite";
 			data["session-id"] = mSessionID;
+			llinfos << "Merov debug : viewer->sim :  LLIMFloater::inviteToSession, session id = " << mSessionID << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 			LLHTTPClient::post(url,	data,new LLSessionInviteResponder(mSessionID));
 		}
 		else
 		{
-			llinfos << "LLIMFloater::inviteToSession -"
+			llinfos << "Merov debug : LLIMFloater::inviteToSession -"
 					<< " no need to invite agents for "
 					<< mDialog << llendl;
 			// successful add, because everyone that needed to get added
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b45903835a..398584e005 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -63,6 +63,7 @@
 #include "lltoolbarview.h"
 #include "llviewercontrol.h"
 #include "llviewerparcelmgr.h"
+#include "llsdserialize.h"
 
 
 const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -1316,6 +1317,7 @@ bool LLIMModel::sendStartSession(
 
 			data["params"] = agents;
 
+			llinfos << "Merov debug : viewer-> sim : LLIMModel::sendStartSession, session id = " << temp_session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 			LLHTTPClient::post(
 				url,
 				data,
@@ -2253,6 +2255,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 				LLSD data;
 				data["method"] = "accept invitation";
 				data["session-id"] = session_id;
+				llinfos << "Merov debug : viewer-> sim : LLIncomingCallDialog::processCallResponse, accept, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 				LLHTTPClient::post(
 					url,
 					data,
@@ -2293,6 +2296,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 			LLSD data;
 			data["method"] = "decline invitation";
 			data["session-id"] = session_id;
+			llinfos << "Merov debug : viewer-> sim : LLIncomingCallDialog::processCallResponse, decline, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 			LLHTTPClient::post(
 				url,
 				data,
@@ -2346,6 +2350,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 				LLSD data;
 				data["method"] = "accept invitation";
 				data["session-id"] = session_id;
+				llinfos << "Merov debug : viewer-> sim : inviteUserResponse, accept, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 				LLHTTPClient::post(
 					url,
 					data,
@@ -2381,6 +2386,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 			LLSD data;
 			data["method"] = "decline invitation";
 			data["session-id"] = session_id;
+			llinfos << "Merov debug : viewer-> sim : inviteUserResponse, decline, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 			LLHTTPClient::post(
 				url,
 				data,
@@ -3345,6 +3351,7 @@ public:
 				LLSD data;
 				data["method"] = "accept invitation";
 				data["session-id"] = session_id;
+				llinfos << "Merov debug : viewer-> sim : LLViewerChatterBoxInvitation, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 				LLHTTPClient::post(
 					url,
 					data,
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 2d2b5202e0..19b99fef11 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -36,6 +36,7 @@
 #include "llviewerobjectlist.h"
 #include "llvoavatar.h"
 #include "llworld.h"
+#include "llsdserialize.h"
 
 const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
 const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
@@ -785,6 +786,7 @@ void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
 	//current value represents ability to type, so invert
 	data["params"]["mute_info"]["text"] = !speakerp->mModeratorMutedText;
 
+	llinfos << "Merov debug : viewer->sim : LLIMSpeakerMgr::toggleAllowTextChat, session id = " << getSessionID() << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 	LLHTTPClient::post(url, data, new ModerationResponder(getSessionID()));
 }
 
@@ -809,6 +811,7 @@ void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmu
 	data["params"]["mute_info"] = LLSD::emptyMap();
 	data["params"]["mute_info"]["voice"] = !unmute;
 
+	llinfos << "Merov debug : viewer->sim : LLIMSpeakerMgr::moderateVoiceParticipant, session id = " << getSessionID() << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 	LLHTTPClient::post(
 		url,
 		data,
@@ -851,6 +854,7 @@ void LLIMSpeakerMgr::moderateVoiceSession(const LLUUID& session_id, bool disallo
 	data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap();
 	data["params"]["update_info"]["moderated_mode"]["voice"] = disallow_voice;
 
+	llinfos << "Merov debug : viewer->sim : LLIMSpeakerMgr::moderateVoiceSession, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 	LLHTTPClient::post(url, data, new ModerationResponder(session_id));
 }
 
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index ceff75a0cc..62a43333dd 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -35,6 +35,7 @@
 #include "llrecentpeople.h"
 #include "llviewercontrol.h"
 #include "llvoicechannel.h"
+#include "llsdserialize.h"
 
 
 LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap;
@@ -539,6 +540,7 @@ void LLVoiceChannelGroup::getChannelInfo()
 		LLSD data;
 		data["method"] = "call";
 		data["session-id"] = mSessionID;
+		llinfos << "Merov debug : viewer-> sim : LLVoiceChannelGroup::getChannelInfo, session id = " << mSessionID << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 		LLHTTPClient::post(url,
 						   data,
 						   new LLVoiceCallCapResponder(mSessionID));
-- 
cgit v1.2.3


From 699e0a1e0b89e4d3c2d1342c821496c5699b8c52 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 15 Oct 2012 14:28:07 -0700
Subject: CHUI-380: Merge fix, the addConverationListItem API was changedso
 that it does not by default select the new conversation item. Adjusted
 sessionAdded and sessionVoiceOrImStarted functions to specify that the first
 item should be selected when calling addConversationListItem().

---
 indra/newview/llimfloatercontainer.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 8a30b5cd68..5c1105531e 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -98,7 +98,7 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
 	LLIMFloater::addToHost(session_id, true);
-	addConversationListItem(session_id);
+	addConversationListItem(session_id, true);
 }
 
 void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
@@ -109,7 +109,7 @@ void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std:
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
 	LLIMFloater::addToHost(session_id, true);
-	addConversationListItem(session_id);
+	addConversationListItem(session_id, true);
 }
 
 void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-- 
cgit v1.2.3


From a8c443feb21d5fe486e9a30649089633ae3f6e22 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 15 Oct 2012 14:29:57 -0700
Subject: MAINT-1551 : WIP : More IM comm tracing and attempt to fix

---
 indra/newview/llavataractions.cpp | 11 +++++++++--
 indra/newview/lleventpoll.cpp     | 31 +++++++++++++++++--------------
 indra/newview/llspeakers.cpp      |  2 ++
 3 files changed, 28 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 3326103d03..f7f5c04ef9 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -296,10 +296,17 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
 	}
 	const std::string title = LLTrans::getString("conference-title");
 	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array, false, floater_id);
-	if (session_id != LLUUID::null)
+
+	if (session_id == LLUUID::null)
 	{
-		LLIMFloater::show(session_id);
+		return;
 	}
+	
+	LLIMFloater::show(session_id);
+//	gIMMgr->processAgentListUpdates(session_id, LLSD());
+	gIMMgr->startCall(session_id,LLVoiceChannel::OUTGOING_CALL);
+	gIMMgr->endCall(session_id);
+	
 	make_ui_sound("UISndStartIM");
 }
 
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 4f4d9a40b4..a5aa014a74 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -109,14 +109,14 @@ namespace
 		const std::string& pollURL, const LLHost& sender)
 	{
 		LLHTTPClient::ResponderPtr result = new LLEventPollResponder(pollURL, sender);
-		llinfos	<< "LLEventPollResponder::start <" << sCount << "> "
+		llinfos	<< "Merov debug : LLEventPollResponder::start <" << sCount << "> "
 				<< pollURL << llendl;
 		return result;
 	}
 
 	void LLEventPollResponder::stop()
 	{
-		llinfos	<< "LLEventPollResponder::stop	<" << mCount <<	"> "
+		llinfos	<< "Merov debug : LLEventPollResponder::stop	<" << mCount <<	"> "
 				<< mPollURL	<< llendl;
 		// there should	be a way to	stop a LLHTTPClient	request	in progress
 		mDone =	true;
@@ -137,14 +137,14 @@ namespace
 			llerrs << "LLEventPoll initialized before region is added." << llendl;
 		}
 		mSender = sender.getIPandPort();
-		llinfos << "LLEventPoll initialized with sender " << mSender << llendl;
+		llinfos << "Merov debug : LLEventPoll initialized with sender " << mSender << llendl;
 		makeRequest();
 	}
 
 	LLEventPollResponder::~LLEventPollResponder()
 	{
 		stop();
-		lldebugs <<	"LLEventPollResponder::~Impl <" <<	mCount << "> "
+		llinfos << "Merov debug : LLEventPollResponder::~Impl <" <<	mCount << "> "
 				 <<	mPollURL <<	llendl;
 	}
 
@@ -154,11 +154,13 @@ namespace
 									const LLChannelDescriptors& channels,
 									const LLIOPipe::buffer_ptr_t& buffer)
 	{
+		llinfos << "Merov debug : LLEventPollResponder::completedRaw url <" << mPollURL << ">, status = " <<	status << ", reason = " <<	reason <<	llendl;
 		if (status == HTTP_BAD_GATEWAY)
 		{
 			// These errors are not parsable as LLSD, 
 			// which LLHTTPClient::Responder::completedRaw will try to do.
-			completed(status, reason, LLSD());
+			//completed(status, reason, LLSD());
+			error(status, reason);
 		}
 		else
 		{
@@ -172,8 +174,7 @@ namespace
 		request["ack"] = mAcknowledge;
 		request["done"]	= mDone;
 		
-		lldebugs <<	"LLEventPollResponder::makeRequest	<" << mCount <<	"> ack = "
-				 <<	LLSDXMLStreamer(mAcknowledge) << llendl;
+		llinfos << "Merov debug : LLEventPollResponder::makeRequest	<" << mCount <<	"> ack = " <<	LLSDXMLStreamer(mAcknowledge) << llendl;
 		LLHTTPClient::post(mPollURL, request, this);
 	}
 
@@ -183,6 +184,7 @@ namespace
 		LLSD message;
 		message["sender"] = mSender;
 		message["body"] = content["body"];
+		llinfos << "Merov debug : LLEventPollResponder::handleMessage, msg_name = " << msg_name << ", message = " << LLSDOStreamer<LLSDNotationFormatter>(message) << llendl;
 		LLMessageSystem::dispatch(msg_name, message);
 	}
 
@@ -190,6 +192,7 @@ namespace
 	void LLEventPollResponder::error(U32 status, const	std::string& reason)
 	{
 		if (mDone) return;
+		llinfos << "Merov debug : LLEventPollResponder::error, status = " << status << ", reason = " << reason << llendl;
 
 		// A HTTP_BAD_GATEWAY (502) error is our standard timeout response
 		// we get this when there are no events.
@@ -207,11 +210,11 @@ namespace
 										+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
 									, this);
 
-			llwarns << "Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl;
+			llinfos << "Merov debug : Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl;
 		}
 		else
 		{
-			llwarns <<	"LLEventPollResponder::error: <" << mCount << "> got "
+			llinfos << "Merov debug : LLEventPollResponder::error: <" << mCount << "> got "
 					<<	status << ": " << reason
 					<<	(mDone ? " -- done"	: "") << llendl;
 			stop();
@@ -227,7 +230,7 @@ namespace
 			// continue running.
 			if(gAgent.getRegion() && gAgent.getRegion()->getHost().getIPandPort() == mSender)
 			{
-				llwarns << "Forcing disconnect due to stalled main region event poll."  << llendl;
+				llinfos << "Merov debug : Forcing disconnect due to stalled main region event poll."  << llendl;
 				LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
 			}
 		}
@@ -236,7 +239,7 @@ namespace
 	//virtual
 	void LLEventPollResponder::result(const LLSD& content)
 	{
-		lldebugs <<	"LLEventPollResponder::result <" << mCount	<< ">"
+		llinfos << "Merov debug : LLEventPollResponder::result <" << mCount	<< ">"
 				 <<	(mDone ? " -- done"	: "") << llendl;
 		
 		if (mDone) return;
@@ -246,7 +249,7 @@ namespace
 		if (!content.get("events") ||
 			!content.get("id"))
 		{
-			llwarns << "received event poll with no events or id key" << llendl;
+			llinfos << "Merov debug : received event poll with no events or id key" << llendl;
 			makeRequest();
 			return;
 		}
@@ -256,11 +259,11 @@ namespace
 
 		if(mAcknowledge.isUndefined())
 		{
-			llwarns << "LLEventPollResponder: id undefined" << llendl;
+			llinfos << "Merov debug : LLEventPollResponder: id undefined" << llendl;
 		}
 		
 		// was llinfos but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
-		lldebugs  << "LLEventPollResponder::completed <" <<	mCount << "> " << events.size() << "events (id "
+		llinfos << "Merov debug : LLEventPollResponder::completed <" <<	mCount << "> " << events.size() << "events (id "
 				 <<	LLSDXMLStreamer(mAcknowledge) << ")" << llendl;
 		
 		LLSD::array_const_iterator i = events.beginArray();
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 2d2b5202e0..92149ee50a 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -286,6 +286,7 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
 		mSpeakers.insert(std::make_pair(speakerp->mID, speakerp));
 		mSpeakersSorted.push_back(speakerp);
 		LL_DEBUGS("Speakers") << "Added speaker " << id << llendl;
+		//llinfos << "Merov debug : setSpeaker, add, id = " << id << ", name = " << name << llendl;
 		fireEvent(new LLSpeakerListChangeEvent(this, speakerp->mID), "add");
 	}
 	else
@@ -306,6 +307,7 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
 		}
 		else
 		{
+			llinfos << "Merov debug : setSpeaker, speaker not found? id = " << id << ", name = " << name << llendl;
 			LL_WARNS("Speakers") << "Speaker " << id << " not found" << llendl;
 		}
 	}
-- 
cgit v1.2.3


From d0f9600f37a87b2d6c7a2c3cfbbc5d793e505872 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 15 Oct 2012 16:06:02 -0700
Subject: CHUI-380: Bug fix after merge. When selecting the participant of a
 conversation focus would be lost on the converstation floater. This was
 because focus would be set to the participant folder item. Resolution: Now
 delegate focus from the particiapnt folder item to the conversation floater.

---
 indra/newview/llconversationview.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 637f30635e..b7ebb70e86 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -425,6 +425,7 @@ void LLConversationViewParticipant::selectItem()
 {
     LLConversationItem* vmi = this->getParentFolder() ? static_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
     LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
+    LLFloater* session_floater;
 
     //Only execute when switching floaters (conversations)
     if(vmi && vmi->getUUID() != container->getSelectedSession())
@@ -441,6 +442,12 @@ void LLConversationViewParticipant::selectItem()
             LLIMFloater::show(vmi->getUUID());
         }
     }
+    //Focus the current conversation floater (it is already visible so just focus it)
+    else
+    {
+        session_floater = LLIMConversation::getConversation(vmi->getUUID());
+        session_floater->setFocus(TRUE);
+    }
 
     LLFolderViewItem::selectItem();
 }
-- 
cgit v1.2.3


From 1557bffb5630158430946abd600218be89e3590e Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 15 Oct 2012 19:44:14 -0700
Subject: MAINT-1551 : WIP : Added a hack : send an accept invitation message
 so to trigger the sending of the agent list.

---
 indra/newview/llavataractions.cpp |   4 +-
 indra/newview/llspeakers.cpp      | 126 +++++++++++++++++++++++++++-----------
 indra/newview/llspeakers.h        |   2 +
 3 files changed, 93 insertions(+), 39 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index f7f5c04ef9..600df31c8b 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -304,8 +304,8 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
 	
 	LLIMFloater::show(session_id);
 //	gIMMgr->processAgentListUpdates(session_id, LLSD());
-	gIMMgr->startCall(session_id,LLVoiceChannel::OUTGOING_CALL);
-	gIMMgr->endCall(session_id);
+//	gIMMgr->startCall(session_id,LLVoiceChannel::OUTGOING_CALL);
+//	gIMMgr->endCall(session_id);
 	
 	make_ui_sound("UISndStartIM");
 }
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 2e26eabb71..11d1b563ac 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -256,6 +256,64 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_
 }
 
 
+//
+// ModerationResponder
+//
+
+class ModerationResponder : public LLHTTPClient::Responder
+{
+public:
+	ModerationResponder(const LLUUID& session_id)
+	{
+		mSessionID = session_id;
+	}
+	
+	virtual void error(U32 status, const std::string& reason)
+	{
+		llwarns << status << ": " << reason << llendl;
+		
+		if ( gIMMgr )
+		{
+			//403 == you're not a mod
+			//should be disabled if you're not a moderator
+			if ( 403 == status )
+			{
+				gIMMgr->showSessionEventError(
+											  "mute",
+											  "not_a_mod_error",
+											  mSessionID);
+			}
+			else
+			{
+				gIMMgr->showSessionEventError(
+											  "mute",
+											  "generic_request_error",
+											  mSessionID);
+			}
+		}
+	}
+	
+private:
+	LLUUID mSessionID;
+};
+
+class UpdateResponder : public LLHTTPClient::Responder
+{
+public:
+	UpdateResponder(const LLUUID& session_id)
+	{
+		mSessionID = session_id;
+	}
+	
+	virtual void error(U32 status, const std::string& reason)
+	{
+		llinfos << "Merov debug : UpdateResponder error, status = " << status << ": " << reason << llendl;
+	}
+	
+private:
+	LLUUID mSessionID;
+};
+
 //
 // LLSpeakerMgr
 //
@@ -483,6 +541,37 @@ void LLSpeakerMgr::updateSpeakerList()
 
 		}
 	}
+	else 
+	{
+		// Check if the list is empty, except if it's Nearby Chat (session_id NULL).
+		LLUUID session_id = getSessionID();
+		if ((mSpeakers.size() == 0) && (!session_id.isNull()))
+		{
+			llinfos << "Merov debug : LLSpeakerMgr::updateSpeakerList: No speakers in " << session_id << llendl;
+			// MAINT-1551 : If the list is empty for too long, we should send a message to the sim so that
+			// it sends the participant list again.
+			updateSession();
+		}
+	}
+}
+
+void LLSpeakerMgr::updateSession()
+{
+	std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
+	LLSD data;
+	data["method"] = "accept invitation";
+//	data["method"] = "session update";
+	data["session-id"] = getSessionID();
+//	data["params"] = LLSD::emptyMap();
+	
+//	data["params"]["update_info"] = LLSD::emptyMap();
+	
+//	data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap();
+//	data["params"]["update_info"]["moderated_mode"]["voice"] = false;
+	
+	llinfos << "Merov debug : viewer->sim : LLSpeakerMgr::updateSession, session id = " << getSessionID() << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
+
+	LLHTTPClient::post(url, data, new UpdateResponder(getSessionID()));
 }
 
 void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
@@ -736,43 +825,6 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
 	}
 }
 
-class ModerationResponder : public LLHTTPClient::Responder
-{
-public:
-	ModerationResponder(const LLUUID& session_id)
-	{
-		mSessionID = session_id;
-	}
-
-	virtual void error(U32 status, const std::string& reason)
-	{
-		llwarns << status << ": " << reason << llendl;
-
-		if ( gIMMgr )
-		{
-			//403 == you're not a mod
-			//should be disabled if you're not a moderator
-			if ( 403 == status )
-			{
-				gIMMgr->showSessionEventError(
-					"mute",
-					"not_a_mod_error",
-					mSessionID);
-			}
-			else
-			{
-				gIMMgr->showSessionEventError(
-					"mute",
-					"generic_request_error",
-					mSessionID);
-			}
-		}
-	}
-
-private:
-	LLUUID mSessionID;
-};
-
 void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
 {
 	LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 8ab08661d3..671b3fb341 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -258,6 +258,8 @@ protected:
 	void setSpeakerNotInChannel(LLSpeaker* speackerp);
 	bool removeSpeaker(const LLUUID& speaker_id);
 
+	void updateSession();
+
 	typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
 	speaker_map_t		mSpeakers;
 
-- 
cgit v1.2.3


From 5a22949cf509ebd1a3c7dfbd029b4bc188fee4a3 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 16 Oct 2012 15:33:12 +0300
Subject: CHUI-388 FIXED Do not add menu items to Participant Menu if own
 avatar is selected in participant list. Do not show Menu if all menu items
 are disabled.

---
 indra/llui/llmenugl.cpp               | 12 +++++++++++-
 indra/newview/llconversationmodel.cpp |  6 +++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 5182a8cea1..ae4aa1e1dd 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3037,7 +3037,17 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 	const S32 CURSOR_HEIGHT = 22;		// Approximate "normal" cursor size
 	const S32 CURSOR_WIDTH = 12;
 
-	if(menu->getChildList()->empty())
+	//Do not show menu if all menu items are disabled
+	BOOL item_enabled = false;
+	for (LLView::child_list_t::const_iterator itor = menu->getChildList()->begin();
+			 itor != menu->getChildList()->end();
+			 ++itor)
+	{
+		LLView *menu_item = (*itor);
+		item_enabled = item_enabled || menu_item->getEnabled();
+	}
+
+	if(menu->getChildList()->empty() || !item_enabled)
 	{
 		return;
 	}
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 29e7ac4e12..e5232d730c 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -27,6 +27,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llagent.h"
 #include "llavatarnamecache.h"
 #include "llavataractions.h"
 #include "llevents.h"
@@ -374,7 +375,10 @@ void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
     menuentry_vec_t items;
     menuentry_vec_t disabled_items;
 
-    buildParticipantMenuOptions(items);
+    if(gAgent.getID() != mUUID)
+    {
+    	buildParticipantMenuOptions(items);
+    }
     hide_context_entries(menu, items, disabled_items);
 }
 
-- 
cgit v1.2.3


From ae093e02a126666c9137d9eb6d9aeea0c1c73a8a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 16 Oct 2012 11:38:36 -0700
Subject: CHUI-380: Realized that the when clicking the
 participant/conversation item that the active session wasn't being stored.
 This caused the right side conversation floater to not change when selecting
 a participant under a conersation. Resolution: now when clicking on a
 conversation or participant the active session is stored using
 setActiveSession().

---
 indra/newview/llconversationview.cpp | 6 ++++++
 indra/newview/llimfloatercontainer.h | 1 +
 2 files changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index b7ebb70e86..1b450665b3 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -242,6 +242,9 @@ void LLConversationViewSession::selectItem()
 	
 	// Set the focus on the selected floater
 	session_floater->setFocus(TRUE);
+    // Store the active session
+    LLIMFloaterContainer::getInstance()->setSelectedSession(item->getUUID());
+
 
 	LLFolderViewItem::selectItem();
 }
@@ -441,6 +444,9 @@ void LLConversationViewParticipant::selectItem()
         {
             LLIMFloater::show(vmi->getUUID());
         }
+
+        // Store the active session
+        container->setSelectedSession(vmi->getUUID());
     }
     //Focus the current conversation floater (it is already visible so just focus it)
     else
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 6643471d97..579f62c688 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -89,6 +89,7 @@ public:
 
 	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
     LLUUID getSelectedSession() { return mSelectedSession; }
+    void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
-- 
cgit v1.2.3


From 337cd3aa9d8a8beaebd35ec6b53f09709e35a4d4 Mon Sep 17 00:00:00 2001
From: "Jeff (Gioffredo Linden)" <gioffredo@lindenlab.com>
Date: Tue, 16 Oct 2012 15:22:42 -0400
Subject: Make getValue const to fix Windows builds - and be more robust

---
 indra/newview/llchathistory.cpp | 2 +-
 indra/newview/llchathistory.h   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index deb658c489..821d1f4685 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -596,7 +596,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
 	mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
 }
 
-LLSD LLChatHistory::getValue()
+const LLSD LLChatHistory::getValue()
 {
   LLSD* text=new LLSD(); 
   text->assign(mEditor->getText());
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index effdd75911..b65d222b53 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -103,7 +103,7 @@ class LLChatHistory : public LLUICtrl
 
 	public:
 		~LLChatHistory();
-		LLSD getValue();   
+		const LLSD getValue();   
 		void initFromParams(const Params&);
 
 		/**
-- 
cgit v1.2.3


From 86c3a45b6749387991064df6a42b1d046bd9d4d8 Mon Sep 17 00:00:00 2001
From: "Jeff (Gioffredo Linden)" <gioffredo@lindenlab.com>
Date: Tue, 16 Oct 2012 16:08:25 -0400
Subject: Move const kw location

---
 indra/newview/llchathistory.cpp | 2 +-
 indra/newview/llchathistory.h   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 821d1f4685..c61a8c8562 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -596,7 +596,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
 	mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
 }
 
-const LLSD LLChatHistory::getValue()
+LLSD LLChatHistory::getValue() const
 {
   LLSD* text=new LLSD(); 
   text->assign(mEditor->getText());
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index b65d222b53..bb6d4fb59c 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -103,7 +103,7 @@ class LLChatHistory : public LLUICtrl
 
 	public:
 		~LLChatHistory();
-		const LLSD getValue();   
+		LLSD getValue() const;   
 		void initFromParams(const Params&);
 
 		/**
-- 
cgit v1.2.3


From 1251f45e6246d81658cf4fe6f2654472c772e94b Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 17 Oct 2012 00:16:18 +0300
Subject: CHUI-394 FIXED Group moderation tools missing in right click menus

---
 indra/llui/llmenugl.cpp                            | 117 +++----
 indra/llui/llmenugl.h                              |  35 +-
 indra/llui/lltoggleablemenu.cpp                    |   5 +
 indra/llui/lltoggleablemenu.h                      |   2 +
 indra/newview/llconversationmodel.cpp              |  13 +
 indra/newview/llimfloatercontainer.cpp             | 344 ++++++++++++++++----
 indra/newview/llimfloatercontainer.h               |  13 +
 indra/newview/llinventorybridge.cpp                |   2 +-
 indra/newview/llparticipantlist.cpp                | 361 ---------------------
 indra/newview/llparticipantlist.h                  |  75 -----
 .../skins/default/xui/en/menu_conversation.xml     |  45 +++
 11 files changed, 435 insertions(+), 577 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index ae4aa1e1dd..93dc13475b 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1764,6 +1764,26 @@ bool LLMenuGL::addChild(LLView* view, S32 tab_group)
 	return false;
 }
 
+// Used in LLContextMenu and in LLTogleableMenu
+
+// Add an item to the context menu branch
+bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)
+{
+	LLContextMenu* context = dynamic_cast<LLContextMenu*>(view);
+	if (context)
+		return appendContextSubMenu(context);
+
+	LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view);
+	if (separator)
+		return append(separator);
+
+	LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view);
+	if (item)
+		return append(item);
+
+	return false;
+}
+
 void LLMenuGL::removeChild( LLView* ctrl)
 {
 	// previously a dynamic_cast with if statement to check validity
@@ -2501,6 +2521,32 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu )
 	return success;
 }
 
+// add a context menu branch
+
+BOOL LLMenuGL::appendContextSubMenu(LLMenuGL *menu)
+
+{
+	if (menu == this)
+	{
+		llerrs << "Can't attach a context menu to itself" << llendl;
+	}
+
+	LLContextMenuBranch *item;
+	LLContextMenuBranch::Params p;
+
+	p.name = menu->getName();
+	p.label = menu->getLabel();
+	p.branch = (LLContextMenu *)menu;
+	p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor");
+	p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
+	p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
+	p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
+	item = LLUICtrlFactory::create<LLContextMenuBranch>(p);
+	LLMenuGL::sMenuContainer->addChild(item->getBranch());
+
+	return append( item );
+}
+
 void LLMenuGL::setEnabledSubMenus(BOOL enable)
 {
 	setEnabled(enable);
@@ -3735,39 +3781,6 @@ void LLTearOffMenu::closeTearOff()
 	mMenu->setDropShadowed(TRUE);
 }
 
-
-//-----------------------------------------------------------------------------
-// class LLContextMenuBranch
-// A branch to another context menu
-//-----------------------------------------------------------------------------
-class LLContextMenuBranch : public LLMenuItemGL
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
-	{
-		Mandatory<LLContextMenu*> branch;
-	};
-
-	LLContextMenuBranch(const Params&);
-
-	virtual ~LLContextMenuBranch()
-	{}
-
-	// called to rebuild the draw label
-	virtual void	buildDrawLabel( void );
-
-	// onCommit() - do the primary funcationality of the menu item.
-	virtual void	onCommit( void );
-
-	LLContextMenu*	getBranch() { return mBranch.get(); }
-	void			setHighlight( BOOL highlight );
-
-protected:
-	void	showSubMenu();
-
-	LLHandle<LLContextMenu> mBranch;
-};
-
 LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) 
 :	LLMenuItemGL(p),
 	mBranch( p.branch()->getHandle() )
@@ -4039,44 +4052,8 @@ BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )
 	return result;
 }
 
-BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu)
-{
-	
-	if (menu == this)
-	{
-		llerrs << "Can't attach a context menu to itself" << llendl;
-	}
-
-	LLContextMenuBranch *item;
-	LLContextMenuBranch::Params p;
-	p.name = menu->getName();
-	p.label = menu->getLabel();
-	p.branch = menu;
-	p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor");
-	p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor");
-	p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor");
-	p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor");
-	
-	item = LLUICtrlFactory::create<LLContextMenuBranch>(p);
-	LLMenuGL::sMenuContainer->addChild(item->getBranch());
-
-	return append( item );
-}
-
 bool LLContextMenu::addChild(LLView* view, S32 tab_group)
 {
-	LLContextMenu* context = dynamic_cast<LLContextMenu*>(view);
-	if (context)
-		return appendContextSubMenu(context);
-
-	LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view);
-	if (separator)
-		return append(separator);
-
-	LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view);
-	if (item)
-		return append(item);
-
-	return false;
+	return addContextChild(view, tab_group);
 }
 
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index a9de3ef937..3e03232e92 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -519,6 +519,9 @@ public:
 	void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; }
 	bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; }
 
+	// add a context menu branch
+	BOOL appendContextSubMenu(LLMenuGL *menu);
+
 protected:
 	void createSpilloverBranch();
 	void cleanupSpilloverBranch();
@@ -528,6 +531,10 @@ protected:
 	// add a menu - this will create a cascading menu
 	virtual BOOL appendMenu( LLMenuGL* menu );
 
+	// Used in LLContextMenu and in LLTogleableMenu
+	// to add an item of context menu branch
+	bool addContextChild(LLView* view, S32 tab_group);
+
 	// TODO: create accessor methods for these?
 	typedef std::list< LLMenuItemGL* > item_list_t;
 	item_list_t mItems;
@@ -677,8 +684,6 @@ public:
 
 	virtual bool	addChild			(LLView* view, S32 tab_group = 0);
 
-			BOOL	appendContextSubMenu(LLContextMenu *menu);
-
 			LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
 
 			LLView*	getSpawningView() const		{ return mSpawningViewHandle.get(); }
@@ -691,7 +696,33 @@ protected:
 	LLHandle<LLView>			mSpawningViewHandle;
 };
 
+//-----------------------------------------------------------------------------
+// class LLContextMenuBranch
+// A branch to another context menu
+//-----------------------------------------------------------------------------
+class LLContextMenuBranch : public LLMenuItemGL
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>
+	{
+		Mandatory<LLContextMenu*> branch;
+	};
+
+	LLContextMenuBranch(const Params&);
+
+	// Called to rebuild strings for this item
+	virtual void	buildDrawLabel( void );
 
+	// Performed when menu item clicked
+	virtual void	onCommit( void );
+
+	LLContextMenu*	getBranch() { return mBranch.get(); }
+	void			setHighlight( BOOL highlight );
+
+protected:
+	void			showSubMenu();
+	LLHandle<LLContextMenu> mBranch;
+};
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLMenuBarGL
diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp
index d29260750f..b4c6c6162b 100644
--- a/indra/llui/lltoggleablemenu.cpp
+++ b/indra/llui/lltoggleablemenu.cpp
@@ -99,3 +99,8 @@ bool LLToggleableMenu::toggleVisibility()
 
 	return true;
 }
+
+bool LLToggleableMenu::addChild(LLView* view, S32 tab_group)
+{
+	return addContextChild(view, tab_group);
+}
diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h
index dd9ac5b8c1..57b8f62eb6 100644
--- a/indra/llui/lltoggleablemenu.h
+++ b/indra/llui/lltoggleablemenu.h
@@ -47,6 +47,8 @@ public:
 
 	virtual void handleVisibilityChange (BOOL curVisibilityIn);
 
+	virtual bool addChild (LLView* view, S32 tab_group = 0);
+	
 	const LLRect& getButtonRect() const { return mButtonRect; }
 
 	// Converts the given local button rect to a screen rect
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index e5232d730c..f0c8658cfe 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -114,6 +114,19 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t&   items)
     items.push_back(std::string("share"));
     items.push_back(std::string("pay"));
     items.push_back(std::string("block_unblock"));
+
+	if(this->getType() != CONV_SESSION_1_ON_1)
+	{
+		items.push_back(std::string("Moderator Options Separator"));
+		items.push_back(std::string("Moderator Options"));
+		items.push_back(std::string("AllowTextChat"));
+		items.push_back(std::string("moderate_voice_separator"));
+		items.push_back(std::string("ModerateVoiceMuteSelected"));
+		items.push_back(std::string("ModerateVoiceUnMuteSelected"));
+		items.push_back(std::string("ModerateVoiceMute"));
+		items.push_back(std::string("ModerateVoiceUnmute"));
+	}
+
 }
 
 //
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 5c1105531e..c9c7e94af9 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -44,6 +44,7 @@
 #include "llfloateravatarpicker.h"
 #include "llfloaterpreference.h"
 #include "llimview.h"
+#include "llnotificationsutil.h"
 #include "lltransientfloatermgr.h"
 #include "llviewercontrol.h"
 #include "llconversationview.h"
@@ -830,59 +831,67 @@ void LLIMFloaterContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
 
 void LLIMFloaterContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
 {
-    if(selectedIDS.size() > 0)
-{
-        const LLUUID userID = selectedIDS.front();
+	if(selectedIDS.size() > 0)
+	{
+		const LLUUID& userID = selectedIDS.front();
 
-    if ("view_profile" == command)
-    {
-        LLAvatarActions::showProfile(userID);
-    }
-    else if("im" == command)
-    {
-        LLAvatarActions::startIM(userID);
-    }
-    else if("offer_teleport" == command)
-    {
-        LLAvatarActions::offerTeleport(selectedIDS);
-    }
-    else if("voice_call" == command)
-    {
-        LLAvatarActions::startCall(userID);
-    }
-    else if("chat_history" == command)
-    {
-        LLAvatarActions::viewChatHistory(userID);
-    }
-    else if("add_friend" == command)
-    {
-        LLAvatarActions::requestFriendshipDialog(userID);
-    }
-    else if("remove_friend" == command)
-    {
-        LLAvatarActions::removeFriendDialog(userID);
-    }
-    else if("invite_to_group" == command)
-    {
-        LLAvatarActions::inviteToGroup(userID);
-    }
-    else if("map" == command)
-    {
-        LLAvatarActions::showOnMap(userID);
-    }
-    else if("share" == command)
-    {
-        LLAvatarActions::share(userID);
-    }
-    else if("pay" == command)
-    {
-        LLAvatarActions::pay(userID);
-    }
-    else if("block_unblock" == command)
-    {
-        LLAvatarActions::toggleBlock(userID);
-    }
-}
+		if ("view_profile" == command)
+		{
+			LLAvatarActions::showProfile(userID);
+		}
+		else if("im" == command)
+		{
+			LLAvatarActions::startIM(userID);
+		}
+		else if("offer_teleport" == command)
+		{
+			LLAvatarActions::offerTeleport(selectedIDS);
+		}
+		else if("voice_call" == command)
+		{
+			LLAvatarActions::startCall(userID);
+		}
+		else if("chat_history" == command)
+		{
+			LLAvatarActions::viewChatHistory(userID);
+		}
+		else if("add_friend" == command)
+		{
+			LLAvatarActions::requestFriendshipDialog(userID);
+		}
+		else if("remove_friend" == command)
+		{
+			LLAvatarActions::removeFriendDialog(userID);
+		}
+		else if("invite_to_group" == command)
+		{
+			LLAvatarActions::inviteToGroup(userID);
+		}
+		else if("map" == command)
+		{
+			LLAvatarActions::showOnMap(userID);
+		}
+		else if("share" == command)
+		{
+			LLAvatarActions::share(userID);
+		}
+		else if("pay" == command)
+		{
+			LLAvatarActions::pay(userID);
+		}
+		else if("block_unblock" == command)
+		{
+			LLAvatarActions::toggleBlock(userID);
+		}
+		else if("selected" == command || "mute_all" == command || "unmute_all" == command)
+		{
+			moderateVoice(command, userID);
+		}
+		else if ("toggle_allow_text_chat" == command)
+		{
+			toggleAllowTextChat(userID);
+		}
+	}
 }
 
 void LLIMFloaterContainer::doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS)
@@ -963,8 +972,8 @@ void LLIMFloaterContainer::doToSelectedGroup(const LLSD& userdata)
 bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
 {
     std::string item = userdata.asString();
-    uuid_vec_t mUUIDs;
-    getParticipantUUIDs(mUUIDs);
+	uuid_vec_t uuids;
+	getParticipantUUIDs(uuids);
 
     if(item == std::string("can_activate_group"))
     {
@@ -972,7 +981,7 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
     	return gAgent.getGroupID() != selected_group_id;
     }
 
-    if(mUUIDs.size() <= 0)
+	if(uuids.size() <= 0)
     {
         return false;
     }
@@ -982,7 +991,7 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
 
     if (item == std::string("can_block"))
     {
-        const LLUUID& id = mUUIDs.front();
+		const LLUUID& id = uuids.front();
         return LLAvatarActions::canBlock(id);
     }
     else if (item == std::string("can_add"))
@@ -992,7 +1001,7 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
         // - and there are no friends among selection yet.
 
         //EXT-7389 - disable for more than 1
-        if(mUUIDs.size() > 1)
+		if(uuids.size() > 1)
         {
             return false;
         }
@@ -1000,8 +1009,8 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
         bool result = true;
 
         uuid_vec_t::const_iterator
-            id = mUUIDs.begin(),
-            uuids_end = mUUIDs.end();
+			id = uuids.begin(),
+			uuids_end = uuids.end();
 
         for (;id != uuids_end; ++id)
         {
@@ -1020,11 +1029,11 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
         // - there are selected people
         // - and there are only friends among selection.
 
-        bool result = (mUUIDs.size() > 0);
+        bool result = (uuids.size() > 0);
 
         uuid_vec_t::const_iterator
-            id = mUUIDs.begin(),
-            uuids_end = mUUIDs.end();
+			id = uuids.begin(),
+			uuids_end = uuids.end();
 
         for (;id != uuids_end; ++id)
         {
@@ -1043,15 +1052,20 @@ bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
     }
     else if (item == std::string("can_show_on_map"))
     {
-        const LLUUID& id = mUUIDs.front();
+		const LLUUID& id = uuids.front();
 
         return (LLAvatarTracker::instance().isBuddyOnline(id) && is_agent_mappable(id))
             || gAgent.isGodlike();
     }
     else if(item == std::string("can_offer_teleport"))
     {
-        return LLAvatarActions::canOfferTeleport(mUUIDs);
+		return LLAvatarActions::canOfferTeleport(uuids);
     }
+	else if("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item)
+	{
+		return enableModerateContextMenuItem(item);
+	}
+
     return false;
 }
 
@@ -1063,10 +1077,19 @@ bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
 
     if(mUUIDs.size() > 0 )
     {
-    if (item == std::string("is_blocked"))
-    {
-            return LLAvatarActions::isBlocked(mUUIDs.front());
-        }
+		if ("is_blocked" == item)
+		{
+			return LLAvatarActions::isBlocked(mUUIDs.front());
+		}
+		else if ("is_allowed_text_chat" == item)
+		{
+			const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+
+			if (NULL != speakerp)
+			{
+				return !speakerp->mModeratorMutedText;
+			}
+		}
     }
 
     return false;
@@ -1284,4 +1307,189 @@ LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParti
 	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
 }
 
+bool LLIMFloaterContainer::enableModerateContextMenuItem(const std::string& userdata)
+{
+	// only group moderators can perform actions related to this "enable callback"
+	if (!isGroupModerator())
+	{
+		return false;
+	}
+
+	LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+	if (NULL == speakerp)
+	{
+		return false;
+	}
+
+	bool voice_channel = speakerp->isInVoiceChannel();
+
+	if ("can_moderate_voice" == userdata)
+	{
+		return voice_channel;
+	}
+	else if ("can_mute" == userdata)
+	{
+		return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+	else if ("can_unmute" == userdata)
+	{
+		return voice_channel && isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+
+	// The last invoke is used to check whether the "can_allow_text_chat" will enabled
+	return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
+}
+
+bool LLIMFloaterContainer::isGroupModerator()
+{
+	LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant();
+	if (NULL == speaker_manager)
+	{
+		llwarns << "Speaker manager is missing" << llendl;
+		return false;
+	}
+
+	// Is session a group call/chat?
+	if(gAgent.isInGroup(speaker_manager->getSessionID()))
+	{
+		LLSpeaker * speaker = speaker_manager->findSpeaker(gAgentID).get();
+
+		// Is agent a moderator?
+		return speaker && speaker->mIsModerator;
+	}
+
+	return false;
+}
+
+void LLIMFloaterContainer::moderateVoice(const std::string& command, const LLUUID& userID)
+{
+	if (!gAgent.getRegion()) return;
+
+	if (command.compare("selected"))
+	{
+		moderateVoiceAllParticipants(command.compare("mute_all"));
+	}
+	else
+	{
+		moderateVoiceParticipant(userID, isMuted(userID));
+	}
+}
+
+bool LLIMFloaterContainer::isMuted(const LLUUID& avatar_id)
+{
+	const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+	return NULL == speakerp ? true : speakerp->mStatus == LLSpeaker::STATUS_MUTED;
+}
+
+void LLIMFloaterContainer::moderateVoiceAllParticipants(bool unmute)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
+
+	if (NULL != speaker_managerp)
+	{
+		if (!unmute)
+		{
+			LLSD payload;
+			payload["session_id"] = speaker_managerp->getSessionID();
+			LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
+			return;
+		}
+
+		speaker_managerp->moderateVoiceAllParticipants(unmute);
+	}
+}
+
+// static
+void LLIMFloaterContainer::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	// if Cancel pressed
+	if (option == 1)
+	{
+		return;
+	}
+
+	const LLSD& payload = notification["payload"];
+	const LLUUID& session_id = payload["session_id"];
+
+	LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
+		LLIMModel::getInstance()->getSpeakerManager(session_id));
+	if (speaker_manager)
+	{
+		speaker_manager->moderateVoiceAllParticipants(false);
+	}
+
+	return;
+}
+
+void LLIMFloaterContainer::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr *>(getSpeakerMgrForSelectedParticipant());
+
+	if (NULL != speaker_managerp)
+	{
+		speaker_managerp->moderateVoiceParticipant(avatar_id, unmute);
+	}
+}
+
+LLSpeakerMgr * LLIMFloaterContainer::getSpeakerMgrForSelectedParticipant()
+{
+	LLFolderViewItem * selected_folder_itemp = mConversationsRoot->getCurSelectedItem();
+	if (NULL == selected_folder_itemp)
+	{
+		llwarns << "Current selected item is null" << llendl;
+		return NULL;
+	}
+
+	LLFolderViewFolder * conversation_itemp = selected_folder_itemp->getParentFolder();
+
+	conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin();
+	conversations_widgets_map::const_iterator end = mConversationsWidgets.end();
+	const LLUUID * conversation_uuidp = NULL;
+	while(iter != end)
+	{
+		if (iter->second == conversation_itemp)
+		{
+			conversation_uuidp = &iter->first;
+			break;
+		}
+		++iter;
+	}
+	if (NULL == conversation_uuidp)
+	{
+		llwarns << "Cannot find conversation item widget" << llendl;
+		return NULL;
+	}
+
+	return conversation_uuidp->isNull() ? (LLSpeakerMgr *)LLLocalSpeakerMgr::getInstance()
+		: LLIMModel::getInstance()->getSpeakerManager(*conversation_uuidp);
+}
+
+LLSpeaker * LLIMFloaterContainer::getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp)
+{
+	if (NULL == speaker_managerp)
+	{
+		llwarns << "Speaker manager is missing" << llendl;
+		return NULL;
+	}
+
+	const LLConversationItem * participant_itemp = getCurSelectedViewModelItem();
+	if (NULL == participant_itemp)
+	{
+		llwarns << "Cannot evaluate current selected view model item" << llendl;
+		return NULL;
+	}
+
+	return speaker_managerp->findSpeaker(participant_itemp->getUUID());
+}
+
+void LLIMFloaterContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
+	if (NULL != speaker_managerp)
+	{
+		speaker_managerp->toggleAllowTextChat(participant_uuid);
+	}
+}
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 579f62c688..ba2d085858 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -45,6 +45,8 @@ class LLLayoutPanel;
 class LLLayoutStack;
 class LLTabContainer;
 class LLIMFloaterContainer;
+class LLSpeaker;
+class LLSpeakerMgr;
 
 class LLIMFloaterContainer
 	: public LLMultiFloater
@@ -126,6 +128,17 @@ private:
     bool checkContextMenuItem(const LLSD& userdata);
     bool enableContextMenuItem(const LLSD& userdata);
 
+	static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
+	bool enableModerateContextMenuItem(const std::string& userdata);
+	LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp);
+	LLSpeakerMgr * getSpeakerMgrForSelectedParticipant();
+	bool isGroupModerator();
+	bool isMuted(const LLUUID& avatar_id);
+	void moderateVoice(const std::string& command, const LLUUID& userID);
+	void moderateVoiceAllParticipants(bool unmute);
+	void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
+	void toggleAllowTextChat(const LLUUID& participant_uuid);
+
 	LLButton* mExpandCollapseBtn;
 	LLLayoutPanel* mMessagesPane;
 	LLLayoutPanel* mConversationsPane;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 139713b96e..28c2edbe84 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -577,7 +577,7 @@ void hide_context_entries(LLMenuGL& menu,
 
 		// descend into split menus:
 		LLMenuItemBranchGL* branchp = dynamic_cast<LLMenuItemBranchGL*>(menu_item);
-		if ((name == "More") && branchp)
+		if (NULL != branchp)
 		{
 			hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries);
 		}
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 90226e7fba..b263143bd1 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -213,7 +213,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 	LLConversationItemSession(data_source->getSessionID(), root_view_model),
 	mSpeakerMgr(data_source),
 	mAvatarList(avatar_list),
-	mParticipantListMenu(NULL),
 	mExcludeAgent(exclude_agent),
 	mValidateSpeakerCallback(NULL)
 {
@@ -248,8 +247,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 
 		if (use_context_menu)
 		{
-			//mParticipantListMenu = new LLParticipantListMenu(*this);
-			//mAvatarList->setContextMenu(mParticipantListMenu);
 			mAvatarList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
 		}
 		else
@@ -316,20 +313,6 @@ LLParticipantList::~LLParticipantList()
 		mAvatarListToggleIconsConnection.disconnect();
 	}
 
-	// It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged()
-	// See ticket EXT-3427
-	// hide menu before deleting it to stop enable and check handlers from triggering.
-	if(mParticipantListMenu && !LLApp::isExiting())
-	{
-		mParticipantListMenu->hide();
-	}
-
-	if (mParticipantListMenu)
-	{
-		delete mParticipantListMenu;
-		mParticipantListMenu = NULL;
-	}
-
 	if (mAvatarList)
 	{
 		mAvatarList->setContextMenu(NULL);
@@ -786,350 +769,6 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::
 	return mParent.onSpeakerMuteEvent(event, userdata);
 }
 
-/*LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
-{
-	// set up the callbacks for all of the avatar menu items
-	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));
-
-	registrar.add("Avatar.Profile",	boost::bind(&LLAvatarActions::showProfile, mUUIDs.front()));
-	registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, mUUIDs.front()));
-	registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs.front()));
-	registrar.add("Avatar.BlockUnblock", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteVoice, this, _2));
-	registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, mUUIDs.front()));
-	registrar.add("Avatar.Pay",	boost::bind(&LLAvatarActions::pay, mUUIDs.front()));
-	registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, mUUIDs.front()));
-
-	registrar.add("ParticipantList.ModerateVoice", boost::bind(&LLParticipantList::LLParticipantListMenu::moderateVoice, this, _2));
-
-	enable_registrar.add("ParticipantList.EnableItem", boost::bind(&LLParticipantList::LLParticipantListMenu::enableContextMenuItem,	this, _2));
-	enable_registrar.add("ParticipantList.EnableItem.Moderate", boost::bind(&LLParticipantList::LLParticipantListMenu::enableModerateContextMenuItem,	this, _2));
-	enable_registrar.add("ParticipantList.CheckItem",  boost::bind(&LLParticipantList::LLParticipantListMenu::checkContextMenuItem,	this, _2));
-
-	// create the context menu from the XUI
-	LLContextMenu* main_menu = createFromFile("menu_participant_list.xml");
-
-	// Don't show sort options for P2P chat
-	bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
-	main_menu->setItemVisible("SortByName", is_sort_visible);
-	main_menu->setItemVisible("SortByRecentSpeakers", is_sort_visible);
-	main_menu->setItemVisible("Moderator Options Separator", isGroupModerator());
-	main_menu->setItemVisible("Moderator Options", isGroupModerator());
-	main_menu->setItemVisible("View Icons Separator", mParent.mAvatarListToggleIconsConnection.connected());
-	main_menu->setItemVisible("View Icons", mParent.mAvatarListToggleIconsConnection.connected());
-	main_menu->arrangeAndClear();
-
-	return main_menu;
-}*/
-
-void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y)
-{
-	if (uuids.size() == 0) return;
-
-	LLListContextMenu::show(spawning_view, uuids, x, y);
-
-	const LLUUID& speaker_id = mUUIDs.front();
-	BOOL is_muted = isMuted(speaker_id);
-
-	if (is_muted)
-	{
-		LLMenuGL::sMenuContainer->getChildView("ModerateVoiceMuteSelected")->setVisible( false);
-	}
-	else
-	{
-		LLMenuGL::sMenuContainer->getChildView("ModerateVoiceUnMuteSelected")->setVisible( false);
-	}
-}
-
-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)
-{
-
-	LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
-	if (mgr)
-	{
-		const LLUUID speaker_id = mUUIDs.front();
-		mgr->toggleAllowTextChat(speaker_id);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata, U32 flags)
-{
-	const LLUUID speaker_id = mUUIDs.front();
-	BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, flags);
-	std::string name;
-
-	//fill in name using voice client's copy of name cache
-	LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(speaker_id);
-	if (speakerp.isNull())
-	{
-		LL_WARNS("Speakers") << "Speaker " << speaker_id << " not found" << llendl;
-		return;
-	}
-	LLAvatarListItem* item = (mParent.mAvatarList ? dynamic_cast<LLAvatarListItem*>(mParent.mAvatarList->getItemByValue(speaker_id)) : NULL);
-	if (NULL == item) return;
-
-	name = item->getAvatarName();
-
-	LLMute::EType mute_type;
-	switch (speakerp->mType)
-	{
-		case LLSpeaker::SPEAKER_AGENT:
-			mute_type = LLMute::AGENT;
-			break;
-		case LLSpeaker::SPEAKER_OBJECT:
-			mute_type = LLMute::OBJECT;
-			break;
-		case LLSpeaker::SPEAKER_EXTERNAL:
-		default:
-			mute_type = LLMute::EXTERNAL;
-			break;
-	}
-	LLMute mute(speaker_id, name, mute_type);
-
-	if (!is_muted)
-	{
-		LLMuteList::getInstance()->add(mute, flags);
-	}
-	else
-	{
-		LLMuteList::getInstance()->remove(mute, flags);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMuteText(const LLSD& userdata)
-{
-	toggleMute(userdata, LLMute::flagTextChat);
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMuteVoice(const LLSD& userdata)
-{
-	toggleMute(userdata, LLMute::flagVoiceChat);
-}
-
-bool LLParticipantList::LLParticipantListMenu::isGroupModerator()
-{
-	if (!mParent.mSpeakerMgr)
-	{
-		llwarns << "Speaker manager is missing" << llendl;
-		return false;
-	}
-
-	// Is session a group call/chat?
-	if(gAgent.isInGroup(mParent.mSpeakerMgr->getSessionID()))
-	{
-		LLSpeaker* speaker = mParent.mSpeakerMgr->findSpeaker(gAgentID).get();
-
-		// Is agent a moderator?
-		return speaker && speaker->mIsModerator;
-	}
-	return false;
-}
-
-bool LLParticipantList::LLParticipantListMenu::isMuted(const LLUUID& avatar_id)
-{
-	LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id);
-	if (!selected_speakerp) return true;
-
-	return selected_speakerp->mStatus == LLSpeaker::STATUS_MUTED;
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdata)
-{
-	if (!gAgent.getRegion()) return;
-
-	bool moderate_selected = userdata.asString() == "selected";
-
-	if (moderate_selected)
-	{
-		const LLUUID& selected_avatar_id = mUUIDs.front();
-		bool is_muted = isMuted(selected_avatar_id);
-		moderateVoiceParticipant(selected_avatar_id, is_muted);
-	}
-	else
-	{
-		bool unmute_all = userdata.asString() == "unmute_all";
-		moderateVoiceAllParticipants(unmute_all);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
-{
-	LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
-	if (mgr)
-	{
-		mgr->moderateVoiceParticipant(avatar_id, unmute);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoiceAllParticipants(bool unmute)
-{
-	LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
-	if (mgr)
-	{
-		if (!unmute)
-		{
-			LLSD payload;
-			payload["session_id"] = mgr->getSessionID();
-			LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
-			return;
-		}
-
-		mgr->moderateVoiceAllParticipants(unmute);
-	}
-}
-
-// static
-void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	// if Cancel pressed
-	if (option == 1)
-	{
-		return;
-	}
-
-	const LLSD& payload = notification["payload"];
-	const LLUUID& session_id = payload["session_id"];
-
-	LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
-		LLIMModel::getInstance()->getSpeakerManager(session_id));
-	if (speaker_manager)
-	{
-		speaker_manager->moderateVoiceAllParticipants(false);
-	}
-
-	return;
-}
-
-
-bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-	const LLUUID& participant_id = mUUIDs.front();
-
-	// For now non of "can_view_profile" action and menu actions listed below except "can_block"
-	// can be performed for Avaline callers.
-	bool is_participant_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(participant_id);
-	if (!is_participant_avatar && "can_block" != item) return false;
-
-	if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item 
-		|| "can_pay" == item)
-	{
-		return mUUIDs.front() != gAgentID;
-	}
-	else if (item == std::string("can_add"))
-	{
-		// We can add friends if:
-		// - there are selected people
-		// - and there are no friends among selection yet.
-
-		bool result = (mUUIDs.size() > 0);
-
-		uuid_vec_t::const_iterator
-			id = mUUIDs.begin(),
-			uuids_end = mUUIDs.end();
-
-		for (;id != uuids_end; ++id)
-		{
-			if ( *id == gAgentID || LLAvatarActions::isFriend(*id) )
-			{
-				result = false;
-				break;
-			}
-		}
-		return result;
-	}
-	else if (item == "can_call")
-	{
-		bool not_agent = mUUIDs.front() != gAgentID;
-		bool can_call = not_agent &&  LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
-		return can_call;
-	}
-
-	return true;
-}
-
-/*
-  Processed menu items with such parameters:
-  can_allow_text_chat
-  can_moderate_voice
-*/
-bool LLParticipantList::LLParticipantListMenu::enableModerateContextMenuItem(const LLSD& userdata)
-{
-	// only group moderators can perform actions related to this "enable callback"
-	if (!isGroupModerator()) return false;
-
-	const LLUUID& participant_id = mUUIDs.front();
-	LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(participant_id);
-
-	// not in voice participants can not be moderated
-	bool speaker_in_voice = speakerp.notNull() && speakerp->isInVoiceChannel();
-
-	const std::string& item = userdata.asString();
-
-	if ("can_moderate_voice" == item)
-	{
-		return speaker_in_voice;
-	}
-
-	// For now non of menu actions except "can_moderate_voice" can be performed for Avaline callers.
-	bool is_participant_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(participant_id);
-	if (!is_participant_avatar) return false;
-
-	return true;
-}
-
-bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-	const LLUUID& id = mUUIDs.front();
-
-	if (item == "is_muted")
-	{
-		return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat);
-	}
-	else if (item == "is_allowed_text_chat")
-	{
-		LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id);
-
-		if (selected_speakerp.notNull())
-		{
-			return !selected_speakerp->mModeratorMutedText;
-		}
-	}
-	else if(item == "is_blocked")
-	{
-		return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
-	}
-	else if(item == "is_sorted_by_name")
-	{
-		return E_SORT_BY_NAME == mParent.getSortOrder();
-	}
-	else if(item == "is_sorted_by_recent_speakers")
-	{
-		return E_SORT_BY_RECENT_SPEAKERS == mParent.getSortOrder();
-	}
-
-	return false;
-}
-
 bool LLParticipantList::LLAvatarItemRecentSpeakerComparator::doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const
 {
 	if (mParent.mSpeakerMgr)
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index acee68873c..aaf1e070a5 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -159,79 +159,6 @@ protected:
 		/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	};
 
-	/**
-	 * Menu used in the participant list.
-	 */
-	class LLParticipantListMenu : public LLListContextMenu
-	{
-	public:
-		LLParticipantListMenu(LLParticipantList& parent):mParent(parent){};
-		/*virtual*/ LLContextMenu* createMenu();
-		/*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
-	protected:
-		LLParticipantList& mParent;
-	private:
-		bool enableContextMenuItem(const LLSD& userdata);
-		bool enableModerateContextMenuItem(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);
-		void toggleMuteVoice(const LLSD& userdata);
-		
-		/**
-		 * Return true if Agent is group moderator(and moderator of group call).
-		 */
-		bool isGroupModerator();
-
-		// Voice moderation support
-		/**
-		 * Check whether specified by argument avatar is muted for group chat or not.
-		 */
-		bool isMuted(const LLUUID& avatar_id);
-
-		/**
-		 * Processes Voice moderation menu items.
-		 *
-		 * It calls either moderateVoiceParticipant() or moderateVoiceParticipant() depend on
-		 * passed parameter.
-		 *
-		 * @param userdata can be "selected" or "others".
-		 *
-		 * @see moderateVoiceParticipant()
-		 * @see moderateVoiceAllParticipants()
-		 */
-		void moderateVoice(const LLSD& userdata);
-
-		/**
-		 * Mutes/Unmutes avatar for current group voice chat.
-		 *
-		 * It only marks avatar as muted for session and does not use local Agent's Block list.
-		 * It does not mute Agent itself.
-		 *
-		 * @param[in] avatar_id UUID of avatar to be processed
-		 * @param[in] unmute if true - specified avatar will be muted, otherwise - unmuted.
-		 *
-		 * @see moderateVoiceAllParticipants()
-		 */
-		void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
-
-		/**
-		 * Mutes/Unmutes all avatars for current group voice chat.
-		 *
-		 * It only marks avatars as muted for session and does not use local Agent's Block list.
-		 *
-		 * @param[in] unmute if true - avatars will be muted, otherwise - unmuted.
-		 *
-		 * @see moderateVoiceParticipant()
-		 */
-		void moderateVoiceAllParticipants(bool unmute);
-
-		static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
-	};
-
 	/**
 	 * Comparator for comparing avatar items by last spoken time
 	 */
@@ -276,8 +203,6 @@ private:
 	LLPointer<SpeakerModeratorUpdateListener>	mSpeakerModeratorListener;
 	LLPointer<SpeakerMuteListener>				mSpeakerMuteListener;
 
-	LLParticipantListMenu*    mParticipantListMenu;
-
 	/**
 	 * This field manages an adding  a new avatar_id in the mAvatarList
 	 * If true, then agent_id wont  be added into mAvatarList
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 682d70e4f0..2e9bda5804 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -125,4 +125,49 @@
      name="leave_group">
         <on_click function="Group.DoToSelected" parameter="leave_group"/>
     </menu_item_call>
+	<menu_item_separator
+	 layout="topleft"
+	 name="Moderator Options Separator"/>
+	<context_menu
+	 label="Moderator Options"
+	 layout="topleft"
+	 name="Moderator Options">
+		<menu_item_check
+		 label="Allow text chat"
+		 layout="topleft"
+		 name="AllowTextChat">
+			<on_check function="Avatar.CheckItem" parameter="is_allowed_text_chat" />
+			<on_click function="Avatar.DoToSelected" parameter="toggle_allow_text_chat" />
+			<on_enable function="Avatar.EnableItem" parameter="can_allow_text_chat" />
+		</menu_item_check>
+		<menu_item_separator layout="topleft" name="moderate_voice_separator" />
+		<menu_item_call
+		 label="Mute this participant"
+		 layout="topleft"
+		 name="ModerateVoiceMuteSelected">
+			<on_click function="Avatar.DoToSelected" parameter="selected" />
+			<on_enable function="Avatar.EnableItem" parameter="can_mute" />
+		</menu_item_call>
+		<menu_item_call
+		 label="Unmute this participant"
+		 layout="topleft"
+		 name="ModerateVoiceUnMuteSelected">
+			<on_click function="Avatar.DoToSelected" parameter="selected" />
+			<on_enable function="Avatar.EnableItem" parameter="can_unmute" />
+		</menu_item_call>
+		<menu_item_call
+		 label="Mute everyone"
+		 layout="topleft"
+		 name="ModerateVoiceMute">
+			<on_click function="Avatar.DoToSelected" parameter="mute_all" />
+			<on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
+		</menu_item_call>
+		<menu_item_call
+		 label="Unmute everyone"
+		 layout="topleft"
+		 name="ModerateVoiceUnmute">
+			<on_click function="Avatar.DoToSelected" parameter="unmute_all" />
+			<on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
+		</menu_item_call>
+	</context_menu>
 </toggleable_menu>
-- 
cgit v1.2.3


From 30a04430df02c6f3e949af0e457fe4ed49474ee3 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 17 Oct 2012 19:16:13 +0300
Subject: CHUI-419 FIXED Selecting the drop down arrow to list participants for
 a conversation does not select that conversation

---
 indra/newview/llconversationview.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 1b450665b3..9144f402b4 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -222,6 +222,13 @@ void LLConversationViewSession::toggleOpen()
 	if (!mMinimizedMode)
 	{
 		LLFolderViewFolder::toggleOpen();
+
+		// do item's selection when opened
+		if (LLFolderViewFolder::isOpen())
+		{
+			getParentFolder()->setSelection(this, true);
+		}
+		
 	}
 }
 
-- 
cgit v1.2.3


From d60609e0096bc7ede9edde1ba6d103f5f860af0d Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 17 Oct 2012 12:26:40 -0700
Subject: MAINT-1551 : WIP : More tests to elicit a correct answer from the
 backbone server

---
 indra/newview/llimview.cpp   |  1 +
 indra/newview/llspeakers.cpp | 52 +++++++++++++++++++++++++++++++++++---------
 indra/newview/llspeakers.h   |  2 ++
 3 files changed, 45 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 398584e005..e6f93aa9be 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -238,6 +238,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 
 	//we need to wait for session initialization for outgoing ad-hoc and group chat session
 	//correct session id for initiated ad-hoc chat will be received from the server
+	// Merov : MAINT-1551 : We need to read that mInitialTargetIDs when initializing the conversation
 	if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, 
 		mInitialTargetIDs, mType))
 	{
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 11d1b563ac..217efdf4af 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -307,7 +307,7 @@ public:
 	
 	virtual void error(U32 status, const std::string& reason)
 	{
-		llinfos << "Merov debug : UpdateResponder error, status = " << status << ": " << reason << llendl;
+		llinfos << "Merov debug : UpdateResponder error, on " << mSessionID << ", status = " << status << ": " << reason << llendl;
 	}
 	
 private:
@@ -322,8 +322,11 @@ LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) :
 	mVoiceChannel(channelp)
 , mVoiceModerated(false)
 , mModerateModeHandledFirstTime(false)
+, mSessionUpdated(false)
+, mSessionID()
 {
 	static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
+//	mSessionID = getSessionID();
 
 	mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay);
 }
@@ -547,7 +550,7 @@ void LLSpeakerMgr::updateSpeakerList()
 		LLUUID session_id = getSessionID();
 		if ((mSpeakers.size() == 0) && (!session_id.isNull()))
 		{
-			llinfos << "Merov debug : LLSpeakerMgr::updateSpeakerList: No speakers in " << session_id << llendl;
+			//llinfos << "Merov debug : LLSpeakerMgr::updateSpeakerList: No speakers in " << session_id << llendl;
 			// MAINT-1551 : If the list is empty for too long, we should send a message to the sim so that
 			// it sends the participant list again.
 			updateSession();
@@ -557,21 +560,50 @@ void LLSpeakerMgr::updateSpeakerList()
 
 void LLSpeakerMgr::updateSession()
 {
+	// We perform this update if is has never been done or if the session id changed (which happens in ad-hoc sessions)
+	if (mSessionUpdated && (mSessionID == getSessionID()))
+		return;
+	
 	std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
 	LLSD data;
-	data["method"] = "accept invitation";
-//	data["method"] = "session update";
+
+// That doesn't work apparently because we are not in the invite list so we get error 500
+//	data["method"] = "accept invitation";
+//	data["session-id"] = getSessionID();
+
+// That doesn't work because we're not a moderator on an IM session so our request is rejected as such	(error 403)
+	data["method"] = "session update";
+	data["session-id"] = getSessionID();
+	data["params"] = LLSD::emptyMap();	
+	data["params"]["update_info"] = LLSD::emptyMap();
+	data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap();
+	data["params"]["update_info"]["moderated_mode"]["voice"] = false;
+
+// That doesn't work, we eventually time out (error 502)...
+//	data["method"] = "call";
+//	data["session-id"] = getSessionID();
+
+	data["params"] = LLSD::emptyArray();
+//	for (int i = 0; i < count; i++)
+//	{
+//		data["params"].append(ids[i]);
+//	}
+	data["params"].append(gAgentID);
+	data["method"] = "invite";
 	data["session-id"] = getSessionID();
-//	data["params"] = LLSD::emptyMap();
-	
-//	data["params"]["update_info"] = LLSD::emptyMap();
-	
-//	data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap();
-//	data["params"]["update_info"]["moderated_mode"]["voice"] = false;
 	
 	llinfos << "Merov debug : viewer->sim : LLSpeakerMgr::updateSession, session id = " << getSessionID() << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 
 	LLHTTPClient::post(url, data, new UpdateResponder(getSessionID()));
+	
+	// bit of extra in the case of invite being sent
+	data.clear();
+	data["method"] = "accept invitation";
+	data["session-id"] = getSessionID();
+	LLHTTPClient::post(url, data, new UpdateResponder(getSessionID()));
+
+	mSessionUpdated = true;
+	mSessionID = getSessionID();
 }
 
 void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 671b3fb341..8a80c4619e 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -259,6 +259,8 @@ protected:
 	bool removeSpeaker(const LLUUID& speaker_id);
 
 	void updateSession();
+	bool mSessionUpdated;
+	LLUUID mSessionID;
 
 	typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
 	speaker_map_t		mSpeakers;
-- 
cgit v1.2.3


From 8a42d5cea3787edf294eec135af38c12ae322325 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 18 Oct 2012 00:04:46 +0300
Subject: CHUI-399 (When user has Pressing Letter Keys starts local chat
 setting on, first presses of letter keys do not open chat) fixed

---
 indra/newview/llviewerwindow.cpp | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 403288b2fd..f80abc816f 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2561,9 +2561,16 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	// If "Pressing letter keys starts local chat" option is selected, we are not in mouselook, 
 	// no view has keyboard focus, this is a printable character key (and no modifier key is 
 	// pressed except shift), then give focus to nearby chat (STORM-560)
-	if ( nearby_chat && gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&
-		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
-	{
+	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() &&
+		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
+	{
+		// Initialize nearby chat if it's missing
+		if (!nearby_chat)
+		{	
+			LLSD name("im_container");
+			LLFloaterReg::toggleInstanceOrBringToFront(name);
+		}
+
 		LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")->getChatBox();
 		if (chat_editor)
 		{
-- 
cgit v1.2.3


From 05a72687d848c13754039f6e720a137827533fdb Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 17 Oct 2012 14:55:36 -0700
Subject: CHUI-410: Now when a converation floater is focused the default text
 'To <Some User>' displays only when the text input field is empty.

---
 indra/llui/llchatentry.cpp                         | 28 ++++++++++++++++++++++
 indra/llui/llchatentry.h                           |  5 ++++
 indra/llui/lltextbase.cpp                          | 20 ++++++++++++++--
 indra/llui/lltextbase.h                            |  4 +++-
 .../skins/default/xui/en/floater_im_session.xml    |  3 ++-
 5 files changed, 56 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index 2a6ccc3dc9..38e2a8106a 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -136,6 +136,34 @@ void LLChatEntry::updateHistory()
 	}
 }
 
+void LLChatEntry::beforeValueChange()
+{
+    if(this->getLength() == 0 && !mLabel.empty())
+    {
+        this->clearSegments();
+    }
+}
+
+void LLChatEntry::onValueChange(S32 start, S32 end)
+{
+    resetLabel();
+}
+
+BOOL LLChatEntry::useLabel()
+{
+    return !getLength() && !mLabel.empty();
+}
+
+void LLChatEntry::onFocusReceived()
+{
+
+}
+
+void LLChatEntry::onFocusLost()
+{
+
+}
+
 BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
 {
 	BOOL handled = FALSE;
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
index 10a4594e83..1f3fcf8945 100644
--- a/indra/llui/llchatentry.h
+++ b/indra/llui/llchatentry.h
@@ -54,11 +54,16 @@ protected:
 
 	friend class LLUICtrlFactory;
 	LLChatEntry(const Params& p);
+    /*virtual*/ void    beforeValueChange();
+    /*virtual*/ void    onValueChange(S32 start, S32 end);
+    /*virtual*/ BOOL    useLabel();
 
 public:
 
 	virtual void	draw();
 	virtual	void	onCommit();
+    /*virtual*/ void	onFocusReceived();
+    /*virtual*/ void	onFocusLost();
 
 	boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
 
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 98624f42b9..15856ae4ef 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -338,6 +338,11 @@ const LLStyle::Params& LLTextBase::getStyleParams()
 	return mStyle;
 }
 
+void LLTextBase::beforeValueChange()
+{
+
+}
+
 void LLTextBase::onValueChange(S32 start, S32 end)
 {
 }
@@ -530,7 +535,7 @@ void LLTextBase::drawText()
 	{
 		return;
 	}
-	else if (text_len <= 0 && !mLabel.empty() && !hasFocus())
+	else if (useLabel() == TRUE)
 	{
 		text_len = mLabel.getWString().length();
 	}
@@ -747,6 +752,8 @@ void LLTextBase::drawText()
 
 S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::segment_vec_t* segments )
 {
+    beforeValueChange();
+
 	S32 old_len = getLength();		// length() returns character length
 	S32 insert_len = wstr.length();
 
@@ -822,6 +829,8 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
 
 S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
 {
+
+    beforeValueChange();
 	segment_set_t::iterator seg_iter = getSegIterContaining(pos);
 	while(seg_iter != mSegments.end())
 	{
@@ -880,6 +889,8 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
 
 S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
 {
+    beforeValueChange();
+
 	if (pos > (S32)getLength())
 	{
 		return 0;
@@ -2048,7 +2059,7 @@ BOOL LLTextBase::setLabelArg(const std::string& key, const LLStringExplicit& tex
 
 void LLTextBase::resetLabel()
 {
-	if (!getLength() && !mLabel.empty() && !hasFocus())
+	if (useLabel() == TRUE)
 	{
 		clearSegments();
 
@@ -2061,6 +2072,11 @@ void LLTextBase::resetLabel()
 	}
 }
 
+BOOL LLTextBase::useLabel()
+{
+    return !getLength() && !mLabel.empty() && !hasFocus();
+}
+
 void LLTextBase::setFont(const LLFontGL* font)
 {
 	mFont = font;
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 79662ebd33..44b149d264 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -382,7 +382,7 @@ public:
 
 	/**
 	 * If label is set, draws text label (which is LLLabelTextSegment)
-	 * that is visible when no user text provided and has no focus
+	 * that is visible when no user text provided
 	 */
 	void					resetLabel();
 
@@ -501,7 +501,9 @@ protected:
 	LLTextBase(const Params &p);
 	virtual ~LLTextBase();
 	void							initFromParams(const Params& p);
+    virtual void					beforeValueChange();
 	virtual void					onValueChange(S32 start, S32 end);
+    virtual BOOL                    useLabel();
 
 	// draw methods
 	void							drawSelectionBackground(); // draws the black box behind the selected text
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 8cd0463de8..2b542595c5 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -255,11 +255,12 @@
              bottom="0"
              expand_lines_count="5"
              follows="left|right|bottom"
-	         font="SansSerifSmall"
+	           font="SansSerifSmall"
              visible="true"
              height="20"
              is_expandable="true"
              label="To"
+             text_tentative_color="TextFgTentativeColor"
              layout="bottomleft"
              name="chat_editor"
              max_length="1023"
-- 
cgit v1.2.3


From 3ee73ee98d31e572e284371074b7cd4744005a29 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 17 Oct 2012 15:26:51 -0700
Subject: warn-on-failure:unix-eol

---
 indra/newview/llviewerwindow.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 403288b2fd..11fe8fda26 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -283,7 +283,7 @@ private:
 	struct Line
 	{
 		Line(const std::string& in_text, S32 in_x, S32 in_y) : text(in_text), x(in_x), y(in_y) {}
-		std::string text;
+		std::string text; 
 		S32 x,y;
 	};
 
-- 
cgit v1.2.3


From 1006e2fd259d5f8136ca933eba8d57c8a980bf31 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 17 Oct 2012 17:14:44 -0700
Subject: CHUI-422 : Update the ad-hoc conversation with the known list of on
 line agents without waiting for server message (which often doesn't come...).

---
 indra/newview/llavataractions.cpp |  3 --
 indra/newview/lleventpoll.cpp     | 42 +++++++-----------
 indra/newview/llimview.cpp        |  3 +-
 indra/newview/llspeakers.cpp      | 92 ++++++---------------------------------
 indra/newview/llspeakers.h        |  4 --
 5 files changed, 32 insertions(+), 112 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 600df31c8b..7322b3bb0b 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -303,9 +303,6 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
 	}
 	
 	LLIMFloater::show(session_id);
-//	gIMMgr->processAgentListUpdates(session_id, LLSD());
-//	gIMMgr->startCall(session_id,LLVoiceChannel::OUTGOING_CALL);
-//	gIMMgr->endCall(session_id);
 	
 	make_ui_sound("UISndStartIM");
 }
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 27f79dda2c..4f4d9a40b4 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -37,7 +37,6 @@
 #include "llviewerregion.h"
 #include "message.h"
 #include "lltrans.h"
-#include "llsdserialize.h"
 
 namespace
 {
@@ -110,14 +109,14 @@ namespace
 		const std::string& pollURL, const LLHost& sender)
 	{
 		LLHTTPClient::ResponderPtr result = new LLEventPollResponder(pollURL, sender);
-		llinfos	<< "Merov debug : LLEventPollResponder::start <" << sCount << "> "
+		llinfos	<< "LLEventPollResponder::start <" << sCount << "> "
 				<< pollURL << llendl;
 		return result;
 	}
 
 	void LLEventPollResponder::stop()
 	{
-		llinfos	<< "Merov debug : LLEventPollResponder::stop	<" << mCount <<	"> "
+		llinfos	<< "LLEventPollResponder::stop	<" << mCount <<	"> "
 				<< mPollURL	<< llendl;
 		// there should	be a way to	stop a LLHTTPClient	request	in progress
 		mDone =	true;
@@ -135,17 +134,17 @@ namespace
 		LLViewerRegion *regionp = gAgent.getRegion();
 		if (!regionp)
 		{
-			llinfos << "Merov debug : LLEventPoll initialized before region is added." << llendl;
+			llerrs << "LLEventPoll initialized before region is added." << llendl;
 		}
 		mSender = sender.getIPandPort();
-		llinfos << "Merov debug : LLEventPoll initialized with sender " << mSender << llendl;
+		llinfos << "LLEventPoll initialized with sender " << mSender << llendl;
 		makeRequest();
 	}
 
 	LLEventPollResponder::~LLEventPollResponder()
 	{
 		stop();
-		llinfos <<	"Merov debug : LLEventPollResponder::~Impl <" <<	mCount << "> "
+		lldebugs <<	"LLEventPollResponder::~Impl <" <<	mCount << "> "
 				 <<	mPollURL <<	llendl;
 	}
 
@@ -155,13 +154,11 @@ namespace
 									const LLChannelDescriptors& channels,
 									const LLIOPipe::buffer_ptr_t& buffer)
 	{
-		llinfos << "Merov debug : LLEventPollResponder::completedRaw url <" << mPollURL << ">, status = " <<	status << ", reason = " <<	reason <<	llendl;
 		if (status == HTTP_BAD_GATEWAY)
 		{
 			// These errors are not parsable as LLSD, 
 			// which LLHTTPClient::Responder::completedRaw will try to do.
-			//completed(status, reason, LLSD());
-			error(status, reason);
+			completed(status, reason, LLSD());
 		}
 		else
 		{
@@ -175,12 +172,8 @@ namespace
 		request["ack"] = mAcknowledge;
 		request["done"]	= mDone;
 		
-		llinfos <<	"Merov debug : viewer->sim : LLEventPollResponder::makeRequest	<" << mCount 
-				<<	"> ack = " <<	LLSDXMLStreamer(mAcknowledge) 
-				<< ", error = " << mErrorCount
-				<< ", sender = " << mSender
-				<< ", url = " << mPollURL
-				<< ", done = " << mDone << llendl;
+		lldebugs <<	"LLEventPollResponder::makeRequest	<" << mCount <<	"> ack = "
+				 <<	LLSDXMLStreamer(mAcknowledge) << llendl;
 		LLHTTPClient::post(mPollURL, request, this);
 	}
 
@@ -190,16 +183,13 @@ namespace
 		LLSD message;
 		message["sender"] = mSender;
 		message["body"] = content["body"];
-		llinfos << "Merov debug : sim->viewer : LLEventPollResponder::handleMessage, msg_name = " << msg_name << ", message = " << LLSDOStreamer<LLSDNotationFormatter>(message) << llendl;
 		LLMessageSystem::dispatch(msg_name, message);
 	}
 
 	//virtual
 	void LLEventPollResponder::error(U32 status, const	std::string& reason)
 	{
-		llinfos << "Merov debug : LLEventPollResponder::error, status = " << status << ", reason = " << reason << llendl;
 		if (mDone) return;
-		llinfos << "Merov debug : LLEventPollResponder::error, status = " << status << ", reason = " << reason << llendl;
 
 		// A HTTP_BAD_GATEWAY (502) error is our standard timeout response
 		// we get this when there are no events.
@@ -217,11 +207,11 @@ namespace
 										+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
 									, this);
 
-			llinfos << "Merov debug : Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl;
+			llwarns << "Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl;
 		}
 		else
 		{
-			llinfos <<	"Merov debug : LLEventPollResponder::error: <" << mCount << "> got "
+			llwarns <<	"LLEventPollResponder::error: <" << mCount << "> got "
 					<<	status << ": " << reason
 					<<	(mDone ? " -- done"	: "") << llendl;
 			stop();
@@ -237,7 +227,7 @@ namespace
 			// continue running.
 			if(gAgent.getRegion() && gAgent.getRegion()->getHost().getIPandPort() == mSender)
 			{
-				llinfos << "Merov debug : Forcing disconnect due to stalled main region event poll."  << llendl;
+				llwarns << "Forcing disconnect due to stalled main region event poll."  << llendl;
 				LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
 			}
 		}
@@ -246,8 +236,8 @@ namespace
 	//virtual
 	void LLEventPollResponder::result(const LLSD& content)
 	{
-		llinfos <<	"Merov debug : LLEventPollResponder::result <" << mCount	<< "> "
-				 <<	(mDone ? " -- done"	: "") << ", content = " << LLSDOStreamer<LLSDNotationFormatter>(content) << llendl;
+		lldebugs <<	"LLEventPollResponder::result <" << mCount	<< ">"
+				 <<	(mDone ? " -- done"	: "") << llendl;
 		
 		if (mDone) return;
 
@@ -256,7 +246,7 @@ namespace
 		if (!content.get("events") ||
 			!content.get("id"))
 		{
-			llinfos << "Merov debug : received event poll with no events or id key" << llendl;
+			llwarns << "received event poll with no events or id key" << llendl;
 			makeRequest();
 			return;
 		}
@@ -266,11 +256,11 @@ namespace
 
 		if(mAcknowledge.isUndefined())
 		{
-			llinfos << "Merov debug : LLEventPollResponder: id undefined" << llendl;
+			llwarns << "LLEventPollResponder: id undefined" << llendl;
 		}
 		
 		// was llinfos but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
-		llinfos  << "Merov debug : LLEventPollResponder::completed <" <<	mCount << "> " << events.size() << "events (id "
+		lldebugs  << "LLEventPollResponder::completed <" <<	mCount << "> " << events.size() << "events (id "
 				 <<	LLSDXMLStreamer(mAcknowledge) << ")" << llendl;
 		
 		LLSD::array_const_iterator i = events.beginArray();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e6f93aa9be..b5f22731f1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -238,7 +238,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 
 	//we need to wait for session initialization for outgoing ad-hoc and group chat session
 	//correct session id for initiated ad-hoc chat will be received from the server
-	// Merov : MAINT-1551 : We need to read that mInitialTargetIDs when initializing the conversation
 	if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, 
 		mInitialTargetIDs, mType))
 	{
@@ -1301,6 +1300,7 @@ bool LLIMModel::sendStartSession(
 	else if ( dialog == IM_SESSION_CONFERENCE_START )
 	{
 		LLSD agents;
+		agents.append(gAgent.getID());
 		for (int i = 0; i < (S32) ids.size(); i++)
 		{
 			agents.append(ids[i]);
@@ -1319,6 +1319,7 @@ bool LLIMModel::sendStartSession(
 			data["params"] = agents;
 
 			llinfos << "Merov debug : viewer-> sim : LLIMModel::sendStartSession, session id = " << temp_session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
+			llinfos << "Merov debug : Extra info for LLIMModel::sendStartSession, other_participant_id = " << other_participant_id << ", agent id = " << gAgent.getID() << llendl;
 			LLHTTPClient::post(
 				url,
 				data,
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 217efdf4af..64477765e1 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -36,7 +36,6 @@
 #include "llviewerobjectlist.h"
 #include "llvoavatar.h"
 #include "llworld.h"
-#include "llsdserialize.h"
 
 const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
 const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
@@ -297,23 +296,6 @@ private:
 	LLUUID mSessionID;
 };
 
-class UpdateResponder : public LLHTTPClient::Responder
-{
-public:
-	UpdateResponder(const LLUUID& session_id)
-	{
-		mSessionID = session_id;
-	}
-	
-	virtual void error(U32 status, const std::string& reason)
-	{
-		llinfos << "Merov debug : UpdateResponder error, on " << mSessionID << ", status = " << status << ": " << reason << llendl;
-	}
-	
-private:
-	LLUUID mSessionID;
-};
-
 //
 // LLSpeakerMgr
 //
@@ -322,11 +304,8 @@ LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) :
 	mVoiceChannel(channelp)
 , mVoiceModerated(false)
 , mModerateModeHandledFirstTime(false)
-, mSessionUpdated(false)
-, mSessionID()
 {
 	static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
-//	mSessionID = getSessionID();
 
 	mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay);
 }
@@ -348,7 +327,6 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
 		mSpeakers.insert(std::make_pair(speakerp->mID, speakerp));
 		mSpeakersSorted.push_back(speakerp);
 		LL_DEBUGS("Speakers") << "Added speaker " << id << llendl;
-		//llinfos << "Merov debug : setSpeaker, add, id = " << id << ", name = " << name << llendl;
 		fireEvent(new LLSpeakerListChangeEvent(this, speakerp->mID), "add");
 	}
 	else
@@ -369,7 +347,6 @@ LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::strin
 		}
 		else
 		{
-			llinfos << "Merov debug : setSpeaker, speaker not found? id = " << id << ", name = " << name << llendl;
 			LL_WARNS("Speakers") << "Speaker " << id << " not found" << llendl;
 		}
 	}
@@ -550,62 +527,24 @@ void LLSpeakerMgr::updateSpeakerList()
 		LLUUID session_id = getSessionID();
 		if ((mSpeakers.size() == 0) && (!session_id.isNull()))
 		{
-			//llinfos << "Merov debug : LLSpeakerMgr::updateSpeakerList: No speakers in " << session_id << llendl;
-			// MAINT-1551 : If the list is empty for too long, we should send a message to the sim so that
-			// it sends the participant list again.
-			updateSession();
+			// If the list is empty, we update it with whatever was used to initiate the call so that it doesn't stay empty too long.
+			// *TODO: Fix the server side code that sometimes forgets to send back the list of agents after a chat started 
+			// (IOW, fix why we get no ChatterBoxSessionAgentListUpdates message after the initial ChatterBoxSessionStartReply)
+			LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
+			for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
+			{
+				// We only add avatars that are on line
+				if (LLAvatarTracker::instance().isBuddyOnline(*it))
+				{
+					setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+				}
+			}
+			// Also add the current agent
+			setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 		}
 	}
 }
 
-void LLSpeakerMgr::updateSession()
-{
-	// We perform this update if is has never been done or if the session id changed (which happens in ad-hoc sessions)
-	if (mSessionUpdated && (mSessionID == getSessionID()))
-		return;
-	
-	std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
-	LLSD data;
-
-// That doesn't work apparently because we are not in the invite list so we get error 500
-//	data["method"] = "accept invitation";
-//	data["session-id"] = getSessionID();
-
-// That doesn't work because we're not a moderator on an IM session so our request is rejected as such	(error 403)
-	data["method"] = "session update";
-	data["session-id"] = getSessionID();
-	data["params"] = LLSD::emptyMap();	
-	data["params"]["update_info"] = LLSD::emptyMap();
-	data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap();
-	data["params"]["update_info"]["moderated_mode"]["voice"] = false;
-
-// That doesn't work, we eventually time out (error 502)...
-//	data["method"] = "call";
-//	data["session-id"] = getSessionID();
-
-	data["params"] = LLSD::emptyArray();
-//	for (int i = 0; i < count; i++)
-//	{
-//		data["params"].append(ids[i]);
-//	}
-	data["params"].append(gAgentID);
-	data["method"] = "invite";
-	data["session-id"] = getSessionID();
-	
-	llinfos << "Merov debug : viewer->sim : LLSpeakerMgr::updateSession, session id = " << getSessionID() << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
-
-	LLHTTPClient::post(url, data, new UpdateResponder(getSessionID()));
-	
-	// bit of extra in the case of invite being sent
-	data.clear();
-	data["method"] = "accept invitation";
-	data["session-id"] = getSessionID();
-	LLHTTPClient::post(url, data, new UpdateResponder(getSessionID()));
-
-	mSessionUpdated = true;
-	mSessionID = getSessionID();
-}
-
 void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
 {
 	speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
@@ -872,7 +811,6 @@ void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
 	//current value represents ability to type, so invert
 	data["params"]["mute_info"]["text"] = !speakerp->mModeratorMutedText;
 
-	llinfos << "Merov debug : viewer->sim : LLIMSpeakerMgr::toggleAllowTextChat, session id = " << getSessionID() << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 	LLHTTPClient::post(url, data, new ModerationResponder(getSessionID()));
 }
 
@@ -897,7 +835,6 @@ void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmu
 	data["params"]["mute_info"] = LLSD::emptyMap();
 	data["params"]["mute_info"]["voice"] = !unmute;
 
-	llinfos << "Merov debug : viewer->sim : LLIMSpeakerMgr::moderateVoiceParticipant, session id = " << getSessionID() << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 	LLHTTPClient::post(
 		url,
 		data,
@@ -940,7 +877,6 @@ void LLIMSpeakerMgr::moderateVoiceSession(const LLUUID& session_id, bool disallo
 	data["params"]["update_info"]["moderated_mode"] = LLSD::emptyMap();
 	data["params"]["update_info"]["moderated_mode"]["voice"] = disallow_voice;
 
-	llinfos << "Merov debug : viewer->sim : LLIMSpeakerMgr::moderateVoiceSession, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 	LLHTTPClient::post(url, data, new ModerationResponder(session_id));
 }
 
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 8a80c4619e..8ab08661d3 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -258,10 +258,6 @@ protected:
 	void setSpeakerNotInChannel(LLSpeaker* speackerp);
 	bool removeSpeaker(const LLUUID& speaker_id);
 
-	void updateSession();
-	bool mSessionUpdated;
-	LLUUID mSessionID;
-
 	typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
 	speaker_map_t		mSpeakers;
 
-- 
cgit v1.2.3


From 1cd3c8408fb485792cf20a73156b0fd43f0d90cc Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 17 Oct 2012 17:45:29 -0700
Subject: CHUI-422 : Clean up of leftover traces and tests

---
 indra/newview/llimfloater.cpp    | 4 +---
 indra/newview/llimview.cpp       | 9 ---------
 indra/newview/llvoicechannel.cpp | 1 -
 3 files changed, 1 insertion(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 47e091a57c..467f48600a 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -59,7 +59,6 @@
 #include "llviewerchat.h"
 #include "llnotificationmanager.h"
 #include "llautoreplace.h"
-#include "llsdserialize.h"
 
 floater_showed_signal_t LLIMFloater::sIMFloaterShowedSignal;
 
@@ -1209,12 +1208,11 @@ BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 			}
 			data["method"] = "invite";
 			data["session-id"] = mSessionID;
-			llinfos << "Merov debug : viewer->sim :  LLIMFloater::inviteToSession, session id = " << mSessionID << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 			LLHTTPClient::post(url,	data,new LLSessionInviteResponder(mSessionID));
 		}
 		else
 		{
-			llinfos << "Merov debug : LLIMFloater::inviteToSession -"
+			llinfos << "LLIMFloater::inviteToSession -"
 					<< " no need to invite agents for "
 					<< mDialog << llendl;
 			// successful add, because everyone that needed to get added
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b5f22731f1..b45903835a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -63,7 +63,6 @@
 #include "lltoolbarview.h"
 #include "llviewercontrol.h"
 #include "llviewerparcelmgr.h"
-#include "llsdserialize.h"
 
 
 const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -1300,7 +1299,6 @@ bool LLIMModel::sendStartSession(
 	else if ( dialog == IM_SESSION_CONFERENCE_START )
 	{
 		LLSD agents;
-		agents.append(gAgent.getID());
 		for (int i = 0; i < (S32) ids.size(); i++)
 		{
 			agents.append(ids[i]);
@@ -1318,8 +1316,6 @@ bool LLIMModel::sendStartSession(
 
 			data["params"] = agents;
 
-			llinfos << "Merov debug : viewer-> sim : LLIMModel::sendStartSession, session id = " << temp_session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
-			llinfos << "Merov debug : Extra info for LLIMModel::sendStartSession, other_participant_id = " << other_participant_id << ", agent id = " << gAgent.getID() << llendl;
 			LLHTTPClient::post(
 				url,
 				data,
@@ -2257,7 +2253,6 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 				LLSD data;
 				data["method"] = "accept invitation";
 				data["session-id"] = session_id;
-				llinfos << "Merov debug : viewer-> sim : LLIncomingCallDialog::processCallResponse, accept, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 				LLHTTPClient::post(
 					url,
 					data,
@@ -2298,7 +2293,6 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 			LLSD data;
 			data["method"] = "decline invitation";
 			data["session-id"] = session_id;
-			llinfos << "Merov debug : viewer-> sim : LLIncomingCallDialog::processCallResponse, decline, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 			LLHTTPClient::post(
 				url,
 				data,
@@ -2352,7 +2346,6 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 				LLSD data;
 				data["method"] = "accept invitation";
 				data["session-id"] = session_id;
-				llinfos << "Merov debug : viewer-> sim : inviteUserResponse, accept, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 				LLHTTPClient::post(
 					url,
 					data,
@@ -2388,7 +2381,6 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 			LLSD data;
 			data["method"] = "decline invitation";
 			data["session-id"] = session_id;
-			llinfos << "Merov debug : viewer-> sim : inviteUserResponse, decline, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 			LLHTTPClient::post(
 				url,
 				data,
@@ -3353,7 +3345,6 @@ public:
 				LLSD data;
 				data["method"] = "accept invitation";
 				data["session-id"] = session_id;
-				llinfos << "Merov debug : viewer-> sim : LLViewerChatterBoxInvitation, session id = " << session_id << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 				LLHTTPClient::post(
 					url,
 					data,
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 62a43333dd..38f9bbc67f 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -540,7 +540,6 @@ void LLVoiceChannelGroup::getChannelInfo()
 		LLSD data;
 		data["method"] = "call";
 		data["session-id"] = mSessionID;
-		llinfos << "Merov debug : viewer-> sim : LLVoiceChannelGroup::getChannelInfo, session id = " << mSessionID << ", data = " << LLSDOStreamer<LLSDNotationFormatter>(data) << llendl;
 		LLHTTPClient::post(url,
 						   data,
 						   new LLVoiceCallCapResponder(mSessionID));
-- 
cgit v1.2.3


From 49ad7fd4b57cec635c557070be02556094e90ff6 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 17 Oct 2012 17:52:10 -0700
Subject: CHUI-410: Post code review submit, changed useLabel() to return bool
 instead of BOOL. Adjusted code accordingly.

---
 indra/llui/llchatentry.cpp | 3 ++-
 indra/llui/llchatentry.h   | 2 +-
 indra/llui/lltextbase.cpp  | 6 +++---
 indra/llui/lltextbase.h    | 2 +-
 4 files changed, 7 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index 38e2a8106a..8e9c6555c3 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -146,10 +146,11 @@ void LLChatEntry::beforeValueChange()
 
 void LLChatEntry::onValueChange(S32 start, S32 end)
 {
+    //Internally resetLabel() must meet a condition before it can reset the label
     resetLabel();
 }
 
-BOOL LLChatEntry::useLabel()
+bool LLChatEntry::useLabel()
 {
     return !getLength() && !mLabel.empty();
 }
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
index 1f3fcf8945..49181c8d78 100644
--- a/indra/llui/llchatentry.h
+++ b/indra/llui/llchatentry.h
@@ -56,7 +56,7 @@ protected:
 	LLChatEntry(const Params& p);
     /*virtual*/ void    beforeValueChange();
     /*virtual*/ void    onValueChange(S32 start, S32 end);
-    /*virtual*/ BOOL    useLabel();
+    /*virtual*/ bool    useLabel();
 
 public:
 
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 15856ae4ef..b827acb185 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -535,7 +535,7 @@ void LLTextBase::drawText()
 	{
 		return;
 	}
-	else if (useLabel() == TRUE)
+	else if (useLabel())
 	{
 		text_len = mLabel.getWString().length();
 	}
@@ -2059,7 +2059,7 @@ BOOL LLTextBase::setLabelArg(const std::string& key, const LLStringExplicit& tex
 
 void LLTextBase::resetLabel()
 {
-	if (useLabel() == TRUE)
+	if (useLabel())
 	{
 		clearSegments();
 
@@ -2072,7 +2072,7 @@ void LLTextBase::resetLabel()
 	}
 }
 
-BOOL LLTextBase::useLabel()
+bool LLTextBase::useLabel()
 {
     return !getLength() && !mLabel.empty() && !hasFocus();
 }
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 44b149d264..629b304b25 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -503,7 +503,7 @@ protected:
 	void							initFromParams(const Params& p);
     virtual void					beforeValueChange();
 	virtual void					onValueChange(S32 start, S32 end);
-    virtual BOOL                    useLabel();
+    virtual bool                    useLabel();
 
 	// draw methods
 	void							drawSelectionBackground(); // draws the black box behind the selected text
-- 
cgit v1.2.3


From e56145176875a09dc9e1524a47bcc1259582c896 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 17 Oct 2012 18:14:37 -0700
Subject: CHUI-422 : One last clean up

---
 indra/newview/llvoicechannel.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 38f9bbc67f..ceff75a0cc 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -35,7 +35,6 @@
 #include "llrecentpeople.h"
 #include "llviewercontrol.h"
 #include "llvoicechannel.h"
-#include "llsdserialize.h"
 
 
 LLVoiceChannel::voice_channel_map_t LLVoiceChannel::sVoiceChannelMap;
-- 
cgit v1.2.3


From c0b60841ce14a1c449ede17284d2aa6939322be3 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 18 Oct 2012 16:50:40 +0300
Subject: CHUI-412 (User restricted in resizing conversation floater width)
 fixed

---
 indra/newview/llimfloatercontainer.cpp | 33 +++++++++++----------------------
 1 file changed, 11 insertions(+), 22 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c9c7e94af9..8a6659667d 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -286,32 +286,21 @@ void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
 // virtual
 void LLIMFloaterContainer::computeResizeLimits(S32& new_min_width, S32& new_min_height)
 {
-	bool is_left_pane_expanded = !mConversationsPane->isCollapsed();
-	bool is_right_pane_expanded = !mMessagesPane->isCollapsed();
-
-	S32 conversations_pane_min_dim = mConversationsPane->getMinDim();
-
-	if (is_right_pane_expanded)
+	// possibly increase floater's minimum height according to children's minimums
+	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
 	{
-		S32 conversations_pane_width =
-				(is_left_pane_expanded ? gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") : conversations_pane_min_dim);
-
-		// possibly increase minimum size constraint due to children's minimums.
-		for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+		LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getPanelByIndex(tab_idx));
+		if (floaterp)
 		{
-			LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getPanelByIndex(tab_idx));
-			if (floaterp)
-			{
-				new_min_width = llmax(new_min_width,
-						floaterp->getMinWidth() + conversations_pane_width + LLPANEL_BORDER_WIDTH * 2);
-				new_min_height = llmax(new_min_height, floaterp->getMinHeight());
-			}
+			new_min_height = llmax(new_min_height, floaterp->getMinHeight());
 		}
 	}
-	else
-	{
-		new_min_width = conversations_pane_min_dim;
-	}
+
+	S32 conversations_pane_min_dim = mConversationsPane->getRelevantMinDim();
+	S32 messages_pane_min_dim = mMessagesPane->getRelevantMinDim();
+
+	// set floater's minimum width according to relevant minimal children's dimensionals
+	new_min_width = conversations_pane_min_dim + messages_pane_min_dim + LLPANEL_BORDER_WIDTH*2;
 }
 
 void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data)
-- 
cgit v1.2.3


From 36ea92678e028abb54e02c603b657dfa10c91da1 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 18 Oct 2012 11:44:52 -0700
Subject: CHUI-329: The text is now gray due to CHUI 410. The only change in
 this commit is that parenthesis surround the nearby chat text (Nearby chat).

---
 indra/newview/llimfloatercontainer.cpp | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c9c7e94af9..6edda76ad2 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1175,8 +1175,18 @@ void LLIMFloaterContainer::setNearbyDistances()
 void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
 {
 	bool is_nearby_chat = uuid.isNull();
-	
-	std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatTitle") : LLIMModel::instance().getName(uuid);
+	std::string display_name;
+
+    //Stores the display name for the conversation line item
+    if(is_nearby_chat)
+    {
+        //Adds parenthesis in code since these are independent of the translated string
+        display_name = "(" + LLTrans::getString("NearbyChatTitle") + ")";
+    }
+    else
+    {
+        display_name = LLIMModel::instance().getName(uuid);
+    }
 
 	// Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do)
 	// Note: this happens often, when reattaching a torn off conversation for instance
-- 
cgit v1.2.3


From 2301c7cff60eca879f605a3ee3f26b960597d8c3 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 18 Oct 2012 13:16:00 -0700
Subject: CHUI-329: Post code review commit, instead of hard coded the
 parenthesis, created a custom string in string.xml. The reasoning for this is
 because some languages may not use the parenthesis or perhaps even use
 brackets if needed...basically allows for flexibility.

---
 indra/newview/llimfloatercontainer.cpp         | 11 +----------
 indra/newview/skins/default/xui/en/strings.xml |  1 +
 2 files changed, 2 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 6edda76ad2..5d328bb283 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1175,18 +1175,9 @@ void LLIMFloaterContainer::setNearbyDistances()
 void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
 {
 	bool is_nearby_chat = uuid.isNull();
-	std::string display_name;
 
     //Stores the display name for the conversation line item
-    if(is_nearby_chat)
-    {
-        //Adds parenthesis in code since these are independent of the translated string
-        display_name = "(" + LLTrans::getString("NearbyChatTitle") + ")";
-    }
-    else
-    {
-        display_name = LLIMModel::instance().getName(uuid);
-    }
+	std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatLabel") : LLIMModel::instance().getName(uuid);
 
 	// Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do)
 	// Note: this happens often, when reattaching a torn off conversation for instance
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 696c282887..01da0a3686 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -385,6 +385,7 @@ Please try logging in again in a minute.</string>
 
 	<!-- Chat -->
 	<string name="NearbyChatTitle">Nearby chat</string>
+  <string name="NearbyChatLabel">(Nearby chat)</string>
 	<string name="whisper">whispers:</string>
 	<string name="shout">shouts:</string>
 	<string name="ringing">Connecting to in-world Voice Chat...</string>
-- 
cgit v1.2.3


From d840a60ecc9f7a9e1e9521dc63a79bc73267ed88 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 18 Oct 2012 21:49:02 -0700
Subject: CHUI-373 : Fix : Refresh panel after setting parcel for sale

---
 indra/newview/llfloaterland.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 4fc6684e8e..a5dd197336 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1045,6 +1045,8 @@ void LLPanelLandGeneral::onCommitAny(LLUICtrl *ctrl, void *userdata)
 void LLPanelLandGeneral::onClickSellLand(void* data)
 {
 	LLViewerParcelMgr::getInstance()->startSellLand();
+	LLPanelLandGeneral *panelp = (LLPanelLandGeneral *)data;
+	panelp->refresh();
 }
 
 // static
-- 
cgit v1.2.3


From 89ba6b793a5a8b3e0599cd2c8db2f1b479ec0fb4 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 19 Oct 2012 13:50:55 +0300
Subject: CHUI-418 FIXED Check the existence of mViewModelItem before calling
 potentiallyVisible().

---
 indra/llui/llfolderview.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index c1a11851e2..c8b8bcae48 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -504,7 +504,11 @@ void LLFolderView::sanitizeSelection()
 		LLFolderViewItem* item = *item_iter;
 
 		// ensure that each ancestor is open and potentially passes filtering
-		BOOL visible = item->getViewModelItem()->potentiallyVisible(); // initialize from filter state for this item
+		BOOL visible = false;
+		if(item->getViewModelItem())
+		{
+			visible = item->getViewModelItem()->potentiallyVisible(); // initialize from filter state for this item
+		}
 		// modify with parent open and filters states
 		LLFolderViewFolder* parent_folder = item->getParentFolder();
 		// Move up through parent folders and see what's visible
-- 
cgit v1.2.3


From 155cb976cb807771772b6bab62709709348c918b Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 19 Oct 2012 19:10:35 +0300
Subject: CHUI-416 FIXED Check if conversationItem is not NULL before calling
 getType().

---
 indra/newview/llimfloatercontainer.cpp | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c4eeccecbe..14ed0b3c3e 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -927,15 +927,18 @@ void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
     const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
     uuid_vec_t selected_uuids;
 
-    getParticipantUUIDs(selected_uuids);
-
-    if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
-    {
-        doToParticipants(command, selected_uuids);
-    }
-    else
+    if(conversationItem != NULL)
     {
-        doToSelectedConversation(command, selected_uuids);
+    	getParticipantUUIDs(selected_uuids);
+
+    	if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
+    	{
+    		doToParticipants(command, selected_uuids);
+    	}
+    	else
+    	{
+    		doToSelectedConversation(command, selected_uuids);
+    	}
     }
 }
 
-- 
cgit v1.2.3


From 2d0b6f033eadb4382da60ba7af913f743c7b0380 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 19 Oct 2012 13:32:23 -0700
Subject: CHUI-391: Replacing nearby chat icon.

---
 .../skins/default/textures/icons/nearby_chat_icon.png   | Bin 793 -> 553 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png
index 7c3ad40381..48c2379133 100644
Binary files a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png and b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png differ
-- 
cgit v1.2.3


From e6a7133ef1fa1760e0bfb53f5b14e7b6e76da0f5 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 19 Oct 2012 13:57:40 -0700
Subject: CHUI-422 : Add invited non buddies to the initial set of speakers

---
 indra/newview/llspeakers.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 64477765e1..46fd8c1290 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -533,8 +533,8 @@ void LLSpeakerMgr::updateSpeakerList()
 			LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
 			for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
 			{
-				// We only add avatars that are on line
-				if (LLAvatarTracker::instance().isBuddyOnline(*it))
+				// Allow to set buddies if they are on line. Allow any other avatar.
+				if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it))
 				{
 					setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 				}
-- 
cgit v1.2.3


From 0356ef61cf9f70b97dc78a59fba58465d99f5fc0 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 19 Oct 2012 16:21:35 -0700
Subject: CHUI-243: Add calls the parent class's implementation for
 onFocusReceived() and onFocusLost() to ensure that the focus change messages
 are properly propagated.

---
 indra/llui/lltextbase.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index b827acb185..8839afb60d 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1359,6 +1359,7 @@ void LLTextBase::onSpellCheckSettingsChange()
 
 void LLTextBase::onFocusReceived()
 {
+	LLUICtrl::onFocusReceived();
 	if (!getLength() && !mLabel.empty())
 	{
 		// delete label which is LLLabelTextSegment
@@ -1368,6 +1369,7 @@ void LLTextBase::onFocusReceived()
 
 void LLTextBase::onFocusLost()
 {
+	LLUICtrl::onFocusLost();
 	if (!getLength() && !mLabel.empty())
 	{
 		resetLabel();
-- 
cgit v1.2.3


From b0c54dfd3e2ecc8d4f875276397a55cef40a3d9a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 19 Oct 2012 17:47:28 -0700
Subject: CHUI-433: Problem: Toasts were not being displayed due to incorrect
 tracking of the current conversation with focus. Resolution: Now when a
 conversation gains focus it will set a flag to ignore toasts. And when a
 conversation loses focus it will set a flag to re-enable toasts.

---
 indra/newview/llimconversation.cpp | 13 ++++---------
 indra/newview/llimview.cpp         |  5 ++---
 2 files changed, 6 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index bd2a2419a8..f4b8d39cd0 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -202,16 +202,10 @@ void LLIMConversation::onFocusReceived()
 {
 	setBackgroundOpaque(true);
 
-	if (mSessionID.notNull())
+	if (mSessionID.notNull() && isInVisibleChain())
 	{
-		LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, true);
-
-		if (getVisible())
-		{
-			// suppress corresponding toast only if this floater is visible and have focus
-			LLIMModel::getInstance()->setActiveSessionID(mSessionID);
-			LLIMModel::instance().sendNoUnreadMessages(mSessionID);
-		}
+        LLIMModel::getInstance()->setActiveSessionID(mSessionID);
+		LLIMModel::instance().sendNoUnreadMessages(mSessionID);
 	}
 
 	LLTransientDockableFloater::onFocusReceived();
@@ -219,6 +213,7 @@ void LLIMConversation::onFocusReceived()
 
 void LLIMConversation::onFocusLost()
 {
+    LLIMModel::getInstance()->resetActiveSessionID();
 	setBackgroundOpaque(false);
 	LLTransientDockableFloater::onFocusLost();
 }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 115da54ec8..572f36ff7d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -119,8 +119,7 @@ void toast_callback(const LLSD& msg){
 	}
 
 	// check whether incoming IM belongs to an active session or not
-	if (LLIMModel::getInstance()->getActiveSessionID().notNull()
-			&& LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
+	if (LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
 	{
 		return;
 	}
@@ -147,7 +146,7 @@ void toast_callback(const LLSD& msg){
 
 	// Skip toasting if we have open window of IM with this session id
 	LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]);
-	if (open_im_floater && open_im_floater->getVisible())
+	if (open_im_floater && open_im_floater->isInVisibleChain() && open_im_floater->hasFocus())
 	{
 		return;
 	}
-- 
cgit v1.2.3


From 364e8118670f7ea80a1fa7187b23cc46ad2fc2f7 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 22 Oct 2012 04:35:31 +0300
Subject: CHUI-428 (Scroll conversation list to the newly created conversation)
 fixed

---
 indra/newview/llimfloatercontainer.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 14ed0b3c3e..cf4d054dd5 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1113,6 +1113,9 @@ void LLIMFloaterContainer::setItemSelect(const LLUUID& session_id)
             mSelectedSession = session_id;
             LLFolderViewItem* widget = mConversationsWidgets[session_id];
             (widget->getRoot())->setSelection(widget, FALSE, FALSE);
+
+			// Scroll to selected item
+			mConversationsRoot->scrollToShowSelection();
         }
     }
 }
@@ -1228,6 +1231,9 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWi
 	// set the widget to minimized mode if conversations pane is collapsed
 	widget->toggleMinimizedMode(mConversationsPane->isCollapsed());
 
+	// scroll to newly added item
+	mConversationsRoot->scrollToShowSelection();
+
 	return;
 }
 
-- 
cgit v1.2.3


From 0d25cca2e1e117962aad57dc951c102bec52cb50 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Mon, 22 Oct 2012 15:01:03 -0700
Subject: Backed out changeset: 4202e227f8e4

---
 indra/llui/llfloaterreg.cpp    |  2 +-
 indra/llui/llfloaterreg.h      | 24 ++++++++++++------------
 indra/newview/llnearbychat.cpp | 12 ++++++------
 3 files changed, 19 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 920525448c..9115eb7174 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -318,7 +318,7 @@ void LLFloaterReg::showInitialVisibleInstances()
 			BOOL isvis = LLFloater::getControlGroup()->getBOOL(controlname);
 			if (isvis)
 			{
-				showInstance(name, LLSD(LLUUID())); // keyed floaters shouldn't set save_vis to true
+				showInstance(name, LLSD()); // keyed floaters shouldn't set save_vis to true
 			}
 		}
 	}
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index 7924b2a7b8..a1e1f8a988 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -90,23 +90,23 @@ public:
 	static LLFloater* getLastFloaterCascading();
 	
 	// Find / get (create) / remove / destroy
-	static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
-	static LLFloater* getInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
-	static LLFloater* removeInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
-	static bool destroyInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
+	static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());
+	static LLFloater* getInstance(const std::string& name, const LLSD& key = LLSD());
+	static LLFloater* removeInstance(const std::string& name, const LLSD& key = LLSD());
+	static bool destroyInstance(const std::string& name, const LLSD& key = LLSD());
 	
 	// Iterators
 	static const_instance_list_t& getFloaterList(const std::string& name);
 
 	// Visibility Management
 	// return NULL if instance not found or can't create instance (no builder)
-	static LLFloater* showInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()), BOOL focus = FALSE);
+	static LLFloater* showInstance(const std::string& name, const LLSD& key = LLSD(), BOOL focus = FALSE);
 	// Close a floater (may destroy or set invisible)
 	// return false if can't find instance
-	static bool hideInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
+	static bool hideInstance(const std::string& name, const LLSD& key = LLSD());
 	// return true if instance is visible:
-	static bool toggleInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()));
-	static bool instanceVisible(const std::string& name, const LLSD& key = LLSD(LLUUID()));
+	static bool toggleInstance(const std::string& name, const LLSD& key = LLSD());
+	static bool instanceVisible(const std::string& name, const LLSD& key = LLSD());
 
 	static void showInitialVisibleInstances();
 	static void hideVisibleInstances(const std::set<std::string>& exceptions = std::set<std::string>());
@@ -126,23 +126,23 @@ public:
 	static void registerControlVariables();
 
 	// Callback wrappers
-	static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD(LLUUID()));
+	static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD());
 	
 	// Typed find / get / show
 	template <class T>
-	static T* findTypedInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()))
+	static T* findTypedInstance(const std::string& name, const LLSD& key = LLSD())
 	{
 		return dynamic_cast<T*>(findInstance(name, key));
 	}
 
 	template <class T>
-	static T* getTypedInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()))
+	static T* getTypedInstance(const std::string& name, const LLSD& key = LLSD())
 	{
 		return dynamic_cast<T*>(getInstance(name, key));
 	}
 
 	template <class T>
-	static T* showTypedInstance(const std::string& name, const LLSD& key = LLSD(LLUUID()), BOOL focus = FALSE)
+	static T* showTypedInstance(const std::string& name, const LLSD& key = LLSD(), BOOL focus = FALSE)
 	{
 		return dynamic_cast<T*>(showInstance(name, key, focus));
 	}
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a89ae4a2dc..5b274dd389 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -287,10 +287,10 @@ void	LLNearbyChat::setVisible(BOOL visible)
 {
 	LLIMConversation::setVisible(visible);
 
-    if(visible)
-    {
-        removeScreenChat();
-    }
+	if(visible)
+	{
+		removeScreenChat();
+	}
     setFocus(visible);
 }
 
@@ -327,7 +327,7 @@ void LLNearbyChat::addToHost()
 
 		mIsHostSet = true;
 	}
-}
+	}
 
 bool LLNearbyChat::isHostSet()
 {
@@ -722,7 +722,7 @@ void LLNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BO
 	send_chat_from_viewer(utf8_out_text, type, channel);
 }
 
-// static
+// static 
 bool LLNearbyChat::isWordsName(const std::string& name)
 {
 	// checking to see if it's display name plus username in parentheses
-- 
cgit v1.2.3


From 23d58c0c0906bd5434611cc73da9437ec7a5b830 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 22 Oct 2012 17:31:51 -0700
Subject: CHUI-433: Implemented an alternate solution to the problem. The
 original solution was ambiguous and incomplete and also preserved an existing
 hack. The new solution removes a hack/deprecated code
 (setActiveSession/getActiveSession functions). Basically, a toast message is
 not displayed if the user already has the conversation in focus. When the
 conversation floater loses focus toasts message will be displayed for that
 conversation.

---
 indra/newview/llimconversation.cpp          |  2 --
 indra/newview/llimview.cpp                  | 30 ++++++-----------------------
 indra/newview/llimview.h                    |  7 -------
 indra/newview/llnotificationhandlerutil.cpp | 17 ----------------
 4 files changed, 6 insertions(+), 50 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index f4b8d39cd0..74bf8cb6fe 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -204,7 +204,6 @@ void LLIMConversation::onFocusReceived()
 
 	if (mSessionID.notNull() && isInVisibleChain())
 	{
-        LLIMModel::getInstance()->setActiveSessionID(mSessionID);
 		LLIMModel::instance().sendNoUnreadMessages(mSessionID);
 	}
 
@@ -213,7 +212,6 @@ void LLIMConversation::onFocusReceived()
 
 void LLIMConversation::onFocusLost()
 {
-    LLIMModel::getInstance()->resetActiveSessionID();
 	setBackgroundOpaque(false);
 	LLTransientDockableFloater::onFocusLost();
 }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 572f36ff7d..4c5631d5e1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -118,11 +118,12 @@ void toast_callback(const LLSD& msg){
 		return;
 	}
 
-	// check whether incoming IM belongs to an active session or not
-	if (LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
-	{
-		return;
-	}
+    // Skip toasting if we have open window of IM with this session id
+    LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]);
+    if (open_im_floater && open_im_floater->isInVisibleChain() && open_im_floater->hasFocus())
+    {
+        return;
+    }
 
 	// Skip toasting for system messages
 	if (msg["from_id"].asUUID() == LLUUID::null)
@@ -144,30 +145,11 @@ void toast_callback(const LLSD& msg){
 		return;
 	}
 
-	// Skip toasting if we have open window of IM with this session id
-	LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]);
-	if (open_im_floater && open_im_floater->isInVisibleChain() && open_im_floater->hasFocus())
-	{
-		return;
-	}
-
 	LLAvatarNameCache::get(msg["from_id"].asUUID(),
 		boost::bind(&on_avatar_name_cache_toast,
 			_1, _2, msg));
 }
 
-void LLIMModel::setActiveSessionID(const LLUUID& session_id)
-{
-	// check if such an ID really exists
-	if (!findIMSession(session_id))
-	{
-		llwarns << "Trying to set as active a non-existent session!" << llendl;
-		return;
-	}
-
-	mActiveSessionID = session_id;
-}
-
 LLIMModel::LLIMModel() 
 {
 	addNewMsgCallback(boost::bind(&LLIMFloater::newIMCallback, _1));
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 00b67f520c..054388bc6c 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -147,13 +147,6 @@ public:
 
 	LLIMModel();
 
-
-	//we should control the currently active session
-	LLUUID	mActiveSessionID;
-	void	setActiveSessionID(const LLUUID& session_id);
-	void	resetActiveSessionID() { mActiveSessionID.setNull(); }
-	LLUUID	getActiveSessionID() { return mActiveSessionID; }
-
 	/** Session id to session object */
 	std::map<LLUUID, LLIMSession*> mId2SessionMap;
 
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 9fd73746e8..b4e8927879 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -93,13 +93,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 	}
 	else
 	{
-		// store active session id
-		const LLUUID & active_session_id =
-				LLIMModel::instance().getActiveSessionID();
-
-		// set searched session as active to avoid IM toast popup
-		LLIMModel::instance().setActiveSessionID(session_id);
-
 		S32 unread = session->mNumUnread;
 		S32 participant_unread = session->mParticipantUnreadMessageCount;
 		LLIMModel::instance().addMessageSilently(session_id, from, from_id,
@@ -110,16 +103,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 
 		// update IM floater messages
 		updateIMFLoaterMesages(session_id);
-
-		// restore active session id
-		if (active_session_id.isNull())
-		{
-			LLIMModel::instance().resetActiveSessionID();
-		}
-		else
-		{
-			LLIMModel::instance().setActiveSessionID(active_session_id);
-		}
 	}
 }
 
-- 
cgit v1.2.3


From 3f020d0be92859e1d9261261ccc9c377df700118 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 22 Oct 2012 19:26:18 -0700
Subject: CHUI-441 : WIP : Initial changes to LLIMFloater to use the same model
 as LLIMFloaterContainer

---
 indra/newview/llimfloater.cpp          |  8 +++++---
 indra/newview/llimfloater.h            |  4 ++--
 indra/newview/llimfloatercontainer.cpp | 19 ++++++++++---------
 indra/newview/llimfloatercontainer.h   |  2 +-
 4 files changed, 18 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index e4032738a7..29e84e1332 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -582,7 +582,7 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 	}
 }
 
-void LLIMFloater::addToHost(const LLUUID& session_id, const bool force)
+void LLIMFloater::addToHost(const LLUUID& session_id, LLConversationItemSession* session_root_model, const bool force)
 {
 	if (!LLIMConversation::isChatMultiTab() || !gIMMgr->hasSession(session_id))
 	{
@@ -593,7 +593,7 @@ void LLIMFloater::addToHost(const LLUUID& session_id, const bool force)
 	bool exist = findInstance(session_id);
 
 	// Get the floater: this will create the instance if it didn't exist
-	LLIMFloater* floater = getInstance(session_id);
+	LLIMFloater* floater = getInstance(session_id, session_root_model);
 	if (floater)
 	{
 
@@ -672,11 +672,12 @@ LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
 	return conversation;
 }
 
-LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
+LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id, LLConversationItemSession* session_root_model)
 {
 	LLIMFloater* conversation =
 				LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
 
+	conversation->setSessionRoot(session_root_model);
 	return conversation;
 }
 
@@ -1322,6 +1323,7 @@ void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
 	floater->removeTypingIndicator();
 }
 
+// CHUI-441 : We should not create a floater here but go through LLIMFLoaterContainer
 void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
 {
 	LLIMFloater::addToHost(session_id);
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 26daf00afd..fd08612c32 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -71,8 +71,8 @@ public:
 	// Check typing timeout timer.
 
 	static LLIMFloater* findInstance(const LLUUID& session_id);
-	static LLIMFloater* getInstance(const LLUUID& session_id);
-	static void addToHost(const LLUUID& session_id, const bool force = false);
+	static LLIMFloater* getInstance(const LLUUID& session_id, LLConversationItemSession* session_root_model);
+	static void addToHost(const LLUUID& session_id, LLConversationItemSession* session_root_model, const bool force = false);
 
 	// LLFloater overrides
 	/*virtual*/ void onClose(bool app_quitting);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index cf4d054dd5..75ccc56885 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -98,8 +98,8 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	LLIMFloater::addToHost(session_id, true);
-	addConversationListItem(session_id, true);
+	LLConversationItemSession* item = addConversationListItem(session_id, true);
+	LLIMFloater::addToHost(session_id, item, true);
 }
 
 void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
@@ -109,12 +109,13 @@ void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std:
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	LLIMFloater::addToHost(session_id, true);
-	addConversationListItem(session_id, true);
+	LLConversationItemSession* item = addConversationListItem(session_id, true);
+	LLIMFloater::addToHost(session_id, item, true);
 }
 
 void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
 {
+	// CHUI-441 : We should do this *without* delete and recreate
 	addConversationListItem(new_session_id, removeConversationListItem(old_session_id));
 }
 
@@ -1167,11 +1168,11 @@ void LLIMFloaterContainer::setNearbyDistances()
 	}
 }
 
-void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
+LLConversationItemSession* LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
 {
 	bool is_nearby_chat = uuid.isNull();
 
-    //Stores the display name for the conversation line item
+    // Stores the display name for the conversation line item
 	std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatLabel") : LLIMModel::instance().getName(uuid);
 
 	// Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do)
@@ -1179,7 +1180,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWi
 	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
 	if (item_it != mConversationsItems.end())
 	{
-		return;
+		return item_it->second;
 	}
 
 	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
@@ -1196,7 +1197,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWi
 	if (!item)
 	{
 		llwarns << "Couldn't create conversation session item : " << display_name << llendl;
-		return;
+		return NULL;
 	}
 	item->renameItem(display_name);
 	item->updateParticipantName(NULL);
@@ -1234,7 +1235,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWi
 	// scroll to newly added item
 	mConversationsRoot->scrollToShowSelection();
 
-	return;
+	return item;
 }
 
 bool LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index ba2d085858..5823a47a8d 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -151,7 +151,7 @@ private:
 	// Conversation list implementation
 public:
 	bool removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
-	void addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
+	LLConversationItemSession* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
 	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
 	void setNearbyDistances();
 
-- 
cgit v1.2.3


From a780eb1a92811c2531c2fc1d211e8e5dd03da103 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 23 Oct 2012 13:20:53 +0300
Subject: CHUI-418 FIXED Check that mViewModelItem is not NULL

---
 indra/llui/llfolderview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index c8b8bcae48..c31a832141 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -505,7 +505,7 @@ void LLFolderView::sanitizeSelection()
 
 		// ensure that each ancestor is open and potentially passes filtering
 		BOOL visible = false;
-		if(item->getViewModelItem())
+		if(item->getViewModelItem() != NULL)
 		{
 			visible = item->getViewModelItem()->potentiallyVisible(); // initialize from filter state for this item
 		}
-- 
cgit v1.2.3


From 52a8ea96a1b9ad52a01c4617de63f8cc1bec1e31 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 23 Oct 2012 10:38:04 -0700
Subject: Backed out changeset: 174fccc7016d

---
 indra/llui/llui.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index f43409a1ff..41a948e545 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1629,10 +1629,10 @@ void LLUI::initClass(const settings_map_t& settings,
 	LLUICtrl::CommitCallbackRegistry::Registrar& reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar();
 
 	// Callbacks for associating controls with floater visibility:
-	reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD(LLUUID())));
-	reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD(LLUUID())));
-	reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(LLUUID()), FALSE));
-	reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD(LLUUID())));
+	reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleInstance, _2, LLSD()));
+	reg.add("Floater.ToggleOrBringToFront", boost::bind(&LLFloaterReg::toggleInstanceOrBringToFront, _2, LLSD()));
+	reg.add("Floater.Show", boost::bind(&LLFloaterReg::showInstance, _2, LLSD(), FALSE));
+	reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideInstance, _2, LLSD()));
 	
 	// Button initialization callback for toggle buttons
 	reg.add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
@@ -1647,8 +1647,8 @@ void LLUI::initClass(const settings_map_t& settings,
 	reg.add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
 	
 	// Used by menus along with Floater.Toggle to display visibility as a check-mark
-	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD(LLUUID())));
-	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.IsOpen", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD(LLUUID())));
+	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD()));
+	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.IsOpen", boost::bind(&LLFloaterReg::instanceVisible, _2, LLSD()));
 
 	// Parse the master list of commands
 	LLCommandManager::load();
-- 
cgit v1.2.3


From 06978c99d12a1261f3834fa2ebc19e24c54fd1d4 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 24 Oct 2012 13:06:30 +0300
Subject: CHUI-430 FIXED Open Nearby chat if is is the only conversation in the
 list.

---
 indra/newview/llimfloatercontainer.cpp | 16 ++++++++++++++++
 indra/newview/llimfloatercontainer.h   |  1 +
 2 files changed, 17 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index cf4d054dd5..7821f2ee0d 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -222,6 +222,7 @@ BOOL LLIMFloaterContainer::postBuild()
 void LLIMFloaterContainer::onOpen(const LLSD& key)
 {
 	LLMultiFloater::onOpen(key);
+	openNearbyChat();
 }
 
 // virtual
@@ -508,6 +509,7 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 			LLSD name("nearby_chat");
 			LLFloaterReg::toggleInstanceOrBringToFront(name);
 		}
+		openNearbyChat();
 	}
 
 	nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
@@ -1491,4 +1493,18 @@ void LLIMFloaterContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
 	}
 }
 
+void LLIMFloaterContainer::openNearbyChat()
+{
+	// If there's only one conversation in the container and that conversation is the nearby chat
+	//(which it should be...), open it so to make the list of participants visible. This happens to be the most common case when opening the Chat floater.
+	if(mConversationsItems.size() == 1)
+	{
+		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[LLUUID()]);
+		if (nearby_chat)
+		{
+			nearby_chat->setOpen(TRUE);
+		}
+	}
+}
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index ba2d085858..75fed18502 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -138,6 +138,7 @@ private:
 	void moderateVoiceAllParticipants(bool unmute);
 	void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
 	void toggleAllowTextChat(const LLUUID& participant_uuid);
+	void openNearbyChat();
 
 	LLButton* mExpandCollapseBtn;
 	LLLayoutPanel* mMessagesPane;
-- 
cgit v1.2.3


From a9f8b945519eece7943694f7ac8c200828e5adfa Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 24 Oct 2012 10:51:29 -0700
Subject: CHUI-363: Problem: Nearby chat is a set to be a null converstation.
 Because of this, when the voice indicator was set to only show for active
 conversations...voice indicators inside null conversations were not being
 turned toggled. Resolution: Now will adjust the speaker indicator even if it
 exists in a null (nearby chat) conversation.

---
 indra/newview/llspeakingindicatormanager.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 9b38bf22ff..900379ae1e 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -241,7 +241,7 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea
 			BOOL switch_current_on = switch_on;
 
 			// we should show indicator for specified voice session only if this is current channel. EXT-5562.
-			if (switch_current_on && indicator->getTargetSessionID().notNull())
+			if (switch_current_on)
 			{
 				switch_current_on = indicator->getTargetSessionID() == session_id;
 				LL_DEBUGS("SpeakingIndicator") << "Session: " << session_id << ", target: " << indicator->getTargetSessionID() << ", the same? = " << switch_current_on << LL_ENDL;
-- 
cgit v1.2.3


From 68815045a629eeb0e4ab33c05d3773d272eafb50 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 24 Oct 2012 13:18:41 -0700
Subject: CHUI-441 : WIP : Initial refactor part 2. Works but the list doesn't
 update in the torn off dialog.

---
 indra/newview/llimconversation.cpp                 | 98 ++++++++++++++++++++--
 indra/newview/llimconversation.h                   | 13 ++-
 indra/newview/llimfloater.cpp                      | 10 ++-
 indra/newview/llimfloater.h                        |  4 +-
 indra/newview/llimfloatercontainer.cpp             | 28 +++++--
 indra/newview/llimfloatercontainer.h               |  3 +-
 .../skins/default/xui/en/floater_im_session.xml    | 12 ---
 7 files changed, 132 insertions(+), 36 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index bd2a2419a8..1e268bcaf9 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -49,7 +49,7 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
   ,  mTearOffBtn(NULL)
   ,  mCloseBtn(NULL)
   ,  mSessionID(session_id.asUUID())
-  , mParticipantList(NULL)
+//  , mParticipantList(NULL)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
@@ -73,11 +73,13 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
 
 LLIMConversation::~LLIMConversation()
 {
+	/*
 	if (mParticipantList)
 	{
 		delete mParticipantList;
 		mParticipantList = NULL;
 	}
+	 */
 
 	delete mRefreshTimer;
 }
@@ -127,11 +129,41 @@ BOOL LLIMConversation::postBuild()
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this));
 
-	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
-
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
 
+	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
+	
+	// Create a root view folder for all participants
+	LLConversationItem* base_item = new LLConversationItem(mConversationViewModel);
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    //p.name = getName();
+    //p.title = getLabel();
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mParticipantListPanel;
+    //p.tool_tip = p.name;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
+    p.use_ellipses = true;
+    //p.options_menu = "menu_conversation.xml";
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+	
+	// Add a scroller for the folder (participant) view
+	LLRect scroller_view_rect = mParticipantListPanel->getRect();
+	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
+	scroller_params.rect(scroller_view_rect);
+	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+	scroller->setFollowsAll();
+	mParticipantListPanel->addChild(scroller);
+	scroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(scroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+	
+	
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
 	mInputEditor = getChild<LLChatEntry>("chat_editor");
@@ -167,15 +199,20 @@ BOOL LLIMConversation::postBuild()
 	return result;
 }
 
+LLParticipantList* LLIMConversation::getParticipantList()
+{
+	return dynamic_cast<LLParticipantList*>(LLIMFloaterContainer::getInstance()->getSessionModel(mSessionID));
+}
+
 void LLIMConversation::draw()
 {
 	LLTransientDockableFloater::draw();
 
 	if (mRefreshTimer->hasExpired())
 	{
-		if (mParticipantList)
+		if (getParticipantList())
 		{
-			mParticipantList->update();
+			getParticipantList()->update();
 		}
 
 		refresh();
@@ -274,6 +311,7 @@ void LLIMConversation::appendMessage(const LLChat& chat, const LLSD &args)
 
 void LLIMConversation::buildParticipantList()
 {
+	/*
 	if (mIsNearbyChat)
 	{
 		LLLocalSpeakerMgr* speaker_manager = LLLocalSpeakerMgr::getInstance();
@@ -289,13 +327,57 @@ void LLIMConversation::buildParticipantList()
 			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), mConversationViewModel, true, false);
 		}
 	}
-	updateHeaderAndToolbar();
+	*/
+
+	// Create the participants widgets now
+	// Note: inspired from LLIMFloaterContainer::addConversationListItem()
+	LLParticipantList* item = getParticipantList();
+	if (!item)
+	{
+		llinfos << "Merov debug : buildParticipantList, no list!" << llendl;
+		return;
+	}
+	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+	while (current_participant_model != end_participant_model)
+	{
+		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+		participant_view->addToFolder(mConversationsRoot);	// ! Not sure about that. TBC...
+		participant_view->setVisible(TRUE);
+		current_participant_model++;
+	}
+	
+	//updateHeaderAndToolbar();
+}
+
+// Copied from LLIMFloaterContainer::createConversationViewParticipant(). Refactor opportunity!
+LLConversationViewParticipant* LLIMConversation::createConversationViewParticipant(LLConversationItem* item)
+{
+	LLConversationViewParticipant::Params params;
+    LLRect panel_rect = mParticipantListPanel->getRect();
+	
+	params.name = item->getDisplayName();
+	//params.icon = bridge->getIcon();
+	//params.icon_open = bridge->getOpenIcon();
+	//params.creation_date = bridge->getCreationDate();
+	params.root = mConversationsRoot;
+	params.listener = item;
+	
+    //24 is the the current hight of an item (itemHeight) loaded from conversation_view_participant.xml.
+	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
+	params.tool_tip = params.name;
+	params.participant_id = item->getUUID();
+	
+	llinfos << "Merov debug : LLIMConversation, create participant, name = " << item->getDisplayName() << llendl;
+	
+	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
 }
 
 void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
 {
 	// TODO: Check this code when sort order menu will be added. (EM)
-	if (!mParticipantList)
+	if (!getParticipantList())
 	{
 		return;
 	}
@@ -304,7 +386,7 @@ void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
 
 	if (chosen_item == "sort_name")
 	{
-		mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
+		getParticipantList()->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
 	}
 
 }
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 603e0d0197..c3f885c8be 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -35,6 +35,7 @@
 #include "lleventtimer.h"
 #include "llimview.h"
 #include "llconversationmodel.h"
+#include "llconversationview.h"
 
 class LLPanelChatControlPanel;
 class LLChatEntry;
@@ -114,10 +115,16 @@ protected:
 
 	LLIMModel::LLIMSession* mSession;
 
-	LLLayoutPanel* mParticipantListPanel;
-	LLParticipantList* mParticipantList;
-	LLUUID mSessionID;
+	// Participants list: model and view
+	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+	
+	LLUUID mSessionID; 
+	LLLayoutPanel* mParticipantListPanel;	// add the widgets to that see mConversationsListPanel
+	//LLParticipantList* mParticipantList; get this from the mConversationsItems for the moment
+	LLParticipantList* getParticipantList();
+	conversations_widgets_map mConversationsWidgets;
 	LLConversationViewModel mConversationViewModel;
+	LLFolderView* mConversationsRoot;
 
 	LLChatHistory* mChatHistory;
 	LLChatEntry* mInputEditor;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 29e84e1332..9f7b3cd50b 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -582,10 +582,11 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 	}
 }
 
-void LLIMFloater::addToHost(const LLUUID& session_id, LLConversationItemSession* session_root_model, const bool force)
+void LLIMFloater::addToHost(const LLUUID& session_id, const bool force)
 {
 	if (!LLIMConversation::isChatMultiTab() || !gIMMgr->hasSession(session_id))
 	{
+		llinfos << "Merov debug : addToHost, not added! multitab = " << LLIMConversation::isChatMultiTab() << ", has session = " << gIMMgr->hasSession(session_id) << llendl;
 		return;
 	}
 
@@ -593,12 +594,14 @@ void LLIMFloater::addToHost(const LLUUID& session_id, LLConversationItemSession*
 	bool exist = findInstance(session_id);
 
 	// Get the floater: this will create the instance if it didn't exist
-	LLIMFloater* floater = getInstance(session_id, session_root_model);
+	LLIMFloater* floater = getInstance(session_id);
 	if (floater)
 	{
 
 		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
 
+		llinfos << "Merov debug : addToHost, done! exist = " << exist << llendl;
+
 		// Do not add again existing floaters
 		if (!exist)
 		{
@@ -672,12 +675,11 @@ LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
 	return conversation;
 }
 
-LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id, LLConversationItemSession* session_root_model)
+LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
 {
 	LLIMFloater* conversation =
 				LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
 
-	conversation->setSessionRoot(session_root_model);
 	return conversation;
 }
 
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index fd08612c32..26daf00afd 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -71,8 +71,8 @@ public:
 	// Check typing timeout timer.
 
 	static LLIMFloater* findInstance(const LLUUID& session_id);
-	static LLIMFloater* getInstance(const LLUUID& session_id, LLConversationItemSession* session_root_model);
-	static void addToHost(const LLUUID& session_id, LLConversationItemSession* session_root_model, const bool force = false);
+	static LLIMFloater* getInstance(const LLUUID& session_id);
+	static void addToHost(const LLUUID& session_id, const bool force = false);
 
 	// LLFloater overrides
 	/*virtual*/ void onClose(bool app_quitting);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 75ccc56885..6f2b8bcf32 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -98,8 +98,10 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	LLConversationItemSession* item = addConversationListItem(session_id, true);
-	LLIMFloater::addToHost(session_id, item, true);
+	llinfos << "Merov debug : sessionAdded, adding LLIMFloater, id = " << session_id << llendl;
+	LLIMFloater::addToHost(session_id, true);
+	llinfos << "Merov debug : sessionAdded, adding conversation item, id = " << session_id << llendl;
+	addConversationListItem(session_id, true);
 }
 
 void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
@@ -109,8 +111,10 @@ void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std:
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	LLConversationItemSession* item = addConversationListItem(session_id, true);
-	LLIMFloater::addToHost(session_id, item, true);
+	llinfos << "Merov debug : sessionVoiceOrIMStarted, adding LLIMFloater, id = " << session_id << llendl;
+	LLIMFloater::addToHost(session_id, true);
+	llinfos << "Merov debug : sessionVoiceOrIMStarted, adding conversation item, id = " << session_id << llendl;
+	addConversationListItem(session_id, true);
 }
 
 void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
@@ -129,6 +133,7 @@ void LLIMFloaterContainer::onCurrentChannelChanged(const LLUUID& session_id)
 {
     if (session_id != LLUUID::null)
     {
+		llinfos << "Merov debug : onCurrentChannelChanged, LLIMFloater::show, id = " << session_id << llendl;
     	LLIMFloater::show(session_id);
     }
 }
@@ -343,6 +348,12 @@ LLIMFloaterContainer* LLIMFloaterContainer::getInstance()
 	return LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
 }
 
+LLConversationItemSession* LLIMFloaterContainer::getSessionModel(const LLUUID& session_id)
+{
+	LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
+	return session_model;
+}
+
 void LLIMFloaterContainer::setMinimized(BOOL b)
 {
 	if (isMinimized() == b) return;
@@ -813,6 +824,7 @@ void LLIMFloaterContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
     //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
     else if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
     {
+		llinfos << "Merov debug : getParticipantUUIDs, LLIMFloater::findInstance, id = " << conversationItem->getUUID() << llendl;
         LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
         LLUUID participantID = conversationFloater->getOtherParticipantUUID();
         selected_uuids.push_back(participantID);
@@ -888,6 +900,7 @@ void LLIMFloaterContainer::doToSelectedConversation(const std::string& command,
 {
     //Find the conversation floater associated with the selected id
     const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+	llinfos << "Merov debug : doToSelectedConversation, LLIMFloater::findInstance, id = " << conversationItem->getUUID() << llendl;
     LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
 
     if(conversationFloater)
@@ -1168,7 +1181,7 @@ void LLIMFloaterContainer::setNearbyDistances()
 	}
 }
 
-LLConversationItemSession* LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
+LLConversationItem* LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
 {
 	bool is_nearby_chat = uuid.isNull();
 
@@ -1180,7 +1193,9 @@ LLConversationItemSession* LLIMFloaterContainer::addConversationListItem(const L
 	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
 	if (item_it != mConversationsItems.end())
 	{
-		return item_it->second;
+		llinfos << "Merov debug : addConversationListItem, item already present -> exit, id = " << uuid << llendl;
+		// HACK!!! DO NOT COMMIT!! Understand why this thing is already present...
+		//return item_it->second;
 	}
 
 	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
@@ -1196,6 +1211,7 @@ LLConversationItemSession* LLIMFloaterContainer::addConversationListItem(const L
 	}
 	if (!item)
 	{
+		llinfos << "Merov debug : Couldn't create conversation session item : " << display_name << llendl;
 		llwarns << "Couldn't create conversation session item : " << display_name << llendl;
 		return NULL;
 	}
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 5823a47a8d..c5abc96162 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -92,6 +92,7 @@ public:
 	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
     LLUUID getSelectedSession() { return mSelectedSession; }
     void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
+	LLConversationItemSession* getSessionModel(const LLUUID& session_id);
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
@@ -151,7 +152,7 @@ private:
 	// Conversation list implementation
 public:
 	bool removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
-	LLConversationItemSession* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
+	LLConversationItem* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
 	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
 	void setNearbyDistances();
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 2b542595c5..84fba0a3b3 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -158,18 +158,6 @@
       width="150" 
       height="310" 
       auto_resize="false">
-            <avatar_list
-             color="DkGray2"
-             follows="all"
-             height="310"
-             ignore_online_status="true"
-        layout="topleft"
-             name="speakers_list"
-             opaque="false"
-             show_info_btn="true"
-             show_profile_btn="false"
-             show_speaking_indicator="false"
-             width="150" />
       </layout_panel>
     <layout_panel
        default_tab_group="3"
-- 
cgit v1.2.3


From b77e2f17aa9755120032ee977d34e9e923cba0be Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 24 Oct 2012 16:02:58 -0700
Subject: CHUI-449: Problem: When a toast was clicked, the conversation floater
 was displayed without selecting the conversation line item. Resolution: Added
 a function that will show the conversation floater container and then trigger
 selecting the conversation line item. When the conversation line item is
 selecting this implicitly will cause the correct conversation floater to be
 displayed.

---
 indra/newview/llconversationview.cpp   | 27 ++++++++++-----------------
 indra/newview/llimfloatercontainer.cpp |  6 ++++++
 indra/newview/llimfloatercontainer.h   |  2 ++
 indra/newview/llimview.cpp             |  3 ++-
 4 files changed, 20 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 9144f402b4..92493194b8 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -437,29 +437,22 @@ void LLConversationViewParticipant::selectItem()
     LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
     LLFloater* session_floater;
 
-    //Only execute when switching floaters (conversations)
-    if(vmi && vmi->getUUID() != container->getSelectedSession())
+    if(vmi)
     {
-        //When null, show the nearby chat conversation floater
-        if(vmi->getUUID().isNull())
+        session_floater = LLIMConversation::getConversation(vmi->getUUID());
+
+        //Only execute when switching floaters (conversations)
+        if(vmi->getUUID() != container->getSelectedSession())
         {
-            LLNearbyChat* nearbyChat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
-            nearbyChat->show();
+            container->selectFloater(session_floater);
+            // Store the active session
+            container->setSelectedSession(vmi->getUUID());
         }
-        //Otherwise, show the IM conversation floater
+        //Focus the current conversation floater (it is already visible so just focus it)
         else
         {
-            LLIMFloater::show(vmi->getUUID());
+            session_floater->setFocus(TRUE);
         }
-
-        // Store the active session
-        container->setSelectedSession(vmi->getUUID());
-    }
-    //Focus the current conversation floater (it is already visible so just focus it)
-    else
-    {
-        session_floater = LLIMConversation::getConversation(vmi->getUUID());
-        session_floater->setFocus(TRUE);
     }
 
     LLFolderViewItem::selectItem();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 7821f2ee0d..0538a286ce 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1089,6 +1089,12 @@ bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
     return false;
 }
 
+void LLIMFloaterContainer::showConversation(const LLUUID& session_id)
+{
+    setVisibleAndFrontmost(false);
+    setConvItemSelect(session_id);    
+}
+
 //Will select only the conversation item
 void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
 {
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 75fed18502..b884ad5d4b 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -65,6 +65,8 @@ public:
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+    
+    void showConversation(const LLUUID& session_id);
     void setConvItemSelect(const LLUUID& session_id);
     void setItemSelect(const LLUUID& session_id);
 	/*virtual*/ void tabClose();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 4c5631d5e1..d5f1e81933 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -49,6 +49,7 @@
 #include "llcallingcard.h"
 #include "llchat.h"
 #include "llimfloater.h"
+#include "llimfloatercontainer.h"
 #include "llgroupiconctrl.h"
 #include "llmd5.h"
 #include "llmutelist.h"
@@ -108,7 +109,7 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	args["FROM"] = av_name.getCompleteName();
 	args["FROM_ID"] = msg["from_id"];
 	args["SESSION_ID"] = msg["session_id"];
-	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID()));
+	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLIMFloaterContainer::showConversation, LLIMFloaterContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
 void toast_callback(const LLSD& msg){
-- 
cgit v1.2.3


From e6e2b0dda2b1c3cb8d96a885a569a645d97e0756 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 24 Oct 2012 16:37:08 -0700
Subject: CHUI-441 : WIP : Fixed the creation of empty model records in the
 list model

---
 indra/newview/llimfloatercontainer.cpp | 70 +++++++++++++++-------------------
 1 file changed, 30 insertions(+), 40 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 6f2b8bcf32..60cc5c6d7e 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -348,10 +348,10 @@ LLIMFloaterContainer* LLIMFloaterContainer::getInstance()
 	return LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
 }
 
+// Returns a pointer to the session model if found, NULL otherwise.
 LLConversationItemSession* LLIMFloaterContainer::getSessionModel(const LLUUID& session_id)
 {
-	LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
-	return session_model;
+	return (mConversationsItems.find(session_id) != mConversationsItems.end() ? dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]) : NULL);
 }
 
 void LLIMFloaterContainer::setMinimized(BOOL b)
@@ -454,7 +454,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	{
 		if (!participant_view)
 		{
-			LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
+			LLConversationItemSession* session_model = getSessionModel(session_id);
 			if (session_model)
 			{
 				LLConversationItemParticipant* participant_model = session_model->findParticipant(participant_id);
@@ -1137,47 +1137,39 @@ void LLIMFloaterContainer::setItemSelect(const LLUUID& session_id)
 
 void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
 {
-	conversations_items_map::iterator item_it = mConversationsItems.find(session_id);
-	if (item_it != mConversationsItems.end())
+	LLConversationItemSession* item = getSessionModel(session_id);
+	if (item)
 	{
-		LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(item_it->second);
-		if (item)
-		{
-			item->setTimeNow(participant_id);
-			mConversationViewModel.requestSortAll();
-			mConversationsRoot->arrangeAll();
-		}
+		item->setTimeNow(participant_id);
+		mConversationViewModel.requestSortAll();
+		mConversationsRoot->arrangeAll();
 	}
 }
 
 void LLIMFloaterContainer::setNearbyDistances()
 {
-	// Get the nearby chat session: that's the one with uuid nul in mConversationsItems
-	conversations_items_map::iterator item_it = mConversationsItems.find(LLUUID());
-	if (item_it != mConversationsItems.end())
-	{
-		LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(item_it->second);
-		if (item)
+	// Get the nearby chat session: that's the one with uuid nul
+	LLConversationItemSession* item = getSessionModel(LLUUID());
+	if (item)
+	{
+		// Get the positions of the nearby avatars and their ids
+		std::vector<LLVector3d> positions;
+		uuid_vec_t avatar_ids;
+		LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+		// Get the position of the agent
+		const LLVector3d& me_pos = gAgent.getPositionGlobal();
+		// For each nearby avatar, compute and update the distance
+		int avatar_count = positions.size();
+		for (int i = 0; i < avatar_count; i++)
 		{
-			// Get the positions of the nearby avatars and their ids
-			std::vector<LLVector3d> positions;
-			uuid_vec_t avatar_ids;
-			LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
-			// Get the position of the agent
-			const LLVector3d& me_pos = gAgent.getPositionGlobal();
-			// For each nearby avatar, compute and update the distance
-			int avatar_count = positions.size();
-			for (int i = 0; i < avatar_count; i++)
-			{
-				F64 dist = dist_vec_squared(positions[i], me_pos);
-				item->setDistance(avatar_ids[i],dist);
-			}
-			// Also does it for the agent itself
-			item->setDistance(gAgent.getID(),0.0f);
-			// Request resort
-			mConversationViewModel.requestSortAll();
-			mConversationsRoot->arrangeAll();
+			F64 dist = dist_vec_squared(positions[i], me_pos);
+			item->setDistance(avatar_ids[i],dist);
 		}
+		// Also does it for the agent itself
+		item->setDistance(gAgent.getID(),0.0f);
+		// Request resort
+		mConversationViewModel.requestSortAll();
+		mConversationsRoot->arrangeAll();
 	}
 }
 
@@ -1188,14 +1180,12 @@ LLConversationItem* LLIMFloaterContainer::addConversationListItem(const LLUUID&
     // Stores the display name for the conversation line item
 	std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatLabel") : LLIMModel::instance().getName(uuid);
 
-	// Check if the item is not already in the list, exit if it is and has the same name and uuid (nothing to do)
+	// Check if the item is not already in the list, exit (nothing to do)
 	// Note: this happens often, when reattaching a torn off conversation for instance
 	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
 	if (item_it != mConversationsItems.end())
 	{
-		llinfos << "Merov debug : addConversationListItem, item already present -> exit, id = " << uuid << llendl;
-		// HACK!!! DO NOT COMMIT!! Understand why this thing is already present...
-		//return item_it->second;
+		return item_it->second;
 	}
 
 	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
-- 
cgit v1.2.3


From 853826efccfea704eb22276dd63c9155a3f77ac1 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 24 Oct 2012 18:12:27 -0700
Subject: CHUI-441 : WIP : More map clean up and better use of get_ptr_in_map()

---
 indra/newview/llimfloatercontainer.cpp | 36 ++++++++++++----------------------
 indra/newview/llimfloatercontainer.h   |  2 +-
 2 files changed, 14 insertions(+), 24 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 60cc5c6d7e..9d9d49f497 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -348,12 +348,6 @@ LLIMFloaterContainer* LLIMFloaterContainer::getInstance()
 	return LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
 }
 
-// Returns a pointer to the session model if found, NULL otherwise.
-LLConversationItemSession* LLIMFloaterContainer::getSessionModel(const LLUUID& session_id)
-{
-	return (mConversationsItems.find(session_id) != mConversationsItems.end() ? dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]) : NULL);
-}
-
 void LLIMFloaterContainer::setMinimized(BOOL b)
 {
 	if (isMinimized() == b) return;
@@ -432,7 +426,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	LLUUID session_id = event.get("session_uuid").asUUID();
 	LLUUID participant_id = event.get("participant_uuid").asUUID();
 
-	LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[session_id]);
+	LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,session_id));
 	if (!session_view)
 	{
 		// We skip events that are not associated to a session
@@ -454,7 +448,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	{
 		if (!participant_view)
 		{
-			LLConversationItemSession* session_model = getSessionModel(session_id);
+			LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
 			if (session_model)
 			{
 				LLConversationItemParticipant* participant_model = session_model->findParticipant(participant_id);
@@ -1101,18 +1095,18 @@ bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
     return false;
 }
 
-//Will select only the conversation item
+// Will select only the conversation item
 void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
 {
-	LLFolderViewItem* widget = mConversationsWidgets[session_id];
-	if (widget && mSelectedSession != session_id)
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
+	if (widget && (mSelectedSession != session_id))
 	{
 		mSelectedSession = session_id;
 		(widget->getRoot())->setSelection(widget, FALSE, FALSE);
 	}
 }
 
-//Will select the conversation/participant item
+// Will select the conversation/participant item
 void LLIMFloaterContainer::setItemSelect(const LLUUID& session_id)
 {
 
@@ -1125,7 +1119,7 @@ void LLIMFloaterContainer::setItemSelect(const LLUUID& session_id)
         if(session_id != vmi->getUUID())
         {
             mSelectedSession = session_id;
-            LLFolderViewItem* widget = mConversationsWidgets[session_id];
+			LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
             (widget->getRoot())->setSelection(widget, FALSE, FALSE);
 
 			// Scroll to selected item
@@ -1137,7 +1131,7 @@ void LLIMFloaterContainer::setItemSelect(const LLUUID& session_id)
 
 void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
 {
-	LLConversationItemSession* item = getSessionModel(session_id);
+	LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
 	if (item)
 	{
 		item->setTimeNow(participant_id);
@@ -1149,7 +1143,7 @@ void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& pa
 void LLIMFloaterContainer::setNearbyDistances()
 {
 	// Get the nearby chat session: that's the one with uuid nul
-	LLConversationItemSession* item = getSessionModel(LLUUID());
+	LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,LLUUID()));
 	if (item)
 	{
 		// Get the positions of the nearby avatars and their ids
@@ -1250,15 +1244,11 @@ bool LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
 	bool isWidgetSelected = false;
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(uuid);
-	if (widget_it != mConversationsWidgets.end())
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+	if (widget)
 	{
-		LLFolderViewItem* widget = widget_it->second;
-		if (widget)
-		{
-			isWidgetSelected = widget->isSelected();
-			widget->destroyView();
-		}
+		isWidgetSelected = widget->isSelected();
+		widget->destroyView();
 	}
 	
 	// Suppress the conversation items and widgets from their respective maps
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index c5abc96162..45a40b8964 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -92,7 +92,7 @@ public:
 	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
     LLUUID getSelectedSession() { return mSelectedSession; }
     void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
-	LLConversationItemSession* getSessionModel(const LLUUID& session_id);
+	LLConversationItem* getSessionModel(const LLUUID& session_id) { return get_ptr_in_map(mConversationsItems,session_id); }
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
-- 
cgit v1.2.3


From b5d76c2b55666083279580f383e5a7b139517504 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 24 Oct 2012 20:08:36 -0700
Subject: CHUI-441 : WIP : Fix the initial attach code so to allow creation of
 the conversation item before the dialog

---
 indra/newview/llimfloater.cpp          | 10 ++--------
 indra/newview/llimfloatercontainer.cpp |  9 ++++-----
 2 files changed, 6 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 9f7b3cd50b..8fbf691897 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -586,13 +586,9 @@ void LLIMFloater::addToHost(const LLUUID& session_id, const bool force)
 {
 	if (!LLIMConversation::isChatMultiTab() || !gIMMgr->hasSession(session_id))
 	{
-		llinfos << "Merov debug : addToHost, not added! multitab = " << LLIMConversation::isChatMultiTab() << ", has session = " << gIMMgr->hasSession(session_id) << llendl;
 		return;
 	}
 
-	// Test the existence of the floater before we try to create it
-	bool exist = findInstance(session_id);
-
 	// Get the floater: this will create the instance if it didn't exist
 	LLIMFloater* floater = getInstance(session_id);
 	if (floater)
@@ -600,10 +596,8 @@ void LLIMFloater::addToHost(const LLUUID& session_id, const bool force)
 
 		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
 
-		llinfos << "Merov debug : addToHost, done! exist = " << exist << llendl;
-
-		// Do not add again existing floaters
-		if (!exist)
+		// Do not attach to the IM container if it's already attached
+		if (!getFloaterHost())
 		{
 			//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
 			// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 9d9d49f497..11d8b29884 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -98,10 +98,10 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	llinfos << "Merov debug : sessionAdded, adding LLIMFloater, id = " << session_id << llendl;
-	LLIMFloater::addToHost(session_id, true);
 	llinfos << "Merov debug : sessionAdded, adding conversation item, id = " << session_id << llendl;
 	addConversationListItem(session_id, true);
+	llinfos << "Merov debug : sessionAdded, adding LLIMFloater, id = " << session_id << llendl;
+	LLIMFloater::addToHost(session_id, true);
 }
 
 void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
@@ -111,10 +111,10 @@ void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std:
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	llinfos << "Merov debug : sessionVoiceOrIMStarted, adding LLIMFloater, id = " << session_id << llendl;
-	LLIMFloater::addToHost(session_id, true);
 	llinfos << "Merov debug : sessionVoiceOrIMStarted, adding conversation item, id = " << session_id << llendl;
 	addConversationListItem(session_id, true);
+	llinfos << "Merov debug : sessionVoiceOrIMStarted, adding LLIMFloater, id = " << session_id << llendl;
+	LLIMFloater::addToHost(session_id, true);
 }
 
 void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
@@ -1195,7 +1195,6 @@ LLConversationItem* LLIMFloaterContainer::addConversationListItem(const LLUUID&
 	}
 	if (!item)
 	{
-		llinfos << "Merov debug : Couldn't create conversation session item : " << display_name << llendl;
 		llwarns << "Couldn't create conversation session item : " << display_name << llendl;
 		return NULL;
 	}
-- 
cgit v1.2.3


From 63548b973e6de392f2bf209b3405b1dde78bda03 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 25 Oct 2012 11:43:18 -0700
Subject: CHUI-449: Got rid of a function called setItemSelect(), I wrote this
 code and it doesn't have a purpose anymore since I can use
 setConvItemSelect() instead. Also now torn off, minimized conversations are
 selected when clicking a toast for that conversation. Resolution: Adjusted
 setConvItemSelect() to be less strict when trying to select an item, now as
 long as the function is called it will attempt to select the conversation
 line item.

---
 indra/newview/llconversationview.cpp   |  8 +++-----
 indra/newview/llimfloatercontainer.cpp | 27 ++-------------------------
 indra/newview/llimfloatercontainer.h   |  1 -
 3 files changed, 5 insertions(+), 31 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 92493194b8..de0c65e24f 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -448,11 +448,9 @@ void LLConversationViewParticipant::selectItem()
             // Store the active session
             container->setSelectedSession(vmi->getUUID());
         }
-        //Focus the current conversation floater (it is already visible so just focus it)
-        else
-        {
-            session_floater->setFocus(TRUE);
-        }
+
+        //Redirect focus to the conversation floater
+        session_floater->setFocus(TRUE);
     }
 
     LLFolderViewItem::selectItem();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 0538a286ce..ebb732b995 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -104,7 +104,7 @@ void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::str
 
 void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-    setItemSelect(session_id);
+    setConvItemSelect(session_id);
 }
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
@@ -1099,35 +1099,12 @@ void LLIMFloaterContainer::showConversation(const LLUUID& session_id)
 void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
 {
 	LLFolderViewItem* widget = mConversationsWidgets[session_id];
-	if (widget && mSelectedSession != session_id)
+	if (widget)
 	{
-		mSelectedSession = session_id;
 		(widget->getRoot())->setSelection(widget, FALSE, FALSE);
 	}
 }
 
-//Will select the conversation/participant item
-void LLIMFloaterContainer::setItemSelect(const LLUUID& session_id)
-{
-
-    if(mConversationsRoot->getCurSelectedItem() && mConversationsRoot->getCurSelectedItem()->getParentFolder())
-    {
-        //Retreive the conversation id. When a participant is selected, then have to to get the converation id from the parent.
-        LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(mConversationsRoot->getCurSelectedItem()->getParentFolder()->getViewModelItem());
-
-        //Will allow selection/highlighting of the conversation/participant
-        if(session_id != vmi->getUUID())
-        {
-            mSelectedSession = session_id;
-            LLFolderViewItem* widget = mConversationsWidgets[session_id];
-            (widget->getRoot())->setSelection(widget, FALSE, FALSE);
-
-			// Scroll to selected item
-			mConversationsRoot->scrollToShowSelection();
-        }
-    }
-}
-
 
 void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
 {
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index b884ad5d4b..e69359321a 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -68,7 +68,6 @@ public:
     
     void showConversation(const LLUUID& session_id);
     void setConvItemSelect(const LLUUID& session_id);
-    void setItemSelect(const LLUUID& session_id);
 	/*virtual*/ void tabClose();
 
 	static LLFloater* getCurrentVoiceFloater();
-- 
cgit v1.2.3


From 7127ea071922ee703cab56439a379f475cd5e4e7 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 25 Oct 2012 14:17:10 -0700
Subject: CHUI-449: Post code review with Merov, adjusted setConvItemSelect()
 fuction to be called selectConversation().

---
 indra/newview/llimfloatercontainer.cpp | 8 ++++----
 indra/newview/llimfloatercontainer.h   | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index ebb732b995..bd7d570154 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -104,7 +104,7 @@ void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::str
 
 void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-    setConvItemSelect(session_id);
+    selectConversation(session_id);
 }
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
@@ -1092,11 +1092,11 @@ bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
 void LLIMFloaterContainer::showConversation(const LLUUID& session_id)
 {
     setVisibleAndFrontmost(false);
-    setConvItemSelect(session_id);    
+    selectConversation(session_id);    
 }
 
 //Will select only the conversation item
-void LLIMFloaterContainer::setConvItemSelect(const LLUUID& session_id)
+void LLIMFloaterContainer::selectConversation(const LLUUID& session_id)
 {
 	LLFolderViewItem* widget = mConversationsWidgets[session_id];
 	if (widget)
@@ -1210,7 +1210,7 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWi
 
 	if (isWidgetSelected)
 	{
-		setConvItemSelect(uuid);
+		selectConversation(uuid);
 	}
 	
 	// set the widget to minimized mode if conversations pane is collapsed
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index e69359321a..7d13b37b31 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -67,7 +67,7 @@ public:
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
     
     void showConversation(const LLUUID& session_id);
-    void setConvItemSelect(const LLUUID& session_id);
+    void selectConversation(const LLUUID& session_id);
 	/*virtual*/ void tabClose();
 
 	static LLFloater* getCurrentVoiceFloater();
-- 
cgit v1.2.3


From d49de3a66a5476f4541f15dc61c68e0e509c4c70 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 25 Oct 2012 18:16:56 -0700
Subject: CHUI-441 : WIP : Fix crashes when spawning torn off floaters, added
 widgets creation in the torn off floater for participants.

---
 indra/llui/llfolderviewitem.cpp        |  6 +++---
 indra/llui/llfolderviewitem.h          |  2 +-
 indra/llui/llfolderviewmodel.h         |  5 +++--
 indra/newview/llconversationview.cpp   | 13 +++++++------
 indra/newview/llimconversation.cpp     | 11 +++++++++++
 indra/newview/llimconversation.h       |  2 ++
 indra/newview/llimfloatercontainer.cpp | 29 ++++++++++++-----------------
 7 files changed, 39 insertions(+), 29 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 0b04288950..099d51ce17 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -169,7 +169,6 @@ BOOL LLFolderViewItem::postBuild()
 // Destroys the object
 LLFolderViewItem::~LLFolderViewItem( void )
 {
-	delete mViewModelItem;
 	mViewModelItem = NULL;
 }
 
@@ -473,8 +472,9 @@ void LLFolderViewItem::rename(const std::string& new_name)
 
 const std::string& LLFolderViewItem::getName( void ) const
 {
-	return getViewModelItem()->getName();
-	}
+	static const std::string noName("");
+	return getViewModelItem() ? getViewModelItem()->getName() : noName;
+}
 
 // LLView functionality
 BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index d4002c3184..19a6b0a44a 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -87,7 +87,7 @@ protected:
 	bool						mLabelWidthDirty;
     S32                         mLabelPaddingRight;
 	LLFolderViewFolder*			mParentFolder;
-	LLFolderViewModelItem*		mViewModelItem;
+	LLPointer<LLFolderViewModelItem> mViewModelItem;
 	LLFontGL::StyleFlags		mLabelStyle;
 	std::string					mLabelSuffix;
 	LLUIImagePtr				mIcon,
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index c6030c9b71..5ec08ae211 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -129,10 +129,11 @@ public:
 
 // This is am abstract base class that users of the folderview classes
 // would use to bridge the folder view with the underlying data
-class LLFolderViewModelItem
+class LLFolderViewModelItem : public LLRefCount
 {
 public:
-	virtual ~LLFolderViewModelItem( void ) {};
+	LLFolderViewModelItem() { }
+	virtual ~LLFolderViewModelItem() { }
 
 	virtual void update() {}	//called when drawing
 	virtual const std::string& getName() const = 0;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 9144f402b4..2d5665190f 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -234,9 +234,9 @@ void LLConversationViewSession::toggleOpen()
 
 void LLConversationViewSession::selectItem()
 {
-	
-	LLConversationItem* item = dynamic_cast<LLConversationItem*>(mViewModelItem);
-	LLFloater* session_floater = LLIMConversation::getConversation(item->getUUID());
+	LLFolderViewModelItem* item = mViewModelItem;
+	LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID();
+	LLFloater* session_floater = LLIMConversation::getConversation(session_uuid);
 	LLMultiFloater* host_floater = session_floater->getHost();
 	
 	if (host_floater == mContainer)
@@ -250,7 +250,7 @@ void LLConversationViewSession::selectItem()
 	// Set the focus on the selected floater
 	session_floater->setFocus(TRUE);
     // Store the active session
-    LLIMFloaterContainer::getInstance()->setSelectedSession(item->getUUID());
+    LLIMFloaterContainer::getInstance()->setSelectedSession(session_uuid);
 
 
 	LLFolderViewItem::selectItem();
@@ -272,8 +272,9 @@ void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
 {
 	// Do this only if the conversation floater has been torn off (i.e. no multi floater host) and is not minimized
 	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
-	LLConversationItem* item = dynamic_cast<LLConversationItem*>(mViewModelItem);
-	LLFloater* session_floater = LLIMConversation::getConversation(item->getUUID());
+	LLFolderViewModelItem* item = mViewModelItem;
+	LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID();
+	LLFloater* session_floater = LLIMConversation::getConversation(session_uuid);
 	
 	if (session_floater && !session_floater->getHost() && !session_floater->isMinimized())
 	{
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 1e268bcaf9..532f1be6a8 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -351,6 +351,17 @@ void LLIMConversation::buildParticipantList()
 	//updateHeaderAndToolbar();
 }
 
+void LLIMConversation::addConversationViewParticipant(LLConversationItem* participant_model)
+{
+	// Check if the model already has an associated view
+	llinfos << "Merov debug : addConversationViewParticipant(). We need to check the existence!!!" << llendl;
+	
+	// Create the participant view and attach it to the root
+	LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+	participant_view->addToFolder(mConversationsRoot);	// ! Not sure about that. TBC...
+	participant_view->setVisible(TRUE);	
+}
+
 // Copied from LLIMFloaterContainer::createConversationViewParticipant(). Refactor opportunity!
 LLConversationViewParticipant* LLIMConversation::createConversationViewParticipant(LLConversationItem* item)
 {
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index c3f885c8be..09d0016946 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -71,6 +71,8 @@ public:
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
+	
+	void addConversationViewParticipant(LLConversationItem* item);
 
 protected:
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 11d8b29884..0d62630b31 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -98,9 +98,7 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	llinfos << "Merov debug : sessionAdded, adding conversation item, id = " << session_id << llendl;
 	addConversationListItem(session_id, true);
-	llinfos << "Merov debug : sessionAdded, adding LLIMFloater, id = " << session_id << llendl;
 	LLIMFloater::addToHost(session_id, true);
 }
 
@@ -111,9 +109,7 @@ void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std:
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	llinfos << "Merov debug : sessionVoiceOrIMStarted, adding conversation item, id = " << session_id << llendl;
 	addConversationListItem(session_id, true);
-	llinfos << "Merov debug : sessionVoiceOrIMStarted, adding LLIMFloater, id = " << session_id << llendl;
 	LLIMFloater::addToHost(session_id, true);
 }
 
@@ -433,6 +429,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 		return false;
 	}
 	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+    LLIMFloater *conversation_floater = LLIMFloater::findInstance(session_id);
 
 	if (type == "remove_participant")
 	{
@@ -446,20 +443,18 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	}
 	else if (type == "add_participant")
 	{
-		if (!participant_view)
+		LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
+		LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL);
+		if (!participant_view && session_model && participant_model)
 		{
-			LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
-			if (session_model)
-			{
-				LLConversationItemParticipant* participant_model = session_model->findParticipant(participant_id);
-				if (participant_model)
-				{
-					participant_view = createConversationViewParticipant(participant_model);
-					participant_view->addToFolder(session_view);
-					participant_view->setVisible(TRUE);
-				}
-			}
-
+			participant_view = createConversationViewParticipant(participant_model);
+			participant_view->addToFolder(session_view);
+			participant_view->setVisible(TRUE);
+		}
+		// CHUI-441 : 
+		if (conversation_floater && participant_model)
+		{
+			conversation_floater->addConversationViewParticipant(participant_model);
 		}
 	}
 	else if (type == "update_participant")
-- 
cgit v1.2.3


From 8f1049b2f8659b039752ee23017c1f30fa6d2725 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 26 Oct 2012 15:22:31 +0300
Subject: CHUI-457 FIXED Check that selected participant is not self before
 performing actions.

---
 indra/newview/llimfloatercontainer.cpp | 112 +++++++++++++++++----------------
 1 file changed, 57 insertions(+), 55 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index bd7d570154..b98558c47b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -825,62 +825,64 @@ void LLIMFloaterContainer::doToParticipants(const std::string& command, uuid_vec
 	if(selectedIDS.size() > 0)
 	{
 		const LLUUID& userID = selectedIDS.front();
-
-		if ("view_profile" == command)
-		{
-			LLAvatarActions::showProfile(userID);
-		}
-		else if("im" == command)
-		{
-			LLAvatarActions::startIM(userID);
-		}
-		else if("offer_teleport" == command)
-		{
-			LLAvatarActions::offerTeleport(selectedIDS);
-		}
-		else if("voice_call" == command)
-		{
-			LLAvatarActions::startCall(userID);
-		}
-		else if("chat_history" == command)
-		{
-			LLAvatarActions::viewChatHistory(userID);
-		}
-		else if("add_friend" == command)
-		{
-			LLAvatarActions::requestFriendshipDialog(userID);
-		}
-		else if("remove_friend" == command)
-		{
-			LLAvatarActions::removeFriendDialog(userID);
-		}
-		else if("invite_to_group" == command)
-		{
-			LLAvatarActions::inviteToGroup(userID);
-		}
-		else if("map" == command)
-		{
-			LLAvatarActions::showOnMap(userID);
-		}
-		else if("share" == command)
-		{
-			LLAvatarActions::share(userID);
-		}
-		else if("pay" == command)
+		if(gAgent.getID() != userID)
 		{
-			LLAvatarActions::pay(userID);
-		}
-		else if("block_unblock" == command)
-		{
-			LLAvatarActions::toggleBlock(userID);
-		}
-		else if("selected" == command || "mute_all" == command || "unmute_all" == command)
-		{
-			moderateVoice(command, userID);
-		}
-		else if ("toggle_allow_text_chat" == command)
-		{
-			toggleAllowTextChat(userID);
+			if ("view_profile" == command)
+			{
+				LLAvatarActions::showProfile(userID);
+			}
+			else if("im" == command)
+			{
+				LLAvatarActions::startIM(userID);
+			}
+			else if("offer_teleport" == command)
+			{
+				LLAvatarActions::offerTeleport(selectedIDS);
+			}
+			else if("voice_call" == command)
+			{
+				LLAvatarActions::startCall(userID);
+			}
+			else if("chat_history" == command)
+			{
+				LLAvatarActions::viewChatHistory(userID);
+			}
+			else if("add_friend" == command)
+			{
+				LLAvatarActions::requestFriendshipDialog(userID);
+			}
+			else if("remove_friend" == command)
+			{
+				LLAvatarActions::removeFriendDialog(userID);
+			}
+			else if("invite_to_group" == command)
+			{
+				LLAvatarActions::inviteToGroup(userID);
+			}
+			else if("map" == command)
+			{
+				LLAvatarActions::showOnMap(userID);
+			}
+			else if("share" == command)
+			{
+				LLAvatarActions::share(userID);
+			}
+			else if("pay" == command)
+			{
+				LLAvatarActions::pay(userID);
+			}
+			else if("block_unblock" == command)
+			{
+				LLAvatarActions::toggleBlock(userID);
+			}
+			else if("selected" == command || "mute_all" == command || "unmute_all" == command)
+			{
+				moderateVoice(command, userID);
+			}
+			else if ("toggle_allow_text_chat" == command)
+			{
+				toggleAllowTextChat(userID);
+			}
 		}
 	}
 }
-- 
cgit v1.2.3


From a815585fd7de0f5aba60739127f473fd9d22ccfc Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Fri, 26 Oct 2012 19:33:31 +0300
Subject: CHUI-439 (Conversation floater is automatically unminimized when a
 selected user is removed from nearby chat participant list after teleport)
 CHUI-438 (Conversation remains transparent after teleport with a participant
 selected in nearby chat)

---
 indra/llui/llfolderviewitem.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 0b04288950..4825fc613c 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1473,6 +1473,8 @@ void LLFolderViewFolder::destroyView()
 // doesn't delete it.
 void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
 {
+	if (item->isSelected())
+		getRoot()->clearSelection();
 	items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
 	if(it == mItems.end())
 	{
-- 
cgit v1.2.3


From 83562e059fdcf9f732bc8effba99d1e95d39cd36 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 26 Oct 2012 11:36:14 -0700
Subject: CHUI-383: Now a new conversation will not take focus. Instead a toast
 will appear. Problem: Each time a conversation was added, code would execute
 to add the conversation floater AND select the conversation. Resolution: This
 is no longer the expected behavior so adjusted LLIMFloater::addToHost() to
 only add a floater and not select/show the floater. If selection and/or
 showing is needed it seems to make sense that this is done outside
 LLIMFloater:addToHost().

---
 indra/newview/llimfloater.cpp          | 17 ++---------------
 indra/newview/llimfloater.h            |  2 +-
 indra/newview/llimfloatercontainer.cpp | 21 ++++++++++-----------
 3 files changed, 13 insertions(+), 27 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index e4032738a7..1af5def5f0 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -582,7 +582,7 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 	}
 }
 
-void LLIMFloater::addToHost(const LLUUID& session_id, const bool force)
+void LLIMFloater::addToHost(const LLUUID& session_id)
 {
 	if (!LLIMConversation::isChatMultiTab() || !gIMMgr->hasSession(session_id))
 	{
@@ -607,20 +607,7 @@ void LLIMFloater::addToHost(const LLUUID& session_id, const bool force)
 			LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
 			if (floater_container)
 			{
-				floater_container->addFloater(floater, TRUE, i_pt);
-			}
-		}
-
-		if (force)
-		{
-			if (floater_container && floater_container->getVisible())
-			{
-				floater->openFloater(floater->getKey());
-				floater->setVisible(TRUE);
-			}
-			else
-			{
-				floater->setVisible(FALSE);
+				floater_container->addFloater(floater, FALSE, i_pt);
 			}
 		}
 	}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 26daf00afd..8a0d6f10e0 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -72,7 +72,7 @@ public:
 
 	static LLIMFloater* findInstance(const LLUUID& session_id);
 	static LLIMFloater* getInstance(const LLUUID& session_id);
-	static void addToHost(const LLUUID& session_id, const bool force = false);
+	static void addToHost(const LLUUID& session_id);
 
 	// LLFloater overrides
 	/*virtual*/ void onClose(bool app_quitting);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index bd7d570154..71487eb382 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -98,8 +98,8 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	LLIMFloater::addToHost(session_id, true);
-	addConversationListItem(session_id, true);
+	LLIMFloater::addToHost(session_id);
+	addConversationListItem(session_id);
 }
 
 void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
@@ -109,8 +109,8 @@ void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std:
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	LLIMFloater::addToHost(session_id, true);
-	addConversationListItem(session_id, true);
+	LLIMFloater::addToHost(session_id);
+	addConversationListItem(session_id);
 }
 
 void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
@@ -1208,16 +1208,15 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWi
 		current_participant_model++;
 	}
 
-	if (isWidgetSelected)
-	{
-		selectConversation(uuid);
-	}
-	
 	// set the widget to minimized mode if conversations pane is collapsed
 	widget->toggleMinimizedMode(mConversationsPane->isCollapsed());
 
-	// scroll to newly added item
-	mConversationsRoot->scrollToShowSelection();
+    if (isWidgetSelected)
+    {
+        selectConversation(uuid);
+        // scroll to newly added item
+        mConversationsRoot->scrollToShowSelection();
+    }
 
 	return;
 }
-- 
cgit v1.2.3


From 1a1a0b91c0c4400ec3febac183124314f9226127 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 26 Oct 2012 16:49:22 -0700
Subject: CHUI-383: Realized that prior changes for this bug caused a regress.
 The regress was using the people panel or a notecard to start a im/call with
 a user. When doing this the conversation line item would not be focused.
 Resolution: Changed all calls to LLIMFloater::show() to
 LLIMFloaterContainer::showConversation(), which will first select the
 conversation line item and then show the corresponding conversation floater.

---
 indra/newview/llavataractions.cpp      | 6 +++---
 indra/newview/llchiclet.cpp            | 3 ++-
 indra/newview/llgroupactions.cpp       | 4 ++--
 indra/newview/llimfloatercontainer.cpp | 2 +-
 indra/newview/llinventorybridge.cpp    | 4 ++--
 indra/newview/llinventorypanel.cpp     | 4 ++--
 6 files changed, 12 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 7322b3bb0b..13262efb3b 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -56,6 +56,7 @@
 #include "llinventorybridge.h"
 #include "llinventorymodel.h"	// for gInventory.findCategoryUUIDForType
 #include "llinventorypanel.h"
+#include "llimfloatercontainer.h"
 #include "llimview.h"			// for gIMMgr
 #include "llmutelist.h"
 #include "llnotificationsutil.h"	// for LLNotificationsUtil
@@ -67,7 +68,6 @@
 #include "llviewerobjectlist.h"
 #include "llviewermessage.h"	// for handle_lure
 #include "llviewerregion.h"
-#include "llimfloater.h"
 #include "lltrans.h"
 #include "llcallingcard.h"
 #include "llslurl.h"			// IDEVO
@@ -184,7 +184,7 @@ static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
 	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id);
 	if (session_id != LLUUID::null)
 	{
-		LLIMFloater::show(session_id);
+		LLIMFloaterContainer::getInstance()->showConversation(session_id);
 	}
 	make_ui_sound("UISndStartIM");
 }
@@ -302,7 +302,7 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
 		return;
 	}
 	
-	LLIMFloater::show(session_id);
+	LLIMFloaterContainer::getInstance()->showConversation(session_id);
 	
 	make_ui_sound("UISndStartIM");
 }
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 17181edffc..e328186fd6 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -34,6 +34,7 @@
 #include "llgroupactions.h"
 #include "lliconctrl.h"
 #include "llimfloater.h"
+#include "llimfloatercontainer.h"
 #include "llimview.h"
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
@@ -1196,7 +1197,7 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
 			chiclet->setShowSpeaker(true);
 			if (gSavedSettings.getBOOL("OpenIMOnVoice"))
 			{
-				LLIMFloater::show(chiclet->getSessionId());
+				LLIMFloaterContainer::getInstance()->showConversation(session_id);
 			}
 		}
 	}
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 623ebb76f2..15eca39bce 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -36,10 +36,10 @@
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llgroupmgr.h"
+#include "llimfloatercontainer.h"
 #include "llimview.h" // for gIMMgr
 #include "llnotificationsutil.h"
 #include "llstatusbar.h"	// can_afford_transaction()
-#include "llimfloater.h"
 #include "groupchatlistener.h"
 
 //
@@ -335,7 +335,7 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id)
 			group_id);
 		if (session_id != LLUUID::null)
 		{
-			LLIMFloater::show(session_id);
+			LLIMFloaterContainer::getInstance()->showConversation(session_id);
 		}
 		make_ui_sound("UISndStartIM");
 		return session_id;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 6377ffeecf..4d2201ebb9 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -128,7 +128,7 @@ void LLIMFloaterContainer::onCurrentChannelChanged(const LLUUID& session_id)
 {
     if (session_id != LLUUID::null)
     {
-    	LLIMFloater::show(session_id);
+    	LLIMFloaterContainer::getInstance()->showConversation(session_id);
     }
 }
 
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 28c2edbe84..5d8d82b226 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -46,7 +46,7 @@
 #include "llfriendcard.h"
 #include "llgesturemgr.h"
 #include "llgiveinventory.h" 
-#include "llimfloater.h"
+#include "llimfloatercontainer.h"
 #include "llimview.h"
 #include "llclipboard.h"
 #include "llinventorydefines.h"
@@ -4704,7 +4704,7 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
 			LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID());
 			if (session_id != LLUUID::null)
 			{
-				LLIMFloater::show(session_id);
+				LLIMFloaterContainer::getInstance()->showConversation(session_id);
 			}
 		}
 	}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index a8d99ad7de..dafc71b59c 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -39,7 +39,7 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llfolderview.h"
 #include "llfolderviewitem.h"
-#include "llimfloater.h"
+#include "llimfloatercontainer.h"
 #include "llimview.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
@@ -1087,7 +1087,7 @@ bool LLInventoryPanel::beginIMSession()
 	LLUUID session_id = gIMMgr->addSession(name, type, members[0], members);
 	if (session_id != LLUUID::null)
 	{
-		LLIMFloater::show(session_id);
+		LLIMFloaterContainer::getInstance()->showConversation(session_id);
 	}
 		
 	return true;
-- 
cgit v1.2.3


From 36b1b4c4b6bbae641271b6b1668e1fea4629d899 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 26 Oct 2012 17:04:17 -0700
Subject: CHUI-465 : Add event handling for LLIMConversation participant list

---
 indra/newview/llimconversation.cpp     | 96 +++++++++++++++++++---------------
 indra/newview/llimconversation.h       |  4 ++
 indra/newview/llimfloatercontainer.cpp | 23 ++++++--
 3 files changed, 78 insertions(+), 45 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 532f1be6a8..cc5adfc2e8 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -137,16 +137,12 @@ BOOL LLIMConversation::postBuild()
 	// Create a root view folder for all participants
 	LLConversationItem* base_item = new LLConversationItem(mConversationViewModel);
     LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
-    //p.name = getName();
-    //p.title = getLabel();
     p.rect = LLRect(0, 0, getRect().getWidth(), 0);
     p.parent_panel = mParticipantListPanel;
-    //p.tool_tip = p.name;
     p.listener = base_item;
     p.view_model = &mConversationViewModel;
     p.root = NULL;
     p.use_ellipses = true;
-    //p.options_menu = "menu_conversation.xml";
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
     mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 	
@@ -157,6 +153,8 @@ BOOL LLIMConversation::postBuild()
 	scroller_params.rect(scroller_view_rect);
 	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
 	scroller->setFollowsAll();
+	
+	// Insert that scroller into the panel widgets hierarchy and folder view
 	mParticipantListPanel->addChild(scroller);
 	scroller->addChild(mConversationsRoot);
 	mConversationsRoot->setScrollContainer(scroller);
@@ -311,72 +309,86 @@ void LLIMConversation::appendMessage(const LLChat& chat, const LLSD &args)
 
 void LLIMConversation::buildParticipantList()
 {
-	/*
-	if (mIsNearbyChat)
-	{
-		LLLocalSpeakerMgr* speaker_manager = LLLocalSpeakerMgr::getInstance();
-		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), mConversationViewModel, true, false);
-	}
-	else
-	{
-		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		// for group and ad-hoc chat we need to include agent into list
-		if(!mIsP2PChat && mSessionID.notNull() && speaker_manager)
-		{
-			delete mParticipantList; // remove the old list and create a new one if the session id has changed
-			mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), mConversationViewModel, true, false);
-		}
-	}
-	*/
-
-	// Create the participants widgets now
-	// Note: inspired from LLIMFloaterContainer::addConversationListItem()
+	// Get the model list
 	LLParticipantList* item = getParticipantList();
 	if (!item)
 	{
-		llinfos << "Merov debug : buildParticipantList, no list!" << llendl;
+		// Nothing to do if the model list is empty
 		return;
 	}
+
+	// Create the participants widgets now
 	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
 	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
 	while (current_participant_model != end_participant_model)
 	{
 		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
-		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
-		participant_view->addToFolder(mConversationsRoot);	// ! Not sure about that. TBC...
-		participant_view->setVisible(TRUE);
+		addConversationViewParticipant(participant_model);
 		current_participant_model++;
 	}
-	
-	//updateHeaderAndToolbar();
 }
 
 void LLIMConversation::addConversationViewParticipant(LLConversationItem* participant_model)
 {
 	// Check if the model already has an associated view
-	llinfos << "Merov debug : addConversationViewParticipant(). We need to check the existence!!!" << llendl;
+	LLUUID uuid = participant_model->getUUID();
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
 	
-	// Create the participant view and attach it to the root
-	LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
-	participant_view->addToFolder(mConversationsRoot);	// ! Not sure about that. TBC...
-	participant_view->setVisible(TRUE);	
+	// If not already present, create the participant view and attach it to the root, otherwise, just refresh it
+	if (widget)
+	{
+		updateConversationViewParticipant(uuid); // overkill?
+	}
+	else
+	{
+		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+		mConversationsWidgets[uuid] = widget;
+		participant_view->addToFolder(mConversationsRoot);
+		participant_view->setVisible(TRUE);
+		refreshConversation();
+	}
+}
+
+void LLIMConversation::removeConversationViewParticipant(const LLUUID& participant_id)
+{
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+	if (widget)
+	{
+		mConversationsRoot->extractItem(widget);
+		delete widget;
+		mConversationsWidgets.erase(participant_id);
+		refreshConversation();
+	}
+}
+
+void LLIMConversation::updateConversationViewParticipant(const LLUUID& participant_id)
+{
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+	if (widget)
+	{
+		widget->refresh();
+		refreshConversation();
+	}
+}
+
+void LLIMConversation::refreshConversation()
+{
+	// *TODO: update the conversation name
+	// *TODO: check that all participant models do have a view (this is a consistency check)
+	mConversationViewModel.requestSortAll();
+	mConversationsRoot->arrangeAll();
 }
 
 // Copied from LLIMFloaterContainer::createConversationViewParticipant(). Refactor opportunity!
 LLConversationViewParticipant* LLIMConversation::createConversationViewParticipant(LLConversationItem* item)
 {
-	LLConversationViewParticipant::Params params;
     LLRect panel_rect = mParticipantListPanel->getRect();
 	
+	LLConversationViewParticipant::Params params;
 	params.name = item->getDisplayName();
-	//params.icon = bridge->getIcon();
-	//params.icon_open = bridge->getOpenIcon();
-	//params.creation_date = bridge->getCreationDate();
 	params.root = mConversationsRoot;
 	params.listener = item;
-	
-    //24 is the the current hight of an item (itemHeight) loaded from conversation_view_participant.xml.
-	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
+	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); // *TODO: use conversation_view_participant.xml itemHeight value in lieu of 24
 	params.tool_tip = params.name;
 	params.participant_id = item->getUUID();
 	
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 09d0016946..a2e56bb2ef 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -72,7 +72,11 @@ public:
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
 	
+	// Handle the left hand participant list widgets
 	void addConversationViewParticipant(LLConversationItem* item);
+	void removeConversationViewParticipant(const LLUUID& participant_id);
+	void updateConversationViewParticipant(const LLUUID& participant_id);
+	void refreshConversation();
 
 protected:
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 0d62630b31..7159b13c8c 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -408,7 +408,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	// For debug only
 	//std::ostringstream llsd_value;
 	//llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
-	//llinfos << "Merov debug : onConversationModelEvent, event = " << llsd_value.str() << llendl;
+	//llinfos << "LLIMFloaterContainer::onConversationModelEvent, event = " << llsd_value.str() << llendl;
 	// end debug
 	
 	// Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
@@ -425,7 +425,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,session_id));
 	if (!session_view)
 	{
-		// We skip events that are not associated to a session
+		// We skip events that are not associated with a session
 		return false;
 	}
 	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
@@ -433,6 +433,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 
 	if (type == "remove_participant")
 	{
+		// Remove a participant view from the hierarchical conversation list
 		if (participant_view)
 		{
 			session_view->extractItem(participant_view);
@@ -440,18 +441,24 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 			session_view->refresh();
 			mConversationsRoot->arrangeAll();
 		}
+		// Remove a participant view from the conversation floater 
+		if (conversation_floater)
+		{
+			conversation_floater->removeConversationViewParticipant(participant_id);
+		}
 	}
 	else if (type == "add_participant")
 	{
 		LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
 		LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL);
+		// Add a participant view to the hierarchical conversation list
 		if (!participant_view && session_model && participant_model)
 		{
 			participant_view = createConversationViewParticipant(participant_model);
 			participant_view->addToFolder(session_view);
 			participant_view->setVisible(TRUE);
 		}
-		// CHUI-441 : 
+		// Add a participant view to the conversation floater 
 		if (conversation_floater && participant_model)
 		{
 			conversation_floater->addConversationViewParticipant(participant_model);
@@ -459,14 +466,24 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 	}
 	else if (type == "update_participant")
 	{
+		// Update the participant view in the hierarchical conversation list
 		if (participant_view)
 		{
 			participant_view->refresh();
 		}
+		// Update the participant view in the conversation floater 
+		if (conversation_floater)
+		{
+			conversation_floater->updateConversationViewParticipant(participant_id);
+		}
 	}
 	else if (type == "update_session")
 	{
 		session_view->refresh();
+		if (conversation_floater)
+		{
+			conversation_floater->refreshConversation();
+		}
 	}
 	
 	mConversationViewModel.requestSortAll();
-- 
cgit v1.2.3


From 09282019ef4d068fe95a94931bf341d8e84f29ea Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 26 Oct 2012 19:12:19 -0700
Subject: CHUI-469 : WIP : Add participants to the nearby chat torn off panel

---
 indra/newview/llimconversation.cpp     |  4 ++--
 indra/newview/llimconversation.h       |  2 +-
 indra/newview/llimfloater.cpp          |  3 +--
 indra/newview/llimfloatercontainer.cpp | 10 +++++++---
 4 files changed, 11 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index cc5adfc2e8..ad34acd941 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -174,7 +174,7 @@ BOOL LLIMConversation::postBuild()
 
 	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 
-	buildParticipantList();
+	buildConversationViewParticipant();
 
 	updateHeaderAndToolbar();
 
@@ -307,7 +307,7 @@ void LLIMConversation::appendMessage(const LLChat& chat, const LLSD &args)
 }
 
 
-void LLIMConversation::buildParticipantList()
+void LLIMConversation::buildConversationViewParticipant()
 {
 	// Get the model list
 	LLParticipantList* item = getParticipantList();
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index a2e56bb2ef..4e66d000e6 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -77,6 +77,7 @@ public:
 	void removeConversationViewParticipant(const LLUUID& participant_id);
 	void updateConversationViewParticipant(const LLUUID& participant_id);
 	void refreshConversation();
+	void buildConversationViewParticipant();
 
 protected:
 
@@ -95,7 +96,6 @@ protected:
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
 
-	void buildParticipantList();
 	void onSortMenuItemClicked(const LLSD& userdata);
 
 	void hideOrShowTitle(); // toggle the floater's drag handle
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 8fbf691897..560b3fa60a 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -825,8 +825,7 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	if (mSessionID != im_session_id)
 	{
 		initIMSession(im_session_id);
-
-		buildParticipantList();
+		buildConversationViewParticipant();
 	}
 
 	initIMFloater();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 7159b13c8c..89dfd2e149 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -429,7 +429,7 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 		return false;
 	}
 	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
-    LLIMFloater *conversation_floater = LLIMFloater::findInstance(session_id);
+    LLIMConversation *conversation_floater = (session_id.isNull() ? (LLIMConversation*)(LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")) : (LLIMConversation*)(LLIMFloater::findInstance(session_id)));
 
 	if (type == "remove_participant")
 	{
@@ -830,7 +830,6 @@ void LLIMFloaterContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
     //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
     else if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
     {
-		llinfos << "Merov debug : getParticipantUUIDs, LLIMFloater::findInstance, id = " << conversationItem->getUUID() << llendl;
         LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
         LLUUID participantID = conversationFloater->getOtherParticipantUUID();
         selected_uuids.push_back(participantID);
@@ -906,7 +905,6 @@ void LLIMFloaterContainer::doToSelectedConversation(const std::string& command,
 {
     //Find the conversation floater associated with the selected id
     const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
-	llinfos << "Merov debug : doToSelectedConversation, LLIMFloater::findInstance, id = " << conversationItem->getUUID() << llendl;
     LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
 
     if(conversationFloater)
@@ -1234,6 +1232,12 @@ LLConversationItem* LLIMFloaterContainer::addConversationListItem(const LLUUID&
 		participant_view->addToFolder(widget);
 		current_participant_model++;
 	}
+	// Do that too for the conversation dialog
+    LLIMConversation *conversation_floater = (uuid.isNull() ? (LLIMConversation*)(LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")) : (LLIMConversation*)(LLIMFloater::findInstance(uuid)));
+	if (conversation_floater)
+	{
+		conversation_floater->buildConversationViewParticipant();
+	}
 
 	if (isWidgetSelected)
 	{
-- 
cgit v1.2.3


From 480c3a1acb32e98d0d64aaf7bb70e4d61e6882f6 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 29 Oct 2012 16:59:53 -0700
Subject: CHUI-469 : Fixed. Add the widget to its map, init the widget map
 consistently and correctly.

---
 indra/newview/llimconversation.cpp     | 18 +++++++++++++-----
 indra/newview/llimfloatercontainer.cpp |  1 -
 2 files changed, 13 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index ad34acd941..f2421dd78f 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -50,6 +50,7 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
   ,  mCloseBtn(NULL)
   ,  mSessionID(session_id.asUUID())
 //  , mParticipantList(NULL)
+  , mConversationsRoot(NULL)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
@@ -309,6 +310,15 @@ void LLIMConversation::appendMessage(const LLChat& chat, const LLSD &args)
 
 void LLIMConversation::buildConversationViewParticipant()
 {
+	// Clear the widget list since we are rebuilding afresh from the model
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	while (widget_it != mConversationsWidgets.end())
+	{
+		removeConversationViewParticipant(widget_it->first);
+		// Iterators are invalidated by erase so we need to pick begin again
+		widget_it = mConversationsWidgets.begin();
+	}
+	
 	// Get the model list
 	LLParticipantList* item = getParticipantList();
 	if (!item)
@@ -342,7 +352,7 @@ void LLIMConversation::addConversationViewParticipant(LLConversationItem* partic
 	else
 	{
 		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
-		mConversationsWidgets[uuid] = widget;
+		mConversationsWidgets[uuid] = participant_view;
 		participant_view->addToFolder(mConversationsRoot);
 		participant_view->setVisible(TRUE);
 		refreshConversation();
@@ -373,10 +383,10 @@ void LLIMConversation::updateConversationViewParticipant(const LLUUID& participa
 
 void LLIMConversation::refreshConversation()
 {
-	// *TODO: update the conversation name
-	// *TODO: check that all participant models do have a view (this is a consistency check)
+	// *TODO: check that all participant models do have a view (debug consistency check)
 	mConversationViewModel.requestSortAll();
 	mConversationsRoot->arrangeAll();
+	mConversationsRoot->update();
 }
 
 // Copied from LLIMFloaterContainer::createConversationViewParticipant(). Refactor opportunity!
@@ -392,8 +402,6 @@ LLConversationViewParticipant* LLIMConversation::createConversationViewParticipa
 	params.tool_tip = params.name;
 	params.participant_id = item->getUUID();
 	
-	llinfos << "Merov debug : LLIMConversation, create participant, name = " << item->getDisplayName() << llendl;
-	
 	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
 }
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 89dfd2e149..297db96c83 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -129,7 +129,6 @@ void LLIMFloaterContainer::onCurrentChannelChanged(const LLUUID& session_id)
 {
     if (session_id != LLUUID::null)
     {
-		llinfos << "Merov debug : onCurrentChannelChanged, LLIMFloater::show, id = " << session_id << llendl;
     	LLIMFloater::show(session_id);
     }
 }
-- 
cgit v1.2.3


From c0b1ae6d976a94918ea8adc0908eb7c1e3d11459 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 30 Oct 2012 17:28:39 +0200
Subject: CHUI-446 FIXED Check that parent_session is not null

---
 indra/newview/llconversationmodel.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index f0c8658cfe..67a1aed675 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -401,12 +401,13 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
 	mNeedsRefresh = true;
 	LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
-	if (parent_session)
+	if (parent_session != NULL)
 	{
 		parent_session->requestSort();
 		parent_session->updateParticipantName(this);
+		postEvent("update_participant", parent_session, this);
 	}
-	postEvent("update_participant", parent_session, this);
+
 }
 
 void LLConversationItemParticipant::dumpDebugData()
-- 
cgit v1.2.3


From d2087bdd8a6591cafc6c8d8de7582a9dda6ea352 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Tue, 30 Oct 2012 18:16:56 +0200
Subject: CHUI-437 (Conversation floater shows as transparent after being
 minimized and unminimized)

---
 indra/newview/llimfloatercontainer.cpp | 14 --------------
 indra/newview/llimfloatercontainer.h   |  2 --
 2 files changed, 16 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index b98558c47b..83233cdd13 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -343,20 +343,6 @@ LLIMFloaterContainer* LLIMFloaterContainer::getInstance()
 	return LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
 }
 
-void LLIMFloaterContainer::setMinimized(BOOL b)
-{
-	if (isMinimized() == b) return;
-	
-	LLMultiFloater::setMinimized(b);
-
-	if (isMinimized()) return;
-
-	if (getActiveFloater())
-	{
-		getActiveFloater()->setVisible(TRUE);
-	}
-}
-
 // Update all participants in the conversation lists
 void LLIMFloaterContainer::processParticipantsStyleUpdate()
 {
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 7d13b37b31..05ea94019b 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -76,8 +76,6 @@ public:
 
 	static void onCurrentChannelChanged(const LLUUID& session_id);
 
-	virtual void setMinimized(BOOL b);
-
 	void collapseMessagesPane(bool collapse);
 	
 	// Callbacks
-- 
cgit v1.2.3


From 5215bf6edef283cb6c570d3e7aea11f0ecf8313f Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 30 Oct 2012 18:38:59 +0200
Subject: CHUI-415 FIXED  Set focus to dependee floater before removing
 dependent floater from it

---
 indra/llui/llfloater.cpp | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 58b17f74a8..8f7d4afb1b 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -725,7 +725,27 @@ void LLFloater::closeFloater(bool app_quitting)
 			make_ui_sound("UISndWindowClose");
 		}
 
-        //If floater is a dependent, remove it from parent (dependee)
+		gFocusMgr.clearLastFocusForGroup(this);
+
+			if (hasFocus())
+			{
+				// Do this early, so UI controls will commit before the
+				// window is taken down.
+				releaseFocus();
+
+				// give focus to dependee floater if it exists, and we had focus first
+				if (isDependent())
+				{
+					LLFloater* dependee = mDependeeHandle.get();
+					if (dependee && !dependee->isDead())
+					{
+						dependee->setFocus(TRUE);
+					}
+				}
+			}
+
+
+		//If floater is a dependent, remove it from parent (dependee)
         LLFloater* dependee = mDependeeHandle.get();
         if (dependee)
         {
@@ -750,24 +770,6 @@ void LLFloater::closeFloater(bool app_quitting)
 		}
 		
 		cleanupHandles();
-		gFocusMgr.clearLastFocusForGroup(this);
-
-		if (hasFocus())
-		{
-			// Do this early, so UI controls will commit before the
-			// window is taken down.
-			releaseFocus();
-
-			// give focus to dependee floater if it exists, and we had focus first
-			if (isDependent())
-			{
-				LLFloater* dependee = mDependeeHandle.get();
-				if (dependee && !dependee->isDead())
-				{
-					dependee->setFocus(TRUE);
-				}
-			}
-		}
 
 		dirtyRect();
 
-- 
cgit v1.2.3


From fb3df4790e27345a1e45f4a4675e756c1e551f21 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 30 Oct 2012 15:59:42 -0700
Subject: CHUI-459: Creating a fetchAvatarName() method for the
 LLConversationItemParticipant class to allow the class to query for the
 avatar display name directly.  Also, added a field to store the avatar name
 cache callback connection so that we can disconnect properly on object
 destruction to avoid a crash with the callback attempting to access recently
 freed memory.

---
 indra/newview/llconversationmodel.cpp  | 32 ++++++++++++++++++++++++++++++--
 indra/newview/llconversationmodel.h    | 12 +++++++++---
 indra/newview/llimfloatercontainer.cpp | 11 +----------
 indra/newview/llparticipantlist.cpp    |  3 +--
 4 files changed, 41 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 67a1aed675..33631a027b 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -369,7 +369,8 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 	LLConversationItem(display_name,uuid,root_view_model),
 	mIsMuted(false),
 	mIsModerator(false),
-	mDistToAgent(-1.0)
+	mDistToAgent(-1.0),
+	mAvatarNameCacheConnection()
 {
 	mConvType = CONV_PARTICIPANT;
 }
@@ -378,11 +379,38 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 	LLConversationItem(uuid,root_view_model),
 	mIsMuted(false),
 	mIsModerator(false),
-	mDistToAgent(-1.0)
+	mDistToAgent(-1.0),
+	mAvatarNameCacheConnection()
 {
 	mConvType = CONV_PARTICIPANT;
 }
 
+LLConversationItemParticipant::~LLConversationItemParticipant()
+{
+	// Disconnect any previous avatar name cache connection to ensure
+	// that the callback method is not called after destruction
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+}
+
+void LLConversationItemParticipant::fetchAvatarName()
+{
+	// Disconnect any previous avatar name cache connection
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	// Request the avatar name from the cache
+	llassert(getUUID().notNull());
+	if (getUUID().notNull())
+	{
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(getUUID(), boost::bind(&LLConversationItemParticipant::onAvatarNameCache, this, _2));
+	}
+}
+
 void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
     menuentry_vec_t items;
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 1d082852f5..481d46af58 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -27,9 +27,11 @@
 #ifndef LL_LLCONVERSATIONMODEL_H
 #define LL_LLCONVERSATIONMODEL_H
 
+#include <boost/signals2.hpp>
+
+#include "llavatarname.h"
 #include "llfolderviewitem.h"
 #include "llfolderviewmodel.h"
-#include "llavatarname.h"
 #include "llviewerfoldertype.h"
 
 // Implementation of conversations list
@@ -177,7 +179,7 @@ class LLConversationItemParticipant : public LLConversationItem
 public:
 	LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
-	virtual ~LLConversationItemParticipant() {}
+	virtual ~LLConversationItemParticipant();
 	
 	virtual const std::string& getDisplayName() const { return mDisplayName; }
 
@@ -189,17 +191,21 @@ public:
 	void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; }
 
     void buildContextMenu(LLMenuGL& menu, U32 flags);
-	void onAvatarNameCache(const LLAvatarName& av_name);
 
 	virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
 
+	void fetchAvatarName();
+
 	void dumpDebugData();
 
 private:
+	void onAvatarNameCache(const LLAvatarName& av_name);
+
 	bool mIsMuted;		// default is false
 	bool mIsModerator;	// default is false
 	std::string mDisplayName;
 	F64  mDistToAgent;  // Distance to the agent. A negative (meaningless) value means the distance has not been set.
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 // We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index f46ecd905a..00ae0b8fd8 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -358,16 +358,7 @@ void LLIMFloaterContainer::processParticipantsStyleUpdate()
 		{
 			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
 			// Get the avatar name for this participant id from the cache and update the model
-			LLUUID participant_id = participant_model->getUUID();
-			LLAvatarName av_name;
-			LLAvatarNameCache::get(participant_id,&av_name);
-			// Avoid updating the model though if the cache is still waiting for its first update
-			if (!av_name.mDisplayName.empty())
-			{
-				participant_model->onAvatarNameCache(av_name);
-			}
-			// Bind update to the next cache name signal
-			LLAvatarNameCache::get(participant_id, boost::bind(&LLConversationItemParticipant::onAvatarNameCache, participant_model, _2));
+			participant_model->fetchAvatarName();
 			// Next participant
 			current_participant_model++;
 		}
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index b263143bd1..e199cb5776 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -676,8 +676,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 ? LLTrans::getString("AvatarNameWaiting") : avatar_name.mDisplayName , avatar_id, mRootViewModel);
-		// Binds avatar's name update callback
-		LLAvatarNameCache::get(avatar_id, boost::bind(&LLConversationItemParticipant::onAvatarNameCache, participant, _2));
+		participant->fetchAvatarName();
 		if (mAvatarList)
 		{
 			mAvatarList->getIDs().push_back(avatar_id);
-- 
cgit v1.2.3


From ec57bd2f8e2859787b274c118fabbc19f76e04b1 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 30 Oct 2012 16:28:57 -0700
Subject: CHUI-461: Changing the default floater opacities according to Leo's
 guidelines.

---
 indra/newview/app_settings/settings.xml                         | 4 ++--
 indra/newview/skins/default/xui/en/panel_preferences_colors.xml | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9ada5e5918..0537487ca3 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -69,7 +69,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>0.95</real>
+      <real>1</real>
     </map>
     <key>AdvanceSnapshot</key>
     <map>
@@ -4302,7 +4302,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>0.65</real>
+      <real>0.95</real>
     </map>
     <key>InBandwidth</key>
     <map>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
index 2b22f0d6e3..9e825fe516 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
@@ -362,7 +362,7 @@
    follows="left|top"
    height="16"
    increment="0.01"
-   initial_value="0.8"
+   initial_value="1.0"
    layout="topleft"
    label_width="115"
    label="Active:"
@@ -380,7 +380,7 @@
    follows="left|top"
    height="16"
    increment="0.01"
-   initial_value="0.5"
+   initial_value="0.95"
    layout="topleft"
    label_width="115"
    label="Inactive:"
-- 
cgit v1.2.3


From 9d9853082361b35987a70574b422c40e8ee04d93 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 30 Oct 2012 18:20:28 -0700
Subject: CHUI-471: Adjusted conversationview so that indentation of the avatar
 icon is dependent upon getIndentation() instead of modifying avatar icon's
 left value.

---
 indra/newview/llconversationview.cpp                   | 18 +++++++++++++++++-
 indra/newview/llconversationview.h                     |  1 +
 indra/newview/llimfloatercontainer.cpp                 |  6 ++----
 .../xui/en/widgets/conversation_view_participant.xml   |  2 --
 4 files changed, 20 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 3082284991..81212a9141 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -432,6 +432,22 @@ void LLConversationViewParticipant::draw()
     LLView::draw();
 }
 
+// virtual
+S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
+{
+    //Need to call arrange first since it computes value used in getIndentation()
+    S32 arranged = LLFolderViewItem::arrange(width, height);
+
+    //Adjusts the avatar icon based upon the indentation
+    LLRect avatarRect(getIndentation(), 
+                        mAvatarIcon->getRect().mTop,
+                        getIndentation() + mAvatarIcon->getRect().getWidth(),
+                        mAvatarIcon->getRect().mBottom);
+    mAvatarIcon->setShape(avatarRect);
+
+    return arranged;
+}
+
 void LLConversationViewParticipant::selectItem()
 {
     LLConversationItem* vmi = this->getParentFolder() ? static_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
@@ -507,7 +523,7 @@ void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
 
 S32 LLConversationViewParticipant::getLabelXPos()
 {
-    return mAvatarIcon->getRect().mRight + mIconPad;
+    return getIndentation() + mAvatarIcon->getRect().getWidth() + mIconPad;
 }
 
 // static
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index bd95387bbe..18cb9bdb27 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -129,6 +129,7 @@ protected:
 	void initFromParams(const Params& params);
 	BOOL postBuild();
     /*virtual*/ void draw();
+    /*virtual*/ S32 arrange(S32* width, S32* height);
 	
 	void onInfoBtnClick();
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 01456fee3b..298a6055bf 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1289,9 +1289,6 @@ LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParti
     LLRect panel_rect = mConversationsListPanel->getRect();
 	
 	params.name = item->getDisplayName();
-	//params.icon = bridge->getIcon();
-	//params.icon_open = bridge->getOpenIcon();
-	//params.creation_date = bridge->getCreationDate();
 	params.root = mConversationsRoot;
 	params.listener = item;
 
@@ -1299,7 +1296,8 @@ LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParti
 	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
 	params.tool_tip = params.name;
 	params.participant_id = item->getUUID();
-	
+    params.folder_indentation = 42;
+
 	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
 }
 
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
index 0024decd4c..b83d9122f7 100755
--- a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <conversation_view_participant
   folder_arrow_image="Folder_Arrow"
-  folder_indentation="0"
   item_height="24" 
   item_top_pad="0"
   selection_image="Rounded_Square"
@@ -20,7 +19,6 @@
      height="20"
      default_icon_name="Generic_Person"
 	 layout="topleft"
-     left="50"
 	 top="2"
      width="20" />
 <info_button
-- 
cgit v1.2.3


From f9b1b440710668a9979e33c7582d79d14cae8d0d Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 30 Oct 2012 18:27:56 -0700
Subject: CHUI-463 : Fixed. Allowed a model to be shared by several views.

---
 indra/llui/llfolderviewitem.cpp       | 26 +++++++++++++++++++-------
 indra/llui/llfolderviewmodel.h        |  2 ++
 indra/newview/llconversationmodel.cpp |  2 +-
 3 files changed, 22 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 5d4c27ee6c..b289581dc2 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1563,7 +1563,7 @@ BOOL LLFolderViewFolder::isRemovable()
 void LLFolderViewFolder::addItem(LLFolderViewItem* item)
 {
 	if (item->getParentFolder())
-{
+	{
 		item->getParentFolder()->extractItem(item);
 	}
 	item->setParentFolder(this);
@@ -1574,7 +1574,13 @@ void LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	item->setVisible(FALSE);
 	
 	addChild(item);
-	getViewModelItem()->addChild(item->getViewModelItem());
+
+	// When the model is already hooked into a hierarchy (i.e. has a parent), do not reparent it
+	// Note: this happens when models are created before views or shared between views
+	if (!item->getViewModelItem()->hasParent())
+	{
+		getViewModelItem()->addChild(item->getViewModelItem());
+	}
 	
 	//TODO RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
 	//// Traverse parent folders and update creation date and resort, if necessary
@@ -1593,11 +1599,11 @@ void LLFolderViewFolder::addItem(LLFolderViewItem* item)
 
 // this is an internal method used for adding items to folders. 
 void LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
-	{
+{
 	if (folder->mParentFolder)
-		{
+	{
 		folder->mParentFolder->extractItem(folder);
-		}
+	}
 	folder->mParentFolder = this;
 	mFolders.push_back(folder);
 	folder->setOrigin(0, 0);
@@ -1607,9 +1613,15 @@ void LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 	//folder->requestArrange();
 	//requestSort();
 
-	addChild( folder );
-	getViewModelItem()->addChild(folder->getViewModelItem());
+	addChild(folder);
+
+	// When the model is already hooked into a hierarchy (i.e. has a parent), do not reparent it
+	// Note: this happens when models are created before views or shared between views
+	if (!folder->getViewModelItem()->hasParent())
+	{
+		getViewModelItem()->addChild(folder->getViewModelItem());
 	}
+}
 
 void LLFolderViewFolder::requestArrange()
 { 
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 5ec08ae211..7019857c0f 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -202,6 +202,7 @@ public:
 	virtual S32 getSortVersion() = 0;
 	virtual void setSortVersion(S32 version) = 0;
 	virtual void setParent(LLFolderViewModelItem* parent) = 0;
+	virtual bool hasParent() = 0;
 
 protected:
 
@@ -332,6 +333,7 @@ public:
 
 protected:
 	virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
+	virtual bool hasParent() { return mParent != NULL; }
 
 	S32						mSortVersion;
 	bool					mPassedFilter;
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index f0c8658cfe..74188195f6 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -405,8 +405,8 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	{
 		parent_session->requestSort();
 		parent_session->updateParticipantName(this);
+		postEvent("update_participant", parent_session, this);
 	}
-	postEvent("update_participant", parent_session, this);
 }
 
 void LLConversationItemParticipant::dumpDebugData()
-- 
cgit v1.2.3


From a8ca9dc5a98d0bd99581d17be45a36c602ce87fd Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 31 Oct 2012 17:51:55 +0200
Subject: CHUI-374 ADD. FIX, CHUI-442 FIXED (Nearby chat is torn off and cannot
 be docked if nearby chat is received while conversation floater is closed) -
 implement. lazy creating of container

---
 indra/newview/llchicletbar.cpp         |  2 +-
 indra/newview/llimconversation.cpp     | 49 ++++++++++++++++++++++++++++++++++
 indra/newview/llimconversation.h       | 11 ++++++++
 indra/newview/llimfloater.cpp          | 34 ++---------------------
 indra/newview/llimfloater.h            |  1 -
 indra/newview/llimfloatercontainer.cpp |  8 +++---
 indra/newview/llnearbychat.cpp         | 34 ++---------------------
 indra/newview/llnearbychat.h           |  5 +---
 8 files changed, 70 insertions(+), 74 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index 39f5d0b8f6..3ebb83b336 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -97,7 +97,7 @@ void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& nam
 	// Do not spawn chiclet when using the new multitab conversation UI
 	if (LLIMConversation::isChatMultiTab())
 	{
-		LLIMFloater::addToHost(session_id);
+		LLIMConversation::addToHost(session_id);
 		return;
 	}
 	
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 74bf8cb6fe..b687e18cae 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -116,6 +116,55 @@ LLIMConversation* LLIMConversation::getConversation(const LLUUID& uuid)
 	return conv;
 };
 
+void LLIMConversation::setVisible(BOOL visible)
+{
+	LLTransientDockableFloater::setVisible(visible);
+
+	if(visible)
+	{
+			LLIMConversation::addToHost(mSessionID);
+	}
+    setFocus(visible);
+}
+
+
+
+void LLIMConversation::addToHost(const LLUUID& session_id)
+{
+	if ((session_id.notNull() && !gIMMgr->hasSession(session_id))
+			|| !LLIMConversation::isChatMultiTab())
+	{
+		return;
+	}
+
+	// Get the floater: this will create the instance if it didn't exist
+	LLIMConversation* conversp = LLIMConversation::getConversation(session_id);
+	if (conversp)
+	{
+		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
+
+		// Do not add again existing floaters
+		if (floater_container && !conversp->isHostAttached())
+		{
+			conversp->setHostAttached(true);
+
+			if (!conversp->isNearbyChat()
+					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
+			{
+				floater_container->addFloater(conversp, TRUE, LLTabContainer::END);
+			}
+			else
+			{
+				// setting of the "potential" host for Nearby Chat: this sequence sets
+				// LLFloater::mHostHandle = NULL (a current host), but
+				// LLFloater::mLastHostHandle = floater_container (a "future" host)
+				conversp->setHost(floater_container);
+				conversp->setHost(NULL);
+			}
+
+		}
+	}
+}
 
 BOOL LLIMConversation::postBuild()
 {
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 603e0d0197..bff4cb4a31 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -59,17 +59,27 @@ public:
 	 */
 	static bool isChatMultiTab();
 
+	// add conversation to container
+	static void addToHost(const LLUUID& session_id);
+
+	bool isHostAttached() {return mIsHostAttached;}
+	void setHostAttached(bool is_attached) {mIsHostAttached = is_attached;}
+
     static LLIMConversation* findConversation(const LLUUID& uuid);
     static LLIMConversation* getConversation(const LLUUID& uuid);
 
 	// show/hide the translation check box
 	void showTranslationCheckbox(const BOOL visible = FALSE);
 
+	bool isNearbyChat() {return mIsNearbyChat;}
+
 	// LLFloater overrides
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
+	/*virtual*/ void setVisible(BOOL visible);
+
 
 protected:
 
@@ -139,6 +149,7 @@ private:
 	void reshapeChatHistory();
 
 	bool checkIfTornOff();
+    bool mIsHostAttached;
 
 	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
 };
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 1af5def5f0..3545b8ff18 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -582,37 +582,6 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 	}
 }
 
-void LLIMFloater::addToHost(const LLUUID& session_id)
-{
-	if (!LLIMConversation::isChatMultiTab() || !gIMMgr->hasSession(session_id))
-	{
-		return;
-	}
-
-	// Test the existence of the floater before we try to create it
-	bool exist = findInstance(session_id);
-
-	// Get the floater: this will create the instance if it didn't exist
-	LLIMFloater* floater = getInstance(session_id);
-	if (floater)
-	{
-
-		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
-
-		// Do not add again existing floaters
-		if (!exist)
-		{
-			//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
-			// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
-			LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
-			if (floater_container)
-			{
-				floater_container->addFloater(floater, FALSE, i_pt);
-			}
-		}
-	}
-}
-
 
 //static
 LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
@@ -721,7 +690,7 @@ void LLIMFloater::setVisible(BOOL visible)
 		(LLNotificationsUI::LLChannelManager::getInstance()->
 											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
 
-	LLTransientDockableFloater::setVisible(visible);
+	LLIMConversation::setVisible(visible);
 
 	// update notification channel state
 	if(channel)
@@ -1309,6 +1278,7 @@ void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
 	floater->removeTypingIndicator();
 }
 
+// static
 void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
 {
 	LLIMFloater::addToHost(session_id);
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 8a0d6f10e0..6c69ed3462 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -72,7 +72,6 @@ public:
 
 	static LLIMFloater* findInstance(const LLUUID& session_id);
 	static LLIMFloater* getInstance(const LLUUID& session_id);
-	static void addToHost(const LLUUID& session_id);
 
 	// LLFloater overrides
 	/*virtual*/ void onClose(bool app_quitting);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 00ae0b8fd8..65dc024aea 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -98,7 +98,7 @@ LLIMFloaterContainer::~LLIMFloaterContainer()
 
 void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	LLIMFloater::addToHost(session_id);
+	LLIMConversation::addToHost(session_id);
 	addConversationListItem(session_id);
 }
 
@@ -109,7 +109,7 @@ void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std:
 
 void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	LLIMFloater::addToHost(session_id);
+	LLIMConversation::addToHost(session_id);
 	addConversationListItem(session_id);
 }
 
@@ -490,9 +490,9 @@ void LLIMFloaterContainer::setVisible(BOOL visible)
 	}
 
 	nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
-	if (nearby_chat && !nearby_chat->isHostSet())
+	if (nearby_chat)
 	{
-		nearby_chat->addToHost();
+		LLIMConversation::addToHost(LLUUID());
 	}
 
 	// We need to show/hide all the associated conversations that have been torn off
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 5b274dd389..d1c7c6bfd7 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -91,8 +91,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& llsd)
 :	LLIMConversation(llsd),
 	//mOutputMonitor(NULL),
 	mSpeakerMgr(NULL),
-	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT),
-	mIsHostSet(false)
+	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
 {
     mIsP2PChat = false;
 	mIsNearbyChat = true;
@@ -283,7 +282,7 @@ void LLNearbyChat::setFocus(BOOL focusFlag)
     
 }
 
-void	LLNearbyChat::setVisible(BOOL visible)
+void LLNearbyChat::setVisible(BOOL visible)
 {
 	LLIMConversation::setVisible(visible);
 
@@ -304,35 +303,6 @@ void LLNearbyChat::onTearOffClicked()
 	gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
 }
 
-void LLNearbyChat::addToHost()
-{
-	if ( LLIMConversation::isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-		if (im_box)
-		{
-			if (gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
-			{
-				im_box->addFloater(this, TRUE, LLTabContainer::END);
-			}
-			else
-			{
-				// setting of the "potential" host: this sequence sets
-				// LLFloater::mHostHandle = NULL (a current host), but
-				// LLFloater::mLastHostHandle = im_box (a "future" host)
-				setHost(im_box);
-				setHost(NULL);
-			}
-		}
-
-		mIsHostSet = true;
-	}
-	}
-
-bool LLNearbyChat::isHostSet()
-{
-    return mIsHostSet;
-}
 
 // virtual
 void LLNearbyChat::onOpen(const LLSD& key)
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 7ada4daea8..b155fd3c26 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -53,7 +53,7 @@ public:
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
     /*virtual*/ void setFocus(BOOL focusFlag);
-	/*virtual*/ void	setVisible(BOOL visible);
+	/*virtual*/ void setVisible(BOOL visible);
 
 	void loadHistory();
     void reloadMessages();
@@ -78,8 +78,6 @@ public:
 	static void startChat(const char* line);
 	static void stopChat();
 
-	bool isHostSet();
-
 	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
 	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
 
@@ -121,7 +119,6 @@ private:
 	LLHandle<LLView>	mPopupMenuHandle;
 	std::vector<LLChat> mMessageArchive;
 
-    bool mIsHostSet;
 };
 
 #endif
-- 
cgit v1.2.3


From 7f2ea292e10b10958b3e00a641b50b194f131e41 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 31 Oct 2012 19:27:41 -0700
Subject: CHUI-474 : Fixed. Refresh the participants list in torn off dialog
 more often.

---
 indra/llui/llfolderview.cpp        |  2 +-
 indra/newview/llimconversation.cpp | 40 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index c31a832141..a33ffc4240 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -566,7 +566,7 @@ void LLFolderView::sanitizeSelection()
 				parent_folder;
 				parent_folder = parent_folder->getParentFolder())
 			{
-				if (parent_folder->getViewModelItem()->potentiallyVisible())
+				if (parent_folder->getViewModelItem() && parent_folder->getViewModelItem()->potentiallyVisible())
 				{
 					// give initial selection to first ancestor folder that potentially passes the filter
 					if (!new_selection)
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 3b6294f43b..aee6642150 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -376,7 +376,44 @@ void LLIMConversation::updateConversationViewParticipant(const LLUUID& participa
 
 void LLIMConversation::refreshConversation()
 {
-	// *TODO: check that all participant models do have a view (debug consistency check)
+	// Debug : Check that all participant models do have a view (debug consistency check)
+	/*
+	LLParticipantList* item = getParticipantList();
+	llinfos << "Merov debug : Start consistency check" << llendl;
+	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+	while (current_participant_model != end_participant_model)
+	{
+		LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+		if (participant_model != NULL)
+		{
+			LLUUID uuid = participant_model->getUUID();
+			LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+			if (!widget)
+			{
+				llinfos << "Merov debug : Consistency error! Couldn't find widget for " << participant_model->getName() << llendl;
+			}
+			else 
+			{
+				llinfos << "Merov debug : Consistency check pass for " << participant_model->getName() << llendl;
+			}
+		}
+		else
+		{
+			llinfos << "Merov debug : Consistency check, skip non participant child" << llendl;
+		}
+		current_participant_model++;
+	}
+	llinfos << "Merov debug : End consistency check" << llendl;
+	 */
+		
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	while (widget_it != mConversationsWidgets.end())
+	{
+		widget_it->second->refresh();
+		widget_it->second->setVisible(TRUE);
+		++widget_it;
+	}
 	mConversationViewModel.requestSortAll();
 	mConversationsRoot->arrangeAll();
 	mConversationsRoot->update();
@@ -629,6 +666,7 @@ void LLIMConversation::onTearOffClicked()
     initRectControl();
 	LLFloater::onClickTearOff(this);
 	updateHeaderAndToolbar();
+	refreshConversation();
 }
 
 // static
-- 
cgit v1.2.3


From 51cabb2089244f170b307b436e0014a872a145ed Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 1 Nov 2012 13:56:25 +0200
Subject: CHUI-444 (Click target off when conversation list is minimized to
 icons)

---
 indra/llui/llfolderviewitem.cpp    | 4 ++--
 indra/llui/llfolderviewitem.h      | 1 +
 indra/newview/llconversationview.h | 2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 4825fc613c..7c63cad1b7 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1826,7 +1826,7 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
 	}
 	if( !handled )
 	{
-		if(mIndentation < x && x < mIndentation + mArrowSize + mTextPad)
+		if(mIndentation < x && x < mIndentation + (isMinimized() ? 0 : mArrowSize) + mTextPad)
 		{
 			toggleOpen();
 			handled = TRUE;
@@ -1850,7 +1850,7 @@ BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 	}
 	if( !handled )
 	{
-		if(mIndentation < x && x < mIndentation + mArrowSize + mTextPad)
+		if(mIndentation < x && x < mIndentation + (isMinimized() ? 0 : mArrowSize) + mTextPad)
 		{
 			// don't select when user double-clicks plus sign
 			// so as not to contradict single-click behavior
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index d4002c3184..7cbe70fb8b 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -289,6 +289,7 @@ protected:
 	friend class LLUICtrlFactory;
 
 	void updateLabelRotation();
+	virtual bool isMinimized() { return FALSE; }
 
 public:
 	typedef std::list<LLFolderViewItem*> items_t;
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index bd95387bbe..4d77a4ade0 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -69,6 +69,8 @@ public:
 
 	/*virtual*/ void toggleOpen();
 
+	/*virtual*/	bool isMinimized() { return mMinimizedMode; }
+
 	void toggleMinimizedMode(bool is_minimized);
 
 	void setVisibleIfDetached(BOOL visible);
-- 
cgit v1.2.3


From d886d89f53267d9a9a02c775fcb16e667278b904 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 1 Nov 2012 15:00:50 +0200
Subject: CHUI-446 FIXED Checkm mParent before using dynamic_cast

---
 indra/newview/llconversationmodel.cpp | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 33631a027b..47a82bfe17 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -428,14 +428,16 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
 	mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
 	mNeedsRefresh = true;
-	LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
-	if (parent_session != NULL)
+	if(mParent != NULL)
 	{
-		parent_session->requestSort();
-		parent_session->updateParticipantName(this);
-		postEvent("update_participant", parent_session, this);
+		LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+		if (parent_session != NULL)
+		{
+			parent_session->requestSort();
+			parent_session->updateParticipantName(this);
+			postEvent("update_participant", parent_session, this);
+		}
 	}
-
 }
 
 void LLConversationItemParticipant::dumpDebugData()
-- 
cgit v1.2.3


From 424a80155ac755bc0191ddd44ef125bdbda39fa5 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Thu, 1 Nov 2012 16:58:55 +0200
Subject: CHUI-445 FIXED Select the next conversation in the list when current
 conversation is deleted

---
 indra/newview/llimfloatercontainer.cpp | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 65dc024aea..f85aa9a353 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1206,6 +1206,7 @@ bool LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
 	bool isWidgetSelected = false;
+	LLFolderViewItem* new_selection = NULL;
 	conversations_widgets_map::iterator widget_it = mConversationsWidgets.find(uuid);
 	if (widget_it != mConversationsWidgets.end())
 	{
@@ -1213,6 +1214,11 @@ bool LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 		if (widget)
 		{
 			isWidgetSelected = widget->isSelected();
+			new_selection = mConversationsRoot->getNextFromChild(widget);
+			if(new_selection == NULL)
+			{
+				new_selection = mConversationsRoot->getPreviousFromChild(widget);
+			}
 			widget->destroyView();
 		}
 	}
@@ -1225,12 +1231,13 @@ bool LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	if (change_focus)
 	{
 		setFocus(TRUE);
-		conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
-		if (widget_it != mConversationsWidgets.end())
+		if(new_selection != NULL)
 		{
-            mSelectedSession = widget_it->first;
-			LLFolderViewItem* widget = widget_it->second;
-			widget->selectItem();
+			LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+			if(vmi != NULL)
+			{
+				selectConversation(vmi->getUUID());
+			}
 		}
 	}
 	return isWidgetSelected;
-- 
cgit v1.2.3


From 0f1c2f8aba148aa7e594d4c9e1bc6a95d34bd99b Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 1 Nov 2012 14:55:47 -0700
Subject: CHUI-472: Problem: Only the converation panel was user/auto
 resizeable but the participants panel was not. By one have only resizable
 this prevented both panels from being resized. Solution: Now set the
 participants panel to be user/auto resizable as well.

---
 indra/newview/skins/default/xui/en/floater_im_session.xml | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 84fba0a3b3..a889eb7933 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -14,7 +14,7 @@
  width="394"
  can_resize="true"
  can_tear_off="false"
- min_width="250"
+ min_width="340"
  min_height="190"
  positioning="relative">
     <floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string>
@@ -157,7 +157,8 @@
       min_width="115"
       width="150" 
       height="310" 
-      auto_resize="false">
+      user_resize="true"
+      auto_resize="true">
       </layout_panel>
     <layout_panel
        default_tab_group="3"
@@ -171,7 +172,8 @@
        user_resize="true"
        auto_resize="true"
        visible="true"
-       name="left_part_holder">
+       name="left_part_holder"
+       min_width="225">
         <panel
          name="trnsAndChat_panel"
          follows="all"
-- 
cgit v1.2.3


From ef5121ffb309c0317a4eb478e9527d33441377c2 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 2 Nov 2012 11:01:08 -0700
Subject: CHUI-481 : WIP : Make updateSessionName() a virtual method of
 LLIMConversation so we can eventually call it on events

---
 indra/newview/llimconversation.cpp |  6 +++++
 indra/newview/llimconversation.h   |  3 +++
 indra/newview/llimfloater.cpp      | 54 +++++++++++++++++++++++---------------
 indra/newview/llimfloater.h        |  4 +--
 4 files changed, 44 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index aee6642150..a6a246a01e 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -508,6 +508,12 @@ void LLIMConversation::hideOrShowTitle()
 	floater_contents->setShape(contents_rect);
 }
 
+void LLIMConversation::updateSessionName(const std::string& name)
+{
+	llinfos << "Merov debug : updateSessionName, name = " << name << llendl;
+	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
+}
+
 void LLIMConversation::hideAllStandardButtons()
 {
 	for (S32 i = 0; i < BUTTON_COUNT; i++)
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 4e66d000e6..2bd1582e87 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -104,6 +104,9 @@ protected:
 	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
 	void updateHeaderAndToolbar();
 
+	// Update the input field help text and other places that need the session name
+	virtual void updateSessionName(const std::string& name);
+
 	// set the enable/disable state for the Call button
 	virtual void enableDisableCallBtn();
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 6d90b6a0b2..4e1bfb4e77 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -243,7 +243,6 @@ void LLIMFloater::initIMSession(const LLUUID& session_id)
 	{
 		mIsP2PChat = mSession->isP2PSessionType();
 		mSessionInitialized = mSession->mSessionInitialized;
-
 		mDialog = mSession->mType;
 	}
 }
@@ -281,7 +280,7 @@ void LLIMFloater::initIMFloater()
 	else
 	{
 		std::string session_name(LLIMModel::instance().getName(mSessionID));
-		updateSessionName(session_name, session_name);
+		updateSessionName(session_name);
 
 		// For ad hoc conferences we should update the title with participants names.
 		if ((IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
@@ -292,6 +291,8 @@ void LLIMFloater::initIMFloater()
 				mParticipantsListRefreshConnection.disconnect();
 			}
 
+			// CHUI-441: We shouldn't have any avatar_list anymore... see floater_im_session.xml
+			// *TODO: Track and delete if not necessary anymore
 			LLAvatarList* avatar_list = getChild<LLAvatarList>("speakers_list");
 			mParticipantsListRefreshConnection = avatar_list->setRefreshCompleteCallback(
 					boost::bind(&LLIMFloater::onParticipantsListChanged, this, _1));
@@ -525,20 +526,21 @@ void LLIMFloater::onVoiceChannelStateChanged(
 	updateCallBtnState(callIsActive);
 }
 
-void LLIMFloater::updateSessionName(const std::string& ui_title,
-									const std::string& ui_label)
+void LLIMFloater::updateSessionName(const std::string& name)
 {
-	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + ui_label);
-	setTitle(ui_title);	
+	LLIMConversation::updateSessionName(name);
+	setTitle(name);	
 }
 
 void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
 									const LLAvatarName& av_name)
 {
-	// Use display name only for labels, as the extended name will be in the
-	// floater title
+	// Use display name for label
+	updateSessionName(av_name.mDisplayName);
+	
+	// Overwrite the floater title with the extended name
 	std::string ui_title = av_name.getCompleteName();
-	updateSessionName(ui_title, av_name.mDisplayName);
+	setTitle(ui_title);	
 	mTypingStart.setArg("[NAME]", ui_title);
 }
 
@@ -550,35 +552,45 @@ void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
 		return;
 	}
 
-	bool all_names_resolved = true;
 	std::vector<LLSD> participants_uuids;
 	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
+	LLUUID unfound_id;
 
 	avatar_list->getValues(participants_uuids);
 
-	// Check whether we have all participants names in LLAvatarNameCache
+	// Check participants names in LLAvatarNameCache
     for (std::vector<LLSD>::const_iterator it = participants_uuids.begin(); it != participants_uuids.end(); ++it)
 	{
 		const LLUUID& id = it->asUUID();
-		temp_uuids.push_back(id);
 		LLAvatarName av_name;
         if (!LLAvatarNameCache::get(id, &av_name))
         {
-			all_names_resolved = false;
-
-			// If a name is not found in cache, request it and continue the process recursively
-			// until all ids are resolved into names.
-			LLAvatarNameCache::get(id,
-					boost::bind(&LLIMFloater::onParticipantsListChanged, this, avatar_list));
-			break;
+			// Keep the first not found avatar id
+			if (unfound_id.isNull())
+			{
+				unfound_id = id;
+			}
         }
+		else
+		{
+			// Add the participant to the list of existing names
+			temp_uuids.push_back(id);
+		}
 	}
 
-	if (all_names_resolved)
+	if (temp_uuids.size() != 0)
 	{
+		// Build the session name and update it
 		std::string ui_title;
 		LLAvatarActions::buildResidentsString(temp_uuids, ui_title);
-		updateSessionName(ui_title, ui_title);
+		updateSessionName(ui_title);
+	}
+
+	if (unfound_id.notNull())
+	{
+		// If a name is not found in cache, request it and continue the process recursively
+		// until all ids are resolved into names.
+		LLAvatarNameCache::get(unfound_id, boost::bind(&LLIMFloater::onParticipantsListChanged, this, avatar_list));
 	}
 }
 
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 8a0d6f10e0..ec3a96f694 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -139,8 +139,8 @@ private:
 
 	/*virtual*/ void onClickCloseBtn();
 
-	// Update the window title, input field help text, etc.
-	void updateSessionName(const std::string& ui_title, const std::string& ui_label);
+	// Update the window title and input field help text
+	/*virtual*/ void updateSessionName(const std::string& name);
 
 	// For display name lookups for IM window titles
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-- 
cgit v1.2.3


From 6e2b3527cc95b92bf136b65fd2ee344d4c879faa Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 2 Nov 2012 13:22:48 -0700
Subject: CHUI-475: Ensuring that objects that query the avatar name cache with
 a callback store the connection and disconnect on object destruction.  This
 should help resolve some of the heap corruption we are seeing.

---
 indra/llui/llnotifications.cpp     | 24 ++++++++----
 indra/llui/llnotifications.h       | 22 +++++++++--
 indra/newview/llavatariconctrl.cpp | 29 ++++++++++++--
 indra/newview/llavatariconctrl.h   | 18 ++++++---
 indra/newview/llavatarlistitem.cpp | 34 +++++++++++++---
 indra/newview/llavatarlistitem.h   |  5 +++
 indra/newview/llchathistory.cpp    | 80 +++++++++++++++++++++++++-------------
 7 files changed, 157 insertions(+), 55 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index fdd45bd76f..929b7da081 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1787,22 +1787,18 @@ std::ostream& operator<<(std::ostream& s, const LLNotification& notification)
 	return s;
 }
 
-//static
-void LLPostponedNotification::lookupName(LLPostponedNotification* thiz,
-										 const LLUUID& id,
+void LLPostponedNotification::lookupName(const LLUUID& id,
 										 bool is_group)
 {
 	if (is_group)
 	{
 		gCacheName->getGroup(id,
 			boost::bind(&LLPostponedNotification::onGroupNameCache,
-				thiz, _1, _2, _3));
+				this, _1, _2, _3));
 	}
 	else
 	{
-		LLAvatarNameCache::get(id,
-			boost::bind(&LLPostponedNotification::onAvatarNameCache,
-				thiz, _1, _2));
+		fetchAvatarName(id);
 	}
 }
 
@@ -1813,6 +1809,20 @@ void LLPostponedNotification::onGroupNameCache(const LLUUID& id,
 	finalizeName(full_name);
 }
 
+void LLPostponedNotification::fetchAvatarName(const LLUUID& id)
+{
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	if (id.notNull())
+	{
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(id,
+			boost::bind(&LLPostponedNotification::onAvatarNameCache, this, _1, _2));
+	}
+}
+
 void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id,
 												const LLAvatarName& av_name)
 {
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 19b30b8973..c677dfe298 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -87,6 +87,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/enable_shared_from_this.hpp>
 #include <boost/type_traits.hpp>
+#include <boost/signals2.hpp>
 
 #include "llevents.h"
 #include "llfunctorregistry.h"
@@ -972,14 +973,15 @@ public:
 		thiz->mParams = params;
 
 		// Avoid header file dependency on llcachename.h
-		lookupName(thiz, id, is_group);
+		thiz->lookupName(id, is_group);
 	}
 
 private:
-	static void lookupName(LLPostponedNotification* thiz, const LLUUID& id, bool is_group);
+	void lookupName(const LLUUID& id, bool is_group);
 	// only used for groups
 	void onGroupNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
 	// only used for avatars
+	void fetchAvatarName(const LLUUID& id);
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
 	// used for both group and avatar names
 	void finalizeName(const std::string& name);
@@ -990,8 +992,19 @@ private:
 	}
 
 protected:
-	LLPostponedNotification() {}
-	virtual ~LLPostponedNotification() {}
+	LLPostponedNotification()
+		: mParams(),
+		mName(),
+		mAvatarNameCacheConnection()
+	{}
+
+	virtual ~LLPostponedNotification()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
 
 	/**
 	 * Abstract method provides possibility to modify notification parameters and
@@ -1002,6 +1015,7 @@ protected:
 
 	LLNotification::Params mParams;
 	std::string mName;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 // Stores only persistent notifications.
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 62c6c6763b..6355f0db56 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -28,6 +28,8 @@
 
 #include "llavatariconctrl.h"
 
+#include <boost/signals2.hpp>
+
 // viewer includes
 #include "llagent.h"
 #include "llavatarconstants.h"
@@ -148,9 +150,13 @@ LLAvatarIconCtrl::Params::Params()
 
 
 LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
-:	LLIconCtrl(p),
+	: LLIconCtrl(p),
+	LLAvatarPropertiesObserver(),
+	mAvatarId(),
+	mFullName(),
 	mDrawTooltip(p.draw_tooltip),
-	mDefaultIconName(p.default_icon_name)
+	mDefaultIconName(p.default_icon_name),
+	mAvatarNameCacheConnection()
 {
 	mPriority = LLViewerFetchedTexture::BOOST_ICON;
 	
@@ -203,6 +209,11 @@ LLAvatarIconCtrl::~LLAvatarIconCtrl()
 		LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
 		// Name callbacks will be automatically disconnected since LLUICtrl is trackable
 	}
+
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 //virtual
@@ -245,9 +256,19 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
 		LLIconCtrl::setValue(value);
 	}
 
-	if (mAvatarId != LLUUID::null)
+	fetchAvatarName();
+}
+
+void LLAvatarIconCtrl::fetchAvatarName()
+{
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	if (mAvatarId.notNull())
 	{
-		LLAvatarNameCache::get(mAvatarId, boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, this, _1, _2));
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, this, _1, _2));
 	}
 }
 
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index 7f568fc5b8..f55967926a 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -27,6 +27,8 @@
 #ifndef LL_LLAVATARICONCTRL_H
 #define LL_LLAVATARICONCTRL_H
 
+#include <boost/signals2.hpp>
+
 #include "lliconctrl.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llviewermenu.h"
@@ -86,20 +88,24 @@ public:
 	// LLAvatarPropertiesProcessor observer trigger
 	virtual void processProperties(void* data, EAvatarProcessorType type);
 
-	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-
 	const LLUUID&		getAvatarId() const	{ return mAvatarId; }
 	const std::string&	getFullName() const { return mFullName; }
 
 	void setDrawTooltip(bool value) { mDrawTooltip = value;}
 
 protected:
-	LLUUID				mAvatarId;
-	std::string			mFullName;
-	bool				mDrawTooltip;
-	std::string			mDefaultIconName;
+	LLUUID                      mAvatarId;
+	std::string                 mFullName;
+	bool                        mDrawTooltip;
+	std::string                 mDefaultIconName;
 
 	bool updateFromCache();
+
+private:
+	void fetchAvatarName();
+	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 #endif  // LL_LLAVATARICONCTRL_H
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 7b5229b5e6..7ff1b39573 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -27,6 +27,8 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include <boost/signals2.hpp>
+
 #include "llavataractions.h"
 #include "llavatarlistitem.h"
 
@@ -59,7 +61,8 @@ LLAvatarListItem::Params::Params()
 
 
 LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
-:	LLPanel(),
+	: LLPanel(),
+	LLFriendObserver(),
 	mAvatarIcon(NULL),
 	mAvatarName(NULL),
 	mLastInteractionTime(NULL),
@@ -74,7 +77,8 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
 	mShowInfoBtn(true),
 	mShowProfileBtn(true),
 	mShowPermissions(false),
-	mHovered(false)
+	mHovered(false),
+	mAvatarNameCacheConnection()
 {
 	if (not_from_ui_factory)
 	{
@@ -87,7 +91,14 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
 LLAvatarListItem::~LLAvatarListItem()
 {
 	if (mAvatarId.notNull())
+	{
 		LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarId, this);
+	}
+
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 BOOL  LLAvatarListItem::postBuild()
@@ -130,6 +141,19 @@ BOOL  LLAvatarListItem::postBuild()
 	return TRUE;
 }
 
+void LLAvatarListItem::fetchAvatarName()
+{
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	if (mAvatarId.notNull())
+	{
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+	}
+}
+
 S32 LLAvatarListItem::notifyParent(const LLSD& info)
 {
 	if (info.has("visibility_changed"))
@@ -260,8 +284,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b
 		mAvatarIcon->setValue(id);
 
 		// Set avatar name.
-		LLAvatarNameCache::get(id,
-			boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+		fetchAvatarName();
 	}
 }
 
@@ -414,8 +437,7 @@ std::string LLAvatarListItem::getAvatarToolTip() const
 
 void LLAvatarListItem::updateAvatarName()
 {
-	LLAvatarNameCache::get(getAvatarId(),
-			boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+	fetchAvatarName();
 }
 
 //== PRIVATE SECITON ==========================================================
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 28a50870d4..41853b6b51 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -27,6 +27,8 @@
 #ifndef LL_LLAVATARLISTITEM_H
 #define LL_LLAVATARLISTITEM_H
 
+#include <boost/signals2.hpp>
+
 #include "llpanel.h"
 #include "lloutputmonitorctrl.h"
 #include "llbutton.h"
@@ -217,6 +219,9 @@ private:
 
 	/// true when the mouse pointer is hovering over this item
 	bool mHovered;
+	
+	void fetchAvatarName();
+	boost::signals2::connection mAvatarNameCacheConnection;
 
 	static bool	sStaticInitialized; // this variable is introduced to improve code readability
 	static S32  sLeftPadding; // padding to first left visible child (icon or name)
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index c61a8c8562..605e3ece51 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -28,6 +28,8 @@
 
 #include "llchathistory.h"
 
+#include <boost/signals2.hpp>
+
 #include "llavatarnamecache.h"
 #include "llinstantmessage.h"
 
@@ -110,7 +112,8 @@ public:
 		mFrom(),
 		mSessionID(),
 		mMinUserNameWidth(0),
-		mUserNameFont(NULL)
+		mUserNameFont(NULL),
+		mAvatarNameCacheConnection()
 	{}
 
 	static LLChatHistoryHeader* createInstance(const std::string& file_name)
@@ -124,6 +127,11 @@ public:
 	{
 		// Detach the info button so that it doesn't get destroyed (EXT-8463).
 		hideInfoCtrl();
+
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
 	}
 
 	BOOL handleMouseUp(S32 x, S32 y, MASK mask)
@@ -283,8 +291,7 @@ public:
 			// Start with blank so sample data from XUI XML doesn't
 			// flash on the screen
 			user_name->setValue( LLSD() );
-			LLAvatarNameCache::get(mAvatarID,
-				boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2));
+			fetchAvatarName();
 		}
 		else if (chat.mChatStyle == CHAT_STYLE_HISTORY ||
 				 mSourceType == CHAT_SOURCE_AGENT)
@@ -416,31 +423,6 @@ public:
 		}
 	}
 
-	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
-	{
-		mFrom = av_name.mDisplayName;
-
-		LLTextBox* user_name = getChild<LLTextBox>("user_name");
-		user_name->setValue( LLSD(av_name.mDisplayName ) );
-		user_name->setToolTip( av_name.mUsername );
-
-		if (gSavedSettings.getBOOL("NameTagShowUsernames") && 
-			LLAvatarNameCache::useDisplayNames() &&
-			!av_name.mIsDisplayNameDefault)
-		{
-			LLStyle::Params style_params_name;
-			LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor");
-			style_params_name.color(userNameColor);
-			style_params_name.font.name("SansSerifSmall");
-			style_params_name.font.style("NORMAL");
-			style_params_name.readonly_color(userNameColor);
-			user_name->appendText("  - " + av_name.mUsername, FALSE, style_params_name);
-		}
-		setToolTip( av_name.mUsername );
-		// name might have changed, update width
-		updateMinUserNameWidth();
-	}
-
 protected:
 	static const S32 PADDING = 20;
 
@@ -555,6 +537,45 @@ private:
 		user_name->reshape(user_rect.getWidth() + delta_pos_x, user_rect.getHeight());
 	}
 
+	void fetchAvatarName()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		
+		if (mAvatarID.notNull())
+		{
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID,
+				boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2));
+		}
+	}
+
+	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+	{
+		mFrom = av_name.mDisplayName;
+
+		LLTextBox* user_name = getChild<LLTextBox>("user_name");
+		user_name->setValue( LLSD(av_name.mDisplayName ) );
+		user_name->setToolTip( av_name.mUsername );
+
+		if (gSavedSettings.getBOOL("NameTagShowUsernames") && 
+			LLAvatarNameCache::useDisplayNames() &&
+			!av_name.mIsDisplayNameDefault)
+		{
+			LLStyle::Params style_params_name;
+			LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor");
+			style_params_name.color(userNameColor);
+			style_params_name.font.name("SansSerifSmall");
+			style_params_name.font.style("NORMAL");
+			style_params_name.readonly_color(userNameColor);
+			user_name->appendText("  - " + av_name.mUsername, FALSE, style_params_name);
+		}
+		setToolTip( av_name.mUsername );
+		// name might have changed, update width
+		updateMinUserNameWidth();
+	}
+
 protected:
 	LLHandle<LLView>	mPopupMenuHandleAvatar;
 	LLHandle<LLView>	mPopupMenuHandleObject;
@@ -569,6 +590,9 @@ protected:
 
 	S32					mMinUserNameWidth;
 	const LLFontGL*		mUserNameFont;
+
+private:
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 LLUICtrl* LLChatHistoryHeader::sInfoCtrl = NULL;
-- 
cgit v1.2.3


From 4f6afb08d7f4c5ae721bd343999715bc22dfca8b Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 2 Nov 2012 16:22:19 -0700
Subject: CHUI-472: This is a fix for the following case: When a torn off
 floater has its conversation reduced to the minimum width, once re-docked the
 conversation does not expand. Solution: Discussed problem with Richard, and
 I'm submitting the changes required to fix the problem.

---
 indra/llui/lllayoutstack.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 1f2496a8e7..260f0bc92e 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -36,7 +36,7 @@
 #include "llcriticaldamp.h"
 #include "boost/foreach.hpp"
 
-static const F32 MIN_FRACTIONAL_SIZE = 0.0f;
+static const F32 MIN_FRACTIONAL_SIZE = 0.00001f;
 static const F32 MAX_FRACTIONAL_SIZE = 1.f;
 
 static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
@@ -71,7 +71,7 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
 	mCollapseAmt(0.f),
 	mVisibleAmt(1.f), // default to fully visible
 	mResizeBar(NULL),
-	mFractionalSize(MIN_FRACTIONAL_SIZE),
+	mFractionalSize(0.f),
 	mTargetDim(0),
 	mIgnoreReshape(false),
 	mOrientation(LLLayoutStack::HORIZONTAL)
@@ -521,7 +521,7 @@ void LLLayoutStack::updateFractionalSizes()
 	{
 		if (panelp->mAutoResize)
 		{
-			total_resizable_dim += llmax(0, panelp->getLayoutDim() - panelp->getRelevantMinDim());
+			total_resizable_dim += llmax(MIN_FRACTIONAL_SIZE, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim()));
 		}
 	}
 
@@ -767,7 +767,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 			{	// freeze new size as fraction
 				F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
 					? MAX_FRACTIONAL_SIZE
-					: llclamp(total_visible_fraction * (F32)(new_dim - (panelp->getRelevantMinDim() - 1)) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
 				fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
 				fraction_remaining -= panelp->mFractionalSize;
 				panelp->mFractionalSize = new_fractional_size;
-- 
cgit v1.2.3


From 7e74481f33d19f24bb596bab75298a720068a716 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 2 Nov 2012 18:00:19 -0700
Subject: This does not pertain to a CHUI bug fix but Richard took a look at
 the behavior of the layout stack test and found a mathematical bug that
 caused panels in a layout stack to jitter as they were resized. Submitting in
 this branch.

---
 indra/llui/lllayoutstack.cpp | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 260f0bc92e..0674275612 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -672,12 +672,12 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 	S32 new_dim = (mOrientation == HORIZONTAL)
 					? new_rect.getWidth()
 					: new_rect.getHeight();
-	S32 delta_dim = new_dim - resized_panel->getVisibleDim();
-	if (delta_dim == 0) return;
+	S32 delta_panel_dim = new_dim - resized_panel->getVisibleDim();
+	if (delta_panel_dim == 0) return;
 
 	F32 total_visible_fraction = 0.f;
 	F32 delta_auto_resize_headroom = 0.f;
-	F32 original_auto_resize_headroom = 0.f;
+	F32 old_auto_resize_headroom = 0.f;
 
 	LLLayoutPanel* other_resize_panel = NULL;
 	LLLayoutPanel* following_panel = NULL;
@@ -686,7 +686,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 	{
 		if (panelp->mAutoResize)
 		{
-			original_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
+			old_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
 			if (panelp->getVisible() && !panelp->mCollapsed)
 			{
 				total_visible_fraction += panelp->mFractionalSize;
@@ -704,25 +704,24 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 		}
 	}
 
-
 	if (resized_panel->mAutoResize)
 	{
 		if (!other_resize_panel || !other_resize_panel->mAutoResize)
 		{
-			delta_auto_resize_headroom += delta_dim;	
+			delta_auto_resize_headroom += delta_panel_dim;	
 		}
 	}
 	else 
 	{
 		if (!other_resize_panel || other_resize_panel->mAutoResize)
 		{
-			delta_auto_resize_headroom -= delta_dim;
+			delta_auto_resize_headroom -= delta_panel_dim;
 		}
 	}
 
 	F32 fraction_given_up = 0.f;
 	F32 fraction_remaining = 1.f;
-	F32 updated_auto_resize_headroom = original_auto_resize_headroom + delta_auto_resize_headroom;
+	F32 new_auto_resize_headroom = old_auto_resize_headroom + delta_auto_resize_headroom;
 
 	enum
 	{
@@ -734,7 +733,14 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 
 	BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
 	{
-		if (!panelp->getVisible() || panelp->mCollapsed) continue;
+		if (!panelp->getVisible() || panelp->mCollapsed) 
+		{
+			if (panelp->mAutoResize) 
+			{
+				fraction_remaining -= panelp->mFractionalSize;
+			}
+			continue;
+		}
 
 		if (panelp == resized_panel)
 		{
@@ -746,9 +752,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 		case BEFORE_RESIZED_PANEL:
 			if (panelp->mAutoResize)
 			{	// freeze current size as fraction of overall auto_resize space
-				F32 fractional_adjustment_factor = updated_auto_resize_headroom == 0.f
+				F32 fractional_adjustment_factor = new_auto_resize_headroom == 0.f
 													? 1.f
-													: original_auto_resize_headroom / updated_auto_resize_headroom;
+													: old_auto_resize_headroom / new_auto_resize_headroom;
 				F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor,
 													MIN_FRACTIONAL_SIZE,
 													MAX_FRACTIONAL_SIZE);
@@ -765,9 +771,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 		case RESIZED_PANEL:
 			if (panelp->mAutoResize)
 			{	// freeze new size as fraction
-				F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
+				F32 new_fractional_size = (new_auto_resize_headroom == 0.f)
 					? MAX_FRACTIONAL_SIZE
-					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / new_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
 				fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
 				fraction_remaining -= panelp->mFractionalSize;
 				panelp->mFractionalSize = new_fractional_size;
@@ -791,7 +797,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 				else
 				{
 					F32 new_fractional_size = llclamp(total_visible_fraction * (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) 
-														/ updated_auto_resize_headroom,
+														/ new_auto_resize_headroom,
 													MIN_FRACTIONAL_SIZE,
 													MAX_FRACTIONAL_SIZE);
 					fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
@@ -800,7 +806,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 			}
 			else
 			{
-				panelp->mTargetDim -= delta_dim;
+				panelp->mTargetDim -= delta_panel_dim;
 			}
 			which_panel = AFTER_RESIZED_PANEL;
 			break;
@@ -816,7 +822,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 		}
 	}
 	updateLayout();
-	normalizeFractionalSizes();
+	//normalizeFractionalSizes();
 }
 
 void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent)
-- 
cgit v1.2.3


From 4da02c26e10fe59dfde762cdb3c0d20be7f6ebde Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 2 Nov 2012 19:36:46 -0700
Subject: CHUI-481, CHUI-404, CHUI-405, CHUI-406, CHUI-407, CHUI-408 : Fixed!
 Change the way Ad-hoc and P2P chats update their session name in a way which
 is consistent and honor display name.

---
 indra/newview/llimconversation.cpp | 60 ++++++++++++++++++--------------------
 indra/newview/llimfloater.cpp      | 22 ++------------
 indra/newview/llimfloater.h        |  3 --
 3 files changed, 31 insertions(+), 54 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index a6a246a01e..6272c75ccf 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -29,6 +29,8 @@
 
 #include "llimconversation.h"
 
+#include "llagent.h"
+#include "llavataractions.h"
 #include "llchatentry.h"
 #include "llchathistory.h"
 #include "llchiclet.h"
@@ -370,50 +372,47 @@ void LLIMConversation::updateConversationViewParticipant(const LLUUID& participa
 	if (widget)
 	{
 		widget->refresh();
-		refreshConversation();
 	}
+	refreshConversation();
 }
 
 void LLIMConversation::refreshConversation()
 {
-	// Debug : Check that all participant models do have a view (debug consistency check)
-	/*
-	LLParticipantList* item = getParticipantList();
-	llinfos << "Merov debug : Start consistency check" << llendl;
-	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
-	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
-	while (current_participant_model != end_participant_model)
+	// Note: We collect participants names to change the session name only in the case of ad-hoc conversations
+	bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false);
+	uuid_vec_t participants_uuids; // uuids vector for building the added participants name string
+	// For P2P chat, we still need to update the session name who may have changed (switch display name for instance)
+	if (mIsP2PChat && mSession)
 	{
-		LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
-		if (participant_model != NULL)
-		{
-			LLUUID uuid = participant_model->getUUID();
-			LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
-			if (!widget)
-			{
-				llinfos << "Merov debug : Consistency error! Couldn't find widget for " << participant_model->getName() << llendl;
-			}
-			else 
-			{
-				llinfos << "Merov debug : Consistency check pass for " << participant_model->getName() << llendl;
-			}
-		}
-		else
-		{
-			llinfos << "Merov debug : Consistency check, skip non participant child" << llendl;
-		}
-		current_participant_model++;
+		participants_uuids.push_back(mSession->mOtherParticipantID);
 	}
-	llinfos << "Merov debug : End consistency check" << llendl;
-	 */
-		
+
 	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
 	while (widget_it != mConversationsWidgets.end())
 	{
+		// Add the participant to the list except if it's the agent itself (redundant)
+		if (is_ad_hoc && (widget_it->first != gAgentID))
+		{
+			participants_uuids.push_back(widget_it->first);
+		}
 		widget_it->second->refresh();
 		widget_it->second->setVisible(TRUE);
 		++widget_it;
 	}
+	if (is_ad_hoc || mIsP2PChat)
+	{
+		// Build the session name and update it
+		std::string session_name;
+		if (participants_uuids.size() != 0)
+		{
+			LLAvatarActions::buildResidentsString(participants_uuids, session_name);
+		}
+		else
+		{
+			session_name = LLIMModel::instance().getName(mSessionID);
+		}
+		updateSessionName(session_name);
+	} 
 	mConversationViewModel.requestSortAll();
 	mConversationsRoot->arrangeAll();
 	mConversationsRoot->update();
@@ -510,7 +509,6 @@ void LLIMConversation::hideOrShowTitle()
 
 void LLIMConversation::updateSessionName(const std::string& name)
 {
-	llinfos << "Merov debug : updateSessionName, name = " << name << llendl;
 	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
 }
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 4e1bfb4e77..75be0a7edc 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -270,14 +270,7 @@ void LLIMFloater::initIMFloater()
 		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
 	}
 
-	if (mIsP2PChat)
-	{
-		// look up display name for window title
-		LLAvatarNameCache::get(mSession->mOtherParticipantID,
-							   boost::bind(&LLIMFloater::onAvatarNameCache,
-										   this, _1, _2));
-	}
-	else
+	if (!mIsP2PChat)
 	{
 		std::string session_name(LLIMModel::instance().getName(mSessionID));
 		updateSessionName(session_name);
@@ -530,18 +523,7 @@ void LLIMFloater::updateSessionName(const std::string& name)
 {
 	LLIMConversation::updateSessionName(name);
 	setTitle(name);	
-}
-
-void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
-									const LLAvatarName& av_name)
-{
-	// Use display name for label
-	updateSessionName(av_name.mDisplayName);
-	
-	// Overwrite the floater title with the extended name
-	std::string ui_title = av_name.getCompleteName();
-	setTitle(ui_title);	
-	mTypingStart.setArg("[NAME]", ui_title);
+	mTypingStart.setArg("[NAME]", name);
 }
 
 void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index ec3a96f694..bac21c27f0 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -142,9 +142,6 @@ private:
 	// Update the window title and input field help text
 	/*virtual*/ void updateSessionName(const std::string& name);
 
-	// For display name lookups for IM window titles
-	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-
 	/// Updates the list of ad hoc conference participants
 	/// in an IM floater title.
 	void onParticipantsListChanged(LLUICtrl* ctrl);
-- 
cgit v1.2.3


From 6220ce33700d011be5831b1bb480c81dec98665e Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 5 Nov 2012 15:18:53 +0200
Subject: CHUI-450 (Your own name does not appear in nearby chat participant
 list if voice chat disabled)

---
 indra/newview/llvoicevivox.cpp | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index f1bf4a6d75..f236123ef1 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -394,7 +394,15 @@ const LLVoiceVersionInfo& LLVivoxVoiceClient::getVersion()
 
 void LLVivoxVoiceClient::updateSettings()
 {
-	setVoiceEnabled(gSavedSettings.getBOOL("EnableVoiceChat"));
+	if(!mAudioSession)
+	{
+		// If audio module is not initialized, pretend that voice is enabled, thus letting state machine to take a full cycle
+		setVoiceEnabled(true);
+	}
+	else
+	{
+		setVoiceEnabled(gSavedSettings.getBOOL("EnableVoiceChat"));
+	}
 	setEarLocation(gSavedSettings.getS32("VoiceEarLocation"));
 
 	std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
@@ -1478,6 +1486,9 @@ void LLVivoxVoiceClient::stateMachine()
 					mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
 					sendPositionalUpdate();
 				}
+
+				// Now that audio module is fully initialized, check for actual mVoiceEnabled value
+				updateSettings();
 			}
 		break;
 		
-- 
cgit v1.2.3


From 622a697788e3cabb9e803226de72856e9189911f Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 6 Nov 2012 14:47:01 +0200
Subject: CHUI-460 FIXED Reselect current conversation on clicking
 expand/collapse button

---
 indra/newview/llimfloatercontainer.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index f85aa9a353..52deae445b 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -331,6 +331,7 @@ void LLIMFloaterContainer::onExpandCollapseButtonClicked()
 	{
 		collapseConversationsPane(!mConversationsPane->isCollapsed());
 	}
+	selectConversation(mSelectedSession);
 }
 
 LLIMFloaterContainer* LLIMFloaterContainer::findInstance()
-- 
cgit v1.2.3


From 741fdfd3e6e6c5556c5bac7ec9cb5bed13975dda Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 6 Nov 2012 14:53:42 +0200
Subject: CHUI-502 FIXED deleted registering Call floater from FloaterReg

---
 indra/newview/llviewerfloaterreg.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index c751550523..a4d45e1fb8 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -322,7 +322,6 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptPreview>, "upload");
 	LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
 
-	LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
 	LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
 
 	LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);	
-- 
cgit v1.2.3


From 0a21efc7abc62511d1ea789bdb47309a6ed1d72e Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 5 Nov 2012 17:52:04 +0200
Subject: CHUI-374 FIXED Nearby chat is torn off and cannot be docked if nearby
 chat is received while conversation floater is closed

---
 indra/newview/llimconversation.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index b687e18cae..833feff3c4 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -54,6 +54,7 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
   , mRefreshTimer(new LLTimer())
+  , mIsHostAttached(false)
 {
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
-- 
cgit v1.2.3


From 8d6aaf8e8e7c2d0f68bf79100f163803cbdd02bc Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 5 Nov 2012 13:47:49 -0800
Subject: CHUI-468 : Suppress LLIMFloater::onParticipantsListChanged(). Not
 useful anymore.

---
 indra/newview/llimfloater.cpp | 68 -------------------------------------------
 indra/newview/llimfloater.h   |  6 ----
 2 files changed, 74 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 8742460689..d9c201d856 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -220,7 +220,6 @@ void LLIMFloater::sendMsg(const std::string& msg)
 
 LLIMFloater::~LLIMFloater()
 {
-	mParticipantsListRefreshConnection.disconnect();
 	mVoiceChannelStateChangeConnection.disconnect();
 	if(LLVoiceClient::instanceExists())
 	{
@@ -274,22 +273,6 @@ void LLIMFloater::initIMFloater()
 	{
 		std::string session_name(LLIMModel::instance().getName(mSessionID));
 		updateSessionName(session_name);
-
-		// For ad hoc conferences we should update the title with participants names.
-		if ((IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
-						|| mDialog == IM_SESSION_CONFERENCE_START)
-		{
-			if (mParticipantsListRefreshConnection.connected())
-			{
-				mParticipantsListRefreshConnection.disconnect();
-			}
-
-			// CHUI-441: We shouldn't have any avatar_list anymore... see floater_im_session.xml
-			// *TODO: Track and delete if not necessary anymore
-			LLAvatarList* avatar_list = getChild<LLAvatarList>("speakers_list");
-			mParticipantsListRefreshConnection = avatar_list->setRefreshCompleteCallback(
-					boost::bind(&LLIMFloater::onParticipantsListChanged, this, _1));
-		}
 	}
 }
 
@@ -526,57 +509,6 @@ void LLIMFloater::updateSessionName(const std::string& name)
 	mTypingStart.setArg("[NAME]", name);
 }
 
-void LLIMFloater::onParticipantsListChanged(LLUICtrl* ctrl)
-{
-	LLAvatarList* avatar_list = dynamic_cast<LLAvatarList*>(ctrl);
-	if (!avatar_list)
-	{
-		return;
-	}
-
-	std::vector<LLSD> participants_uuids;
-	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
-	LLUUID unfound_id;
-
-	avatar_list->getValues(participants_uuids);
-
-	// Check participants names in LLAvatarNameCache
-    for (std::vector<LLSD>::const_iterator it = participants_uuids.begin(); it != participants_uuids.end(); ++it)
-	{
-		const LLUUID& id = it->asUUID();
-		LLAvatarName av_name;
-        if (!LLAvatarNameCache::get(id, &av_name))
-        {
-			// Keep the first not found avatar id
-			if (unfound_id.isNull())
-			{
-				unfound_id = id;
-			}
-        }
-		else
-		{
-			// Add the participant to the list of existing names
-			temp_uuids.push_back(id);
-		}
-	}
-
-	if (temp_uuids.size() != 0)
-	{
-		// Build the session name and update it
-		std::string ui_title;
-		LLAvatarActions::buildResidentsString(temp_uuids, ui_title);
-		updateSessionName(ui_title);
-	}
-
-	if (unfound_id.notNull())
-	{
-		// If a name is not found in cache, request it and continue the process recursively
-		// until all ids are resolved into names.
-		LLAvatarNameCache::get(unfound_id, boost::bind(&LLIMFloater::onParticipantsListChanged, this, avatar_list));
-	}
-}
-
-
 //static
 LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 {
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index dba3a4bcbd..8a0a163678 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -141,10 +141,6 @@ private:
 	// Update the window title and input field help text
 	/*virtual*/ void updateSessionName(const std::string& name);
 
-	/// Updates the list of ad hoc conference participants
-	/// in an IM floater title.
-	void onParticipantsListChanged(LLUICtrl* ctrl);
-
 	bool dropPerson(LLUUID* person_id, bool drop);
 
 	BOOL isInviteAllowed() const;
@@ -196,8 +192,6 @@ private:
 
 	// connection to voice channel state change signal
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
-
-	boost::signals2::connection mParticipantsListRefreshConnection;
 };
 
 #endif  // LL_IMFLOATER_H
-- 
cgit v1.2.3


From e3524a5fe159566edefb0bbc395e94ee3126adec Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 5 Nov 2012 15:53:31 -0800
Subject: CHUI-468 : Suppress LLCallFloater completely

---
 indra/newview/CMakeLists.txt                       |   2 -
 indra/newview/llappviewer.cpp                      |   1 -
 indra/newview/llcallfloater.cpp                    | 822 ---------------------
 indra/newview/llcallfloater.h                      | 275 -------
 indra/newview/llviewerfloaterreg.cpp               |   2 -
 indra/newview/llvoicevivox.cpp                     |   3 +-
 .../default/xui/en/floater_voice_controls.xml      | 155 ----
 7 files changed, 1 insertion(+), 1259 deletions(-)
 delete mode 100644 indra/newview/llcallfloater.cpp
 delete mode 100644 indra/newview/llcallfloater.h
 delete mode 100644 indra/newview/skins/default/xui/en/floater_voice_controls.xml

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c6ba8a22bd..2c7e96f1e4 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -117,7 +117,6 @@ set(viewer_SOURCE_FILES
     llbrowsernotification.cpp
     llbuycurrencyhtml.cpp
     llcallbacklist.cpp
-    llcallfloater.cpp
     llcallingcard.cpp
     llcapabilitylistener.cpp
     llcaphttpsender.cpp
@@ -701,7 +700,6 @@ set(viewer_HEADER_FILES
     llbreadcrumbview.h
     llbuycurrencyhtml.h
     llcallbacklist.h
-    llcallfloater.h
     llcallingcard.h
     llcapabilitylistener.h
     llcapabilityprovider.h
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d6c781020d..b23e5866dc 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -95,7 +95,6 @@
 #include "llweb.h"
 #include "llsecondlifeurls.h"
 #include "llupdaterservice.h"
-#include "llcallfloater.h"
 #include "llfloatertexturefetchdebugger.h"
 #include "llspellcheck.h"
 
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
deleted file mode 100644
index e767609d74..0000000000
--- a/indra/newview/llcallfloater.cpp
+++ /dev/null
@@ -1,822 +0,0 @@
-/** 
- * @file llcallfloater.cpp
- * @author Mike Antipov
- * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...).
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llcallfloater.h"
-
-#include "llnotificationsutil.h"
-#include "lltrans.h"
-
-#include "llagent.h"
-#include "llagentdata.h" // for gAgentID
-#include "llavatarnamecache.h"
-#include "llavatariconctrl.h"
-#include "llavatarlist.h"
-#include "lldraghandle.h"
-#include "llimfloater.h"
-#include "llimview.h"
-#include "llfloaterreg.h"
-#include "llparticipantlist.h"
-#include "llspeakers.h"
-#include "lltextutil.h"
-#include "lltransientfloatermgr.h"
-#include "llviewercontrol.h"
-#include "llviewerdisplayname.h"
-#include "llviewerwindow.h"
-#include "llvoicechannel.h"
-#include "llviewerparcelmgr.h"
-#include "llfirstuse.h"
-
-static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids);
-void reshape_floater(LLCallFloater* floater, S32 delta_height);
-
-class LLNonAvatarCaller : public LLAvatarListItem
-{
-public:
-	LLNonAvatarCaller() : LLAvatarListItem(false)
-	{
-
-	}
-	BOOL postBuild()
-	{
-		BOOL rv = LLAvatarListItem::postBuild();
-
-		if (rv)
-		{
-			setOnline(true);
-			showLastInteractionTime(false);
-			setShowProfileBtn(false);
-			setShowInfoBtn(false);
-			mAvatarIcon->setValue("Avaline_Icon");
-			mAvatarIcon->setToolTip(std::string(""));
-		}
-		return rv;
-	}
-
-	void setName(const std::string& name)
-	{
-		const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
-		LLAvatarListItem::setAvatarName(formatted_phone);
-		LLAvatarListItem::setAvatarToolTip(formatted_phone);
-	}
-
-	void setSpeakerId(const LLUUID& id) { mSpeakingIndicator->setSpeakerId(id); }
-};
-
-
-static void* create_non_avatar_caller(void*)
-{
-	return new LLNonAvatarCaller;
-}
-
-LLVoiceChannel* LLCallFloater::sCurrentVoiceChannel = NULL;
-
-LLCallFloater::LLCallFloater(const LLSD& key)
-: LLTransientDockableFloater(NULL, false, key)
-, mSpeakerManager(NULL)
-, mParticipants(NULL)
-, mAvatarList(NULL)
-, mNonAvatarCaller(NULL)
-, mVoiceType(VC_LOCAL_CHAT)
-, mAgentPanel(NULL)
-, mSpeakingIndicator(NULL)
-, mIsModeratorMutedVoice(false)
-, mInitParticipantsVoiceState(false)
-{
-	static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10);
-	mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay);
-
-	mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL);
-	LLVoiceClient::instance().addObserver(this);
-	LLTransientFloaterMgr::getInstance()->addControlView(this);
-
-	// update the agent's name if display name setting change
-	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLCallFloater::updateAgentModeratorState, this));
-	LLViewerDisplayName::addNameChangedCallback(boost::bind(&LLCallFloater::updateAgentModeratorState, this));
-
-}
-
-LLCallFloater::~LLCallFloater()
-{
-	resetVoiceRemoveTimers();
-	delete mSpeakerDelayRemover;
-
-	delete mParticipants;
-	mParticipants = NULL;
-
-	mAvatarListRefreshConnection.disconnect();
-	mVoiceChannelStateChangeConnection.disconnect();
-
-	if(LLVoiceClient::instanceExists())
-	{
-		LLVoiceClient::getInstance()->removeObserver(this);
-	}
-	LLTransientFloaterMgr::getInstance()->removeControlView(this);
-}
-
-// virtual
-BOOL LLCallFloater::postBuild()
-{
-	mAvatarList = getChild<LLAvatarList>("speakers_list");
-	mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLCallFloater::onAvatarListRefreshed, this));
-
-	childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this));
-
-	mNonAvatarCaller = findChild<LLNonAvatarCaller>("non_avatar_caller");
-	mNonAvatarCaller->setVisible(FALSE);
-
-	initAgentData();
-
-	connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
-
-	updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
-	
-	updateSession();
-	return TRUE;
-}
-
-// virtual
-void LLCallFloater::onOpen(const LLSD& /*key*/)
-{
-	LLFirstUse::speak(false);
-}
-
-// virtual
-void LLCallFloater::draw()
-{
-	// we have to refresh participants to display ones not in voice as disabled.
-	// It should be done only when she joins or leaves voice chat.
-	// But seems that LLVoiceClientParticipantObserver is not enough to satisfy this requirement.
-	// *TODO: mantipov: remove from draw()
-
-	// NOTE: it looks like calling onChange() here is not necessary,
-	// but sometime it is not called properly from the observable object.
-	// Seems this is a problem somewhere in Voice Client (LLVoiceClient::participantAddedEvent)
-//	onChange();
-
-	bool is_moderator_muted = LLVoiceClient::getInstance()->getIsModeratorMuted(gAgentID);
-
-	if (mIsModeratorMutedVoice != is_moderator_muted)
-	{
-		setModeratorMutedVoice(is_moderator_muted);
-	}
-
-	// Need to resort the participant list if it's in sort by recent speaker order.
-	if (mParticipants)
-		mParticipants->update();
-
-	LLFloater::draw();
-}
-
-// virtual
-void LLCallFloater::setFocus( BOOL b )
-{
-	LLFloater::setFocus(b);
-
-	// Force using active floater transparency (STORM-730).
-	// We have to override setFocus() for LLCallFloater because selecting an item
-	// of the voice morphing combobox causes the floater to lose focus and thus become transparent.
-	updateTransparency(TT_ACTIVE);
-}
-
-// virtual
-void LLCallFloater::onParticipantsChanged()
-{
-	if (NULL == mParticipants) return;
-	updateParticipantsVoiceState();
-
-	// Add newly joined participants.
-	uuid_vec_t speakers_uuids;
-	get_voice_participants_uuids(speakers_uuids);
-	for (uuid_vec_t::const_iterator it = speakers_uuids.begin(); it != speakers_uuids.end(); it++)
-	{
-		mParticipants->addAvatarIDExceptAgent(*it);
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// PRIVATE SECTION
-//////////////////////////////////////////////////////////////////////////
-
-void LLCallFloater::leaveCall()
-{
-	LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
-	if (voice_channel)
-	{
-		gIMMgr->endCall(voice_channel->getSessionID());
-	}
-}
-
-void LLCallFloater::updateSession()
-{
-	LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
-	if (voice_channel)
-	{
-		LL_DEBUGS("Voice") << "Current voice channel: " << voice_channel->getSessionID() << LL_ENDL;
-
-		if (mSpeakerManager && voice_channel->getSessionID() == mSpeakerManager->getSessionID())
-		{
-			LL_DEBUGS("Voice") << "Speaker manager is already set for session: " << voice_channel->getSessionID() << LL_ENDL;
-			return;
-		}
-		else
-		{
-			mSpeakerManager = NULL;
-		}
-	}
-
-	const LLUUID& session_id = voice_channel ? voice_channel->getSessionID() : LLUUID::null;
-
-	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
-	if (im_session)
-	{
-		mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id);
-		switch (im_session->mType)
-		{
-		case IM_NOTHING_SPECIAL:
-		case IM_SESSION_P2P_INVITE:
-			mVoiceType = VC_PEER_TO_PEER;
-
-			if (!im_session->mOtherParticipantIsAvatar)
-			{
-				mVoiceType = VC_PEER_TO_PEER_AVALINE;
-			}
-			break;
-		case IM_SESSION_CONFERENCE_START:
-		case IM_SESSION_GROUP_START:
-		case IM_SESSION_INVITE:
-			if (gAgent.isInGroup(session_id))
-			{
-				mVoiceType = VC_GROUP_CHAT;
-			}
-			else
-			{
-				mVoiceType = VC_AD_HOC_CHAT;				
-			}
-			break;
-		default:
-			llwarning("Failed to determine voice call IM type", 0);
-			mVoiceType = VC_GROUP_CHAT;
-			break;
-		}
-	}
-
-	if (NULL == mSpeakerManager)
-	{
-		// By default show nearby chat participants
-		mSpeakerManager = LLLocalSpeakerMgr::getInstance();
-		LL_DEBUGS("Voice") << "Set DEFAULT speaker manager" << LL_ENDL;
-		mVoiceType = VC_LOCAL_CHAT;
-	}
-
-	updateTitle();
-
-	// Hide "Leave Call" button for nearby chat
-	bool is_local_chat = mVoiceType == VC_LOCAL_CHAT;
-	getChildView("leave_call_btn_panel")->setVisible( !is_local_chat);
-
-	refreshParticipantList();
-	updateAgentModeratorState();
-
-	// Show floater for voice calls & only in CONNECTED to voice channel state
-	if (!is_local_chat &&
-	    voice_channel &&
-	    LLVoiceChannel::STATE_CONNECTED == voice_channel->getState())
-	{
-		LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
-		bool show_me = !(im_floater && im_floater->getVisible());
-		if (show_me) 
-		{
-			setVisible(true);
-		}
-	}
-}
-
-void LLCallFloater::refreshParticipantList()
-{
-	bool non_avatar_caller = VC_PEER_TO_PEER_AVALINE == mVoiceType;
-
-	if (non_avatar_caller)
-	{
-		LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSpeakerManager->getSessionID());
-		mNonAvatarCaller->setSpeakerId(session->mOtherParticipantID);
-		mNonAvatarCaller->setName(session->mName);
-	}
-
-	mNonAvatarCaller->setVisible(non_avatar_caller);
-	mAvatarList->setVisible(!non_avatar_caller);
-
-	if (!non_avatar_caller)
-	{
-		llassert(mParticipants == NULL); // check for possible memory leak
-		mParticipants = new LLParticipantList(mSpeakerManager, mAvatarList, mConversationViewModel, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT, false);
-		mParticipants->setValidateSpeakerCallback(boost::bind(&LLCallFloater::validateSpeaker, this, _1));
-		const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
-		mParticipants->setSortOrder(LLParticipantList::EParticipantSortOrder(speaker_sort_order));
-		
-		if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager)
-		{
-			mAvatarList->setNoItemsCommentText(getString("no_one_near"));
-		}
-
-		// we have to made delayed initialization of voice state of participant list.
-		// it will be performed after first LLAvatarList refreshing in the onAvatarListRefreshed().
-		mInitParticipantsVoiceState = true;
-	}
-}
-
-void LLCallFloater::onAvatarListRefreshed()
-{
-	if (mInitParticipantsVoiceState)
-	{
-		initParticipantsVoiceState();
-		mInitParticipantsVoiceState = false;
-	}
-	else
-	{
-		updateParticipantsVoiceState();
-	}
-}
-
-// static
-// This entry point now disable, but left for later use.
-void LLCallFloater::onCurrentChannelChanged(const LLUUID& /*session_id*/)
-{
-	LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
-
-	// *NOTE: if signal was sent for voice channel with LLVoiceChannel::STATE_NO_CHANNEL_INFO
-	// it sill be sent for the same channel again (when state is changed).
-	// So, lets ignore this call.
-	if (channel == sCurrentVoiceChannel) return;
-
-	LLCallFloater* call_floater = LLFloaterReg::getTypedInstance<LLCallFloater>("voice_controls");
-
-	call_floater->connectToChannel(channel);
-}
-
-void LLCallFloater::onAvatarNameCache(const LLUUID& agent_id,
-									  const LLAvatarName& av_name)
-{
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = av_name.getCompleteName();
-	std::string title = getString("title_peer_2_peer", args);
-	setTitle(title);
-}
-
-void LLCallFloater::updateTitle()
-{
-	LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
-	if (mVoiceType == VC_PEER_TO_PEER)
-	{
-		LLUUID session_id = voice_channel->getSessionID();
-		LLIMModel::LLIMSession* im_session =
-			LLIMModel::getInstance()->findIMSession(session_id);
-		if (im_session)
-		{
-			LLAvatarNameCache::get(im_session->mOtherParticipantID,
-				boost::bind(&LLCallFloater::onAvatarNameCache,
-					this, _1, _2));
-			return;
-		}
-	}
-	std::string title;
-	switch (mVoiceType)
-	{
-	case VC_LOCAL_CHAT:
-		title = getString("title_nearby");
-		break;
-	case VC_PEER_TO_PEER:
-	case VC_PEER_TO_PEER_AVALINE:
-		{
-			title = voice_channel->getSessionName();
-
-			if (VC_PEER_TO_PEER_AVALINE == mVoiceType)
-			{
-				title = LLTextUtil::formatPhoneNumber(title);
-			}
-
-			LLStringUtil::format_map_t args;
-			args["[NAME]"] = title;
-			title = getString("title_peer_2_peer", args);
-		}
-		break;
-	case VC_AD_HOC_CHAT:
-		title = getString("title_adhoc");
-		break;
-	case VC_GROUP_CHAT:
-		{
-			LLStringUtil::format_map_t args;
-			args["[GROUP]"] = voice_channel->getSessionName();
-			title = getString("title_group", args);
-		}
-		break;
-	}
-
-	setTitle(title);
-}
-
-void LLCallFloater::initAgentData()
-{
-	mAgentPanel = getChild<LLPanel> ("my_panel");
-
-	if ( mAgentPanel )
-	{
-		mAgentPanel->getChild<LLUICtrl>("user_icon")->setValue(gAgentID);
-
-		// Just use display name, because it's you
-		LLAvatarName av_name;
-		LLAvatarNameCache::get( gAgentID, &av_name );
-		mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(av_name.mDisplayName);
-
-		mSpeakingIndicator = mAgentPanel->getChild<LLOutputMonitorCtrl>("speaking_indicator");
-		mSpeakingIndicator->setSpeakerId(gAgentID);
-	}
-}
-
-void LLCallFloater::setModeratorMutedVoice(bool moderator_muted)
-{
-	mIsModeratorMutedVoice = moderator_muted;
-
-	if (moderator_muted)
-	{
-		LLNotificationsUtil::add("VoiceIsMutedByModerator");
-	}
-	mSpeakingIndicator->setIsMuted(moderator_muted);
-}
-
-void LLCallFloater::onModeratorNameCache(const LLAvatarName& av_name)
-{
-	std::string name;
-	name = av_name.mDisplayName;
-
-	if(mSpeakerManager && gAgent.isInGroup(mSpeakerManager->getSessionID()))
-	{
-		// This method can be called when LLVoiceChannel.mState == STATE_NO_CHANNEL_INFO
-		// in this case there are not any speakers yet.
-		if (mSpeakerManager->findSpeaker(gAgentID))
-		{
-			// Agent is Moderator
-			if (mSpeakerManager->findSpeaker(gAgentID)->mIsModerator)
-
-			{
-				const std::string moderator_indicator(LLTrans::getString("IM_moderator_label")); 
-				name += " " + moderator_indicator;
-			}
-		}
-	}
-	mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(name);
-}
-
-void LLCallFloater::updateAgentModeratorState()
-{
-	LLAvatarNameCache::get(gAgentID, boost::bind(&LLCallFloater::onModeratorNameCache, this, _2));
-}
-
-static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids)
-{
-	// Get a list of participants from VoiceClient
-       std::set<LLUUID> participants;
-       LLVoiceClient::getInstance()->getParticipantList(participants);
-	
-	for (std::set<LLUUID>::const_iterator iter = participants.begin();
-		 iter != participants.end(); ++iter)
-	{
-		speakers_uuids.push_back(*iter);
-	}
-
-}
-
-void LLCallFloater::initParticipantsVoiceState()
-{
-	// Set initial status for each participant in the list.
-	std::vector<LLPanel*> items;
-	mAvatarList->getItems(items);
-	std::vector<LLPanel*>::const_iterator
-		it = items.begin(),
-		it_end = items.end();
-
-
-	uuid_vec_t speakers_uuids;
-	get_voice_participants_uuids(speakers_uuids);
-
-	for(; it != it_end; ++it)
-	{
-		LLAvatarListItem *item = dynamic_cast<LLAvatarListItem*>(*it);
-		
-		if (!item)	continue;
-		
-		LLUUID speaker_id = item->getAvatarId();
-
-		uuid_vec_t::const_iterator speaker_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), speaker_id);
-
-		// If an avatarID assigned to a panel is found in a speakers list
-		// obtained from VoiceClient we assign the JOINED status to the owner
-		// of this avatarID.
-		if (speaker_iter != speakers_uuids.end())
-		{
-			setState(item, STATE_JOINED);
-		}
-		else
-		{
-			LLPointer<LLSpeaker> speakerp = mSpeakerManager->findSpeaker(speaker_id);
-			// If someone has already left the call before, we create his
-			// avatar row panel with HAS_LEFT status and remove it after
-			// the timeout, otherwise we create a panel with INVITED status
-			if (speakerp.notNull() && speakerp.get()->mHasLeftCurrentCall)
-			{
-				setState(item, STATE_LEFT);
-			}
-			else
-			{
-				setState(item, STATE_INVITED);
-			}
-		}
-	}
-}
-
-void LLCallFloater::updateParticipantsVoiceState()
-{
-	uuid_vec_t speakers_list;
-
-	// Get a list of participants from VoiceClient
-	uuid_vec_t speakers_uuids;
-	get_voice_participants_uuids(speakers_uuids);
-
-	// Updating the status for each participant already in list.
-	std::vector<LLPanel*> items;
-	mAvatarList->getItems(items);
-	std::vector<LLPanel*>::const_iterator
-		it = items.begin(),
-		it_end = items.end();
-
-	for(; it != it_end; ++it)
-	{
-		LLAvatarListItem *item = dynamic_cast<LLAvatarListItem*>(*it);
-		if (!item) continue;
-
-		const LLUUID participant_id = item->getAvatarId();
-		bool found = false;
-
-		uuid_vec_t::iterator speakers_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), participant_id);
-
-		LL_DEBUGS("Voice") << "processing speaker: " << item->getAvatarName() << ", " << item->getAvatarId() << LL_ENDL;
-
-		// If an avatarID assigned to a panel is found in a speakers list
-		// obtained from VoiceClient we assign the JOINED status to the owner
-		// of this avatarID.
-		if (speakers_iter != speakers_uuids.end())
-		{
-			setState(item, STATE_JOINED);
-
-			LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id);
-			if (speaker.isNull())
-				continue;
-			speaker->mHasLeftCurrentCall = FALSE;
-
-			speakers_uuids.erase(speakers_iter);
-			found = true;
-		}
-
-		if (!found)
-		{
-			updateNotInVoiceParticipantState(item);
-		}
-	}
-}
-
-void LLCallFloater::updateNotInVoiceParticipantState(LLAvatarListItem* item)
-{
-	LLUUID participant_id = item->getAvatarId();
-	ESpeakerState current_state = getState(participant_id);
-
-	switch (current_state)
-	{
-	case STATE_JOINED:
-		// If an avatarID is not found in a speakers list from VoiceClient and
-		// a panel with this ID has a JOINED status this means that this person
-		// HAS LEFT the call.
-		setState(item, STATE_LEFT);
-
-		{
-			LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id);
-			if (speaker.notNull())
-			{
-				speaker->mHasLeftCurrentCall = TRUE;
-			}
-		}
-		break;
-	case STATE_LEFT:
-		// nothing to do. These states should not be changed.
-		break;
-	case STATE_INVITED:
-		// If avatar was invited into group chat and went offline it is still exists in mSpeakerStateMap
-		// If it goes online it will be rendered as JOINED via LAvatarListItem.
-		// Lets update its visual representation. See EXT-6660
-	case STATE_UNKNOWN:
-		// If an avatarID is not found in a speakers list from VoiceClient and
-		// a panel with this ID has an UNKNOWN status this means that this person
-		// HAS ENTERED session but it is not in voice chat yet. So, set INVITED status
-		setState(item, STATE_INVITED);
-		break;
-	default:
-		// for possible new future states.
-		llwarns << "Unsupported (" << getState(participant_id) << ") state for: " << item->getAvatarName()  << llendl;
-		break;
-	}
-}
-
-void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state)
-{
-	// *HACK: mantipov: sometimes such situation is possible while switching to voice channel:
-/*
-	- voice channel is switched to the one user is joining
-	- participant list is initialized with voice states: agent is in voice
-	- than such log messages were found (with agent UUID)
-			- LLVivoxProtocolParser::process_impl: parsing: <Response requestId="22" action="Session.MediaDisconnect.1"><ReturnCode>0</ReturnCode><Results><StatusCode>0</StatusCode><StatusString /></Results><InputXml><Request requestId="22" action="Session.MediaDisconnect.1"><SessionGroupHandle>9</SessionGroupHandle><SessionHandle>12</SessionHandle><Media>Audio</Media></Request></InputXml></Response>
-			- LLVoiceClient::sessionState::removeParticipant: participant "sip:x2pwNkMbpR_mK4rtB_awASA==@bhr.vivox.com" (da9c0d90-c6e9-47f9-8ae2-bb41fdac0048) removed.
-	- and than while updating participants voice states agent is marked as HAS LEFT
-	- next updating of LLVoiceClient state makes agent JOINED
-	So, lets skip HAS LEFT state for agent's avatar
-*/
-	if (STATE_LEFT == state && item->getAvatarId() == gAgentID) return;
-
-	setState(item->getAvatarId(), state);
-
-	switch (state)
-	{
-	case STATE_INVITED:
-		item->setState(LLAvatarListItem::IS_VOICE_INVITED);
-		break;
-	case STATE_JOINED:
-		removeVoiceRemoveTimer(item->getAvatarId());
-		item->setState(LLAvatarListItem::IS_VOICE_JOINED);
-		break;
-	case STATE_LEFT:
-		{
-			setVoiceRemoveTimer(item->getAvatarId());
-			item->setState(LLAvatarListItem::IS_VOICE_LEFT);
-		}
-		break;
-	default:
-		llwarns << "Unrecognized avatar panel state (" << state << ")" << llendl;
-		break;
-	}
-}
-
-void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id)
-{
-	mSpeakerDelayRemover->setActionTimer(voice_speaker_id);
-}
-
-bool LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
-{
-	uuid_vec_t& speaker_uuids = mAvatarList->getIDs();
-	uuid_vec_t::iterator pos = std::find(speaker_uuids.begin(), speaker_uuids.end(), voice_speaker_id);
-	if(pos != speaker_uuids.end())
-	{
-		speaker_uuids.erase(pos);
-		mAvatarList->setDirty();
-	}
-
-	return false;
-}
-
-
-void LLCallFloater::resetVoiceRemoveTimers()
-{
-	mSpeakerDelayRemover->removeAllTimers();
-}
-
-void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
-{
-	mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
-}
-
-bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
-{
-	bool is_valid = true;
-	switch (mVoiceType)
-	{
-	case  VC_LOCAL_CHAT:
-		{
-			// A nearby chat speaker is considered valid it it's known to LLVoiceClient (i.e. has enabled voice).
-			uuid_vec_t speakers;
-			get_voice_participants_uuids(speakers);
-			is_valid = std::find(speakers.begin(), speakers.end(), speaker_id) != speakers.end();
-		}
-		break;
-	case VC_GROUP_CHAT:
-		// if participant had left this call before do not allow add her again. See EXT-4216.
-		// but if she Join she will be added into the list from the LLCallFloater::onChange()
-		is_valid = STATE_LEFT != getState(speaker_id);
-		break;
-	default:
-		// do nothing. required for Linux build
-		break;
-	}
-
-	return is_valid;
-}
-
-void LLCallFloater::connectToChannel(LLVoiceChannel* channel)
-{
-	mVoiceChannelStateChangeConnection.disconnect();
-
-	sCurrentVoiceChannel = channel;
-
-	mVoiceChannelStateChangeConnection = sCurrentVoiceChannel->setStateChangedCallback(boost::bind(&LLCallFloater::onVoiceChannelStateChanged, this, _1, _2));
-
-	updateState(channel->getState());
-}
-
-void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
-	// check is voice operational and if it doesn't work hide VCP (EXT-4397)
-	if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())
-	{
-		updateState(new_state);
-	}
-	else
-	{
-		closeFloater();
-	}
-}
-
-void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state)
-{
-	LL_DEBUGS("Voice") << "Updating state: " << new_state << ", session name: " << sCurrentVoiceChannel->getSessionName() << LL_ENDL;
-	if (LLVoiceChannel::STATE_CONNECTED == new_state)
-	{
-		updateSession();
-	}
-	else
-	{
-		reset(new_state);
-	}
-}
-
-void LLCallFloater::reset(const LLVoiceChannel::EState& new_state)
-{
-	// lets forget states from the previous session
-	// for timers...
-	resetVoiceRemoveTimers();
-
-	// ...and for speaker state
-	mSpeakerStateMap.clear();
-
-	delete mParticipants;
-	mParticipants = NULL;
-	mAvatarList->clear();
-
-	// These ifs were added instead of simply showing "loading" to make VCP work correctly in parcels
-	// with disabled voice (EXT-4648 and EXT-4649)
-	if (!LLViewerParcelMgr::getInstance()->allowAgentVoice() && LLVoiceChannel::STATE_HUNG_UP == new_state)
-	{
-		// hides "Leave Call" when call is ended in parcel with disabled voice- hiding usually happens in
-		// updateSession() which won't be called here because connect to nearby voice never happens 
-		getChildView("leave_call_btn_panel")->setVisible( false);
-		// setting title to nearby chat an "no one near..." text- because in region with disabled
-		// voice we won't have chance to really connect to nearby, so VCP is changed here manually
-		setTitle(getString("title_nearby"));
-		mAvatarList->setNoItemsCommentText(getString("no_one_near"));
-	}
-	// "loading" is shown  only when state is "ringing" to avoid showing it in nearby chat vcp
-	// of parcels with disabled voice all the time- "no_one_near" is now shown there (EXT-4648)
-	else if (new_state == LLVoiceChannel::STATE_RINGING)
-	{
-		// update floater to show Loading while waiting for data.
-		mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
-	}
-
-	mAvatarList->setVisible(TRUE);
-	mNonAvatarCaller->setVisible(FALSE);
-
-	mSpeakerManager = NULL;
-}
-
-//EOF
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
deleted file mode 100644
index e1c7b3f43a..0000000000
--- a/indra/newview/llcallfloater.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/** 
- * @file llcallfloater.h
- * @author Mike Antipov
- * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...).
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLCALLFLOATER_H
-#define LL_LLCALLFLOATER_H
-
-#include "lltransientdockablefloater.h"
-#include "llvoicechannel.h"
-#include "llvoiceclient.h"
-#include "llconversationmodel.h"
-
-class LLAvatarList;
-class LLAvatarListItem;
-class LLAvatarName;
-class LLNonAvatarCaller;
-class LLOutputMonitorCtrl;
-class LLParticipantList;
-class LLSpeakerMgr;
-class LLSpeakersDelayActionsStorage;
-
-/**
- * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron
- * on the Speak button. It can be torn-off and freely positioned onscreen.
- *
- * When the Resident is engaged in Voice Chat, the Voice Control Panel provides control
- * over the audible volume of each of the other participants, the Resident's own Voice
- * Morphing settings (if she has subscribed to enable the feature), and Voice Recording.
- *
- * When the Resident is engaged in any chat except Nearby Chat, the Voice Control Panel
- * also provides a 'Leave Call' button to allow the Resident to leave that voice channel.
- */
-class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipantObserver
-{
-public:
-
-	LOG_CLASS(LLCallFloater);
-
-	LLCallFloater(const LLSD& key);
-	~LLCallFloater();
-
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void draw();
-	/*virtual*/ void setFocus( BOOL b );
-
-	/**
-	 * Is called by LLVoiceClient::notifyParticipantObservers when voice participant list is changed.
-	 *
-	 * Refreshes list to display participants not in voice as disabled.
-	 */
-	/*virtual*/ void onParticipantsChanged();
-
-	static void onCurrentChannelChanged(const LLUUID& session_id);
-
-private:
-	typedef enum e_voice_controls_type
-	{
-		VC_LOCAL_CHAT,
-		VC_GROUP_CHAT,
-		VC_AD_HOC_CHAT,
-		VC_PEER_TO_PEER,
-		VC_PEER_TO_PEER_AVALINE
-	}EVoiceControls;
-
-	typedef enum e_speaker_state
-	{
-		STATE_UNKNOWN,
-		STATE_INVITED,
-		STATE_JOINED,
-		STATE_LEFT,
-	} ESpeakerState;
-
-	typedef std::map<LLUUID, ESpeakerState> speaker_state_map_t;
-
-	void leaveCall();
-
-	/**
-	 * Updates mSpeakerManager and list according to current Voice Channel
-	 *
-	 * It compares mSpeakerManager & current Voice Channel session IDs.
-	 * If they are different gets Speaker manager related to current channel and updates channel participant list.
-	 */
-	void updateSession();
-
-	/**
-	 * Refreshes participant list according to current Voice Channel
-	 */
-	void refreshParticipantList();
-
-	/**
-	 * Handles event on avatar list is refreshed after it was marked dirty.
-	 *
-	 * It sets initial participants voice states (once after the first refreshing)
-	 * and updates voice states each time anybody is joined/left voice chat in session.
-	 */
-	void onAvatarListRefreshed();
-
-	/**
-	 * Updates window title with an avatar name
-	 */
-	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-	
-	void updateTitle();
-	void initAgentData();
-	void setModeratorMutedVoice(bool moderator_muted);
-	void updateAgentModeratorState();
-	void onModeratorNameCache(const LLAvatarName& av_name);
-
-	/**
-	 * Sets initial participants voice states in avatar list (Invited, Joined, Has Left).
-	 *
-	 * @see refreshParticipantList()
-	 * @see onAvatarListRefreshed()
-	 * @see mInitParticipantsVoiceState
-	 */
-	void initParticipantsVoiceState();
-
-	/**
-	 * Updates participants voice states in avatar list (Invited, Joined, Has Left).
-	 *
-	 * @see onAvatarListRefreshed()
-	 * @see onChanged()
-	 */
-	void updateParticipantsVoiceState();
-
-	/**
-	 * Updates voice state of participant not in current voice channel depend on its current state.
-	 */
-	void updateNotInVoiceParticipantState(LLAvatarListItem* item);
-	void setState(LLAvatarListItem* item, ESpeakerState state);
-	void setState(const LLUUID& speaker_id, ESpeakerState state)
-	{
-		lldebugs << "Storing state: " << speaker_id << ", " << state << llendl;
-		mSpeakerStateMap[speaker_id] = state;
-	}
-
-	ESpeakerState getState(const LLUUID& speaker_id)
-	{
-		lldebugs << "Getting state: " << speaker_id << ", " << mSpeakerStateMap[speaker_id] << llendl;
-
-		return mSpeakerStateMap[speaker_id];
-	}
-
-	/**
-	 * Instantiates new LLAvatarListItemRemoveTimer and adds it into the map if it is not already created.
-	 *
-	 * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list when timer expires.
-	 */
-	void setVoiceRemoveTimer(const LLUUID& voice_speaker_id);
-
-	/**
-	 * Removes specified by UUID Avatar List item.
-	 *
-	 * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list.
-	 */
-	bool removeVoiceLeftParticipant(const LLUUID& voice_speaker_id);
-
-	/**
-	 * Deletes all timers from the list to prevent started timers from ticking after destruction
-	 * and after switching on another voice channel.
-	 */
-	void resetVoiceRemoveTimers();
-
-	/**
-	 * Removes specified by UUID timer from the map.
-	 *
-	 * @param voice_speaker_id LLUUID of Avatar List item whose timer should be removed from the map.
-	 */
-	void removeVoiceRemoveTimer(const LLUUID& voice_speaker_id);
-
-	/**
-	 * Called by LLParticipantList before adding a speaker to the participant list.
-	 *
-	 * If false is returned, the speaker will not be added to the list.
-	 *
-	 * @param speaker_id Speaker to validate.
-	 * @return true if this is a valid speaker, false otherwise.
-	 */
-	bool validateSpeaker(const LLUUID& speaker_id);
-
-	/**
-	 * Connects to passed channel to be updated according to channel's voice states.
-	 */
-	void connectToChannel(LLVoiceChannel* channel);
-
-	/**
-	 * Callback to process changing of voice channel's states.
-	 */
-	void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
-
-	/**
-	 * Updates floater according to passed channel's voice state.
-	 */
-	void updateState(const LLVoiceChannel::EState& new_state);
-
-	/**
-	 * Resets floater to be ready to show voice participants.
-	 *
-	 * Clears all data from the latest voice session.
-	 */
-	void reset(const LLVoiceChannel::EState& new_state);
-
-private:
-	speaker_state_map_t mSpeakerStateMap;
-	LLSpeakerMgr* mSpeakerManager;
-	LLParticipantList* mParticipants;
-	LLAvatarList* mAvatarList;
-	LLConversationViewModel mConversationViewModel;
-	LLNonAvatarCaller* mNonAvatarCaller;
-	EVoiceControls mVoiceType;
-	LLPanel* mAgentPanel;
-	LLOutputMonitorCtrl* mSpeakingIndicator;
-	bool mIsModeratorMutedVoice;
-
-	/**
-	 * Flag indicated that participants voice states should be initialized.
-	 *
-	 * It is used due to Avatar List has delayed refreshing after it content is changed.
-	 * Real initializing is performed when Avatar List is first time refreshed.
-	 *
-	 * @see onAvatarListRefreshed()
-	 * @see initParticipantsVoiceState()
-	 */
-	bool mInitParticipantsVoiceState;
-
-	boost::signals2::connection mAvatarListRefreshConnection;
-
-
-	/**
-	 * time out speakers when they are not part of current session
-	 */
-	LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;
-
-	/**
-	 * Stores reference to current voice channel.
-	 *
-	 * Is used to ignore voice channel changed callback for the same channel.
-	 *
-	 * @see onCurrentChannelChanged()
-	 */
-	static LLVoiceChannel* sCurrentVoiceChannel;
-
-	/* virtual */
-	LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
-
-	boost::signals2::connection mVoiceChannelStateChangeConnection;
-};
-
-
-#endif //LL_LLCALLFLOATER_H
-
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index c751550523..b99d04abae 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -32,7 +32,6 @@
 #include "llviewerfloaterreg.h"
 #include "llfloaterautoreplacesettings.h"
 #include "llcompilequeue.h"
-#include "llcallfloater.h"
 #include "llfasttimerview.h"
 #include "llfloaterabout.h"
 #include "llfloaterauction.h"
@@ -322,7 +321,6 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptPreview>, "upload");
 	LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
 
-	LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
 	LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
 
 	LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);	
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index f1bf4a6d75..7da71a04d9 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -3712,8 +3712,7 @@ void LLVivoxVoiceClient::participantUpdatedEvent(
 			 voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager                                          
 			 and event is not fired.                                                                                                               
 			 
-			 So, we have to call LLSpeakerMgr::update() here. In any case it is better than call it                                                
-			 in LLCallFloater::draw()                                                                                                              
+			 So, we have to call LLSpeakerMgr::update() here.                                                                                                              
 			 */
 			LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel();
 			
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
deleted file mode 100644
index dce2720cf8..0000000000
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ /dev/null
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- can_resize="true"
- can_minimize="true"
- can_close="true"
- chrome="true"
- height="205"
- layout="topleft"
- min_height="124"
- min_width="190"
- name="floater_voice_controls"
- help_topic="floater_voice_controls"
- title="VOICE CONTROLS"
- save_dock_state="true"
- save_visibility="true"
- save_rect="true"
- single_instance="true"
- width="282">
-    <string
-     name="title_nearby">
-        VOICE SETTINGS
-    </string>
-    <string
-     name="title_group">
-        GROUP CALL WITH [GROUP]
-    </string>
-    <string
-     name="title_adhoc">
-        CONFERENCE CALL
-    </string>
-    <string
-     name="title_peer_2_peer">
-        CALL WITH [NAME]
-    </string>
-    <string
-     name="no_one_near">
-        No one near has voice enabled
-    </string>
-      <layout_stack
-         clip="false"
-         follows="all"
-         height="189"
-         layout="topleft"
-         left="10"
-         mouse_opaque="false"
-         name="my_call_stack"
-         orientation="vertical"
-         width="263">
-        <layout_panel
-         follows="top|left|right"
-         auto_resize="false"
-         layout="topleft"
-         min_height="20"
-         height="20"
-         name="my_panel">
-            <avatar_icon
-             enabled="false"
-             follows="left|top"
-             height="18"
-             default_icon_name="Generic_Person"
-             layout="topleft"
-             left="5"
-             name="user_icon"
-             top="0"
-             width="18" />
-            <text
-             follows="top|left|right"
-             font="SansSerifSmallBold"
-             height="16"
-             layout="topleft"
-             left_pad="10"
-             name="user_text"
-             text_color="White"
-             top="4"
-             use_ellipses="true"
-             value="My Avatar:"
-             width="210" />
-            <output_monitor
-             auto_update="true"
-             draw_border="false"
-             follows="top|right"
-             height="16"
-             layout="topleft"
-             right="-3"
-             name="speaking_indicator"
-             left_pad="5"
-             visible="true"
-             width="20" />
-        </layout_panel>
-        <layout_panel name="leave_call_panel" height="26" min_height="26" auto_resize="false">
-        <layout_stack
-         clip="true"
-         follows="left|top|right"
-         height="26"
-         layout="topleft"
-         mouse_opaque="false"
-         name="voice_effect_and_leave_call_stack"
-         orientation="horizontal"
-         width="262">
-          <layout_panel
-            height="26"
-            width="200">
-            <panel
-             class="panel_voice_effect"
-             name="panel_voice_effect"
-             visiblity_control="VoiceMorphingEnabled"
-             filename="panel_voice_effect.xml" />
-          </layout_panel>
-          <layout_panel
-           auto_resize="false"
-           follows="top|right"
-           height="23"
-           visible="true"
-           layout="topleft"
-           name="leave_call_btn_panel"
-           width="100">
-            <button
-             follows="right|top"
-             height="23"
-             label="Leave Call"
-             name="leave_call_btn"
-             width="100" />
-          </layout_panel>
-        </layout_stack>
-          </layout_panel>
-      <layout_panel
-          follows="all"
-          layout="topleft"
-          left="2"
-          top_pad="0"
-          height="132"
-          name="callers_panel"
-          auto_resize="true"
-          width="280">
-        <avatar_list
-         follows="all"
-         height="132"
-         ignore_online_status="true"
-         layout="topleft"
-         multi_select="true"
-         name="speakers_list"
-         width="280" />
-        <panel
-         filename="panel_avatar_list_item.xml"
-         follows="left|right|top"
-         height="24"
-         layout="topleft"
-         left="0"
-         name="non_avatar_caller"
-         top="10"
-         width="276" />
-      </layout_panel>
-    </layout_stack>
-</floater>
-- 
cgit v1.2.3


From 37c416dee38a082aada799f0430022bd3051e54a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 5 Nov 2012 17:39:29 -0800
Subject: CHUI-479: Problem: The parent folder's view model did not store the
 session id. Because of this, the speaker indicator would be set to a session
 id of null (nearby chat). Solution: Now when the folder view model is created
 in the torn off list, pass in the session id. This allows the folder view
 model to know which session id it belongs to. Participants can then look at
 the parent folder (folder view) and retrieve the session id.

---
 indra/newview/llimconversation.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index de769d95ac..3e42e0b4ef 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -187,7 +187,7 @@ BOOL LLIMConversation::postBuild()
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
 	
 	// Create a root view folder for all participants
-	LLConversationItem* base_item = new LLConversationItem(mConversationViewModel);
+	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
     LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
     p.rect = LLRect(0, 0, getRect().getWidth(), 0);
     p.parent_panel = mParticipantListPanel;
-- 
cgit v1.2.3


From 2d9d44e31643214c80bde5ffee03f9b6af6af9d0 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 5 Nov 2012 18:33:39 -0800
Subject: CHUI-468 : WIP : Taking LLAvatarList and related out of
 LLParticipantList

---
 indra/newview/llconversationview.cpp               |   7 +-
 indra/newview/llimconversation.cpp                 |   5 +-
 indra/newview/llimconversation.h                   |   1 +
 indra/newview/llimfloatercontainer.cpp             |   4 +-
 indra/newview/llparticipantlist.cpp                | 142 ++++-----------------
 indra/newview/llparticipantlist.h                  |  37 ++----
 .../xui/en/panel_conversation_list_item.xml        |   2 +-
 7 files changed, 43 insertions(+), 155 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 81212a9141..87532268e7 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -108,7 +108,7 @@ BOOL LLConversationViewSession::postBuild()
 	mSessionTitle = mItemPanel->getChild<LLTextBox>("conversation_title");
 
 	mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewSession::onCurrentVoiceSessionChanged, this, _1));
-	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicatorn");
+	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
 
 	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
 	if (vmi)
@@ -476,10 +476,11 @@ void LLConversationViewParticipant::selectItem()
 void LLConversationViewParticipant::refresh()
 {
 	// Refresh the participant view from its model data
-	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+	LLConversationItemParticipant* vmi = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
 	vmi->resetRefresh();
 	
-	// Note: for the moment, all that needs to be done is done by LLFolderViewItem::refresh()
+	// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
+	mSpeakingIndicator->setIsMuted(vmi->isMuted());
 	
 	// Do the regular upstream refresh
 	LLFolderViewItem::refresh();
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index de769d95ac..62712a5c7c 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -485,7 +485,8 @@ LLConversationViewParticipant* LLIMConversation::createConversationViewParticipa
 
 void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
 {
-	// TODO: Check this code when sort order menu will be added. (EM)
+	// *TODO: Check this code when sort order menu will be added. (EM)
+	/*
 	if (!getParticipantList())
 	{
 		return;
@@ -497,7 +498,7 @@ void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
 	{
 		getParticipantList()->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
 	}
-
+	 */
 }
 
 void LLIMConversation::onIMSessionMenuItemClicked(const LLSD& userdata)
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index cb306c4d8d..ff248d97ff 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -36,6 +36,7 @@
 #include "llimview.h"
 #include "llconversationmodel.h"
 #include "llconversationview.h"
+#include "lltexteditor.h"
 
 class LLPanelChatControlPanel;
 class LLChatEntry;
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 72e0f90f8c..e6657260e6 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -115,7 +115,7 @@ void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 
 void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
 {
-	// CHUI-441 : We should do this *without* delete and recreate
+	// *TODO: We should do this *without* delete and recreate
 	addConversationListItem(new_session_id, removeConversationListItem(old_session_id));
 }
 
@@ -1164,7 +1164,7 @@ LLConversationItem* LLIMFloaterContainer::addConversationListItem(const LLUUID&
 	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
 	if (speaker_manager)
 	{
-		item = new LLParticipantList(speaker_manager, NULL, getRootViewModel(), true, false);
+		item = new LLParticipantList(speaker_manager, getRootViewModel(), true, false);
 	}
 	if (!item)
 	{
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index e199cb5776..6afcf21348 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file llparticipantlist.cpp
- * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages
+ * @brief LLParticipantList widgets of a conversation list
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -48,23 +48,6 @@
 #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
 #endif
 
-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)
-{
-	if (avatar_list)
-	{
-		LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(avatar_list->getItemByValue(avatar_uuid));
-		if (item)
-		{
-			LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator");
-			indicator->setIsMuted(is_muted);
-		}
-	}
-}
-
-
 // See EXT-4301.
 /**
  * class LLAvalineUpdater - observe the list of voice participants in session and check
@@ -205,14 +188,12 @@ private:
 };
 
 LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
-									 LLAvatarList* avatar_list,
 									 LLFolderViewModelInterface& root_view_model,
 									 bool use_context_menu/* = true*/,
 									 bool exclude_agent /*= true*/,
 									 bool can_toggle_icons /*= true*/) :
 	LLConversationItemSession(data_source->getSessionID(), root_view_model),
 	mSpeakerMgr(data_source),
-	mAvatarList(avatar_list),
 	mExcludeAgent(exclude_agent),
 	mValidateSpeakerCallback(NULL)
 {
@@ -234,7 +215,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 	mSpeakerMgr->addListener(mSpeakerUpdateListener, "update_speaker");
 
 	setSessionID(mSpeakerMgr->getSessionID());
-	
+	/*
 	if (mAvatarList)
 	{
 		mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
@@ -260,7 +241,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 			mAvatarListToggleIconsConnection = gSavedSettings.getControl("ParticipantListShowIcons")->getSignal()->connect(boost::bind(&LLAvatarList::toggleIcons, mAvatarList));
 		}
 	}
-
+	 */
 	//Lets fill avatarList with existing speakers
 	LLSpeakerMgr::speaker_list_t speaker_list;
 	mSpeakerMgr->getSpeakerList(&speaker_list, true);
@@ -278,8 +259,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 			mModeratorToRemoveList.insert(speakerp->mID);
 		}
 	}
-	// we need to exclude agent id for non group chat
-	sort();
 	
 	// Identify and store what kind of session we are
 	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(data_source->getSessionID());
@@ -305,6 +284,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 
 LLParticipantList::~LLParticipantList()
 {
+	/*
 	if (mAvatarList)
 	{
 		mAvatarListDoubleClickConnection.disconnect();
@@ -318,10 +298,11 @@ LLParticipantList::~LLParticipantList()
 		mAvatarList->setContextMenu(NULL);
 		mAvatarList->setComparator(NULL);
 	}
-
+	 */
 	delete mAvalineUpdater;
 }
 
+/*
 void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
 {
 	if (mAvatarList)
@@ -329,7 +310,8 @@ void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
 		mAvatarList->setSpeakingIndicatorsVisible(visible);
 	}
 }
-
+*/
+/*
 void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl)
 {
 	LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl);
@@ -345,7 +327,8 @@ void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl)
 	
 	LLAvatarActions::startIM(clicked_id);
 }
-
+*/
+/*
 void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 {
 	LLAvatarList* list = dynamic_cast<LLAvatarList*>(ctrl);
@@ -423,11 +406,10 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 		if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
 		{
 			setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
-			update_speaker_indicator(list, speakerp->mID, speakerp->mModeratorMutedVoice);
 		}
 	}
 }
-
+*/
 /*
   Seems this method is not necessary after onAvalineCallerRemoved was implemented;
 
@@ -441,40 +423,11 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 */
 void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
 {
-	if (mAvatarList)
-	{
-		LLPanel* item = mAvatarList->getItemByValue(participant_id);
-
-		if (NULL == item)
-		{
-			LL_WARNS("Avaline") << "Something wrong. Unable to find item for: " << participant_id << LL_ENDL;
-			return;
-		}
-
-		if (typeid(*item) == typeid(LLAvalineListItem))
-		{
-			LL_DEBUGS("Avaline") << "Avaline caller has already correct class type for: " << participant_id << LL_ENDL;
-			// item representing an Avaline caller has a correct type already.
-			return;
-		}
-
-		LL_DEBUGS("Avaline") << "remove item from the list and re-add it: " << participant_id << LL_ENDL;
-
-		// remove UUID from LLAvatarList::mIDs to be able add it again.
-		uuid_vec_t& ids = mAvatarList->getIDs();
-		uuid_vec_t::iterator pos = std::find(ids.begin(), ids.end(), participant_id);
-		ids.erase(pos);
-
-		// remove item directly
-		mAvatarList->removeItem(item);
-	}
-	
 	LLConversationItemParticipant* participant = findParticipant(participant_id);
 	if (participant)
 	{
 		removeParticipant(participant);
 	}
-
 	// re-add avaline caller with a correct class instance.
 	addAvatarIDExceptAgent(participant_id);
 }
@@ -485,7 +438,7 @@ void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
 
 	mSpeakerMgr->removeAvalineSpeaker(participant_id);
 }
-
+/*
 void LLParticipantList::setSortOrder(EParticipantSortOrder order)
 {
 	const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
@@ -502,7 +455,7 @@ const LLParticipantList::EParticipantSortOrder LLParticipantList::getSortOrder()
 	const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
 	return EParticipantSortOrder(speaker_sort_order);
 }
-
+*/
 void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
 {
 	mValidateSpeakerCallback = cb;
@@ -512,19 +465,14 @@ void LLParticipantList::update()
 {
 	mSpeakerMgr->update(true);
 
+	/*
 	// Need to resort the participant list if it's in sort by recent speaker order.
-	if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder() && !isHovered())
+	if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder())
 	{
 		// Resort avatar list
 		sort();
 	}
-}
-
-bool LLParticipantList::isHovered()
-{
-	S32 x, y;
-	LLUI::getMousePositionScreen(&x, &y);
-	return (mAvatarList ? mAvatarList->calcScreenRect().pointInRect(x, y) : false);
+	 */
 }
 
 bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
@@ -537,35 +485,18 @@ bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, co
 	}
 
 	addAvatarIDExceptAgent(uu_id);
-	sort();
 	return true;
 }
 
 bool LLParticipantList::onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
 {
 	LLUUID avatar_id = event->getValue().asUUID();
-	if (mAvatarList)
-	{
-		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)
 {
-	if (mAvatarList)
-	{
-		uuid_vec_t& group_members = mAvatarList->getIDs();
-		group_members.clear();
-		mAvatarList->setDirty();
-	}
 	clearParticipants();
 	return true;
 }
@@ -605,9 +536,9 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> e
 					mModeratorList.erase(id);
 				}
 			}
-
+			// *TODO : do we have to fire an event so that LLIMConversation::refreshConversation() gets called
 			// apply changes immediately
-			onAvatarListRefreshed(mAvatarList, LLSD());
+			//onAvatarListRefreshed(mAvatarList, LLSD());
 		}
 	}
 	return true;
@@ -622,11 +553,11 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
 	if (event->getValue().asString() == "voice")
 	{
 		setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
-		update_speaker_indicator(mAvatarList, speakerp->mID, speakerp->mModeratorMutedVoice);
 	}
 	return true;
 }
 
+/*
 void LLParticipantList::sort()
 {
 	// *TODO : Merov : Need to plan for sort() for LLConversationModel
@@ -658,12 +589,12 @@ void LLParticipantList::sort()
 			return;
 	}
 }
+*/
 
 void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 {
 	// Do not add if already in there or excluded for some reason
 	if (mExcludeAgent && gAgent.getID() == avatar_id) return;
-	if (mAvatarList && mAvatarList->contains(avatar_id)) return;
 	if (findParticipant(avatar_id)) return;
 
 	bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id);
@@ -677,21 +608,25 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 		bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
 		participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.mDisplayName , avatar_id, mRootViewModel);
 		participant->fetchAvatarName();
+		/*
 		if (mAvatarList)
 		{
 			mAvatarList->getIDs().push_back(avatar_id);
 			mAvatarList->setDirty();
 		}
+		 */
 	}
 	else
 	{
 		std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
 		// Create a participant view model instance
 		participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
+		/*
 		if (mAvatarList)
 		{
 			mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
 		}
+		 */
 		mAvalineUpdater->watchAvalineCaller(avatar_id);
 	}
 
@@ -768,33 +703,4 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::
 	return mParent.onSpeakerMuteEvent(event, userdata);
 }
 
-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 aaf1e070a5..97e06dcfea 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -1,6 +1,6 @@
 /** 
  * @file llparticipantlist.h
- * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages
+ * @brief LLParticipantList widgets of a conversation list
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -29,12 +29,10 @@
 
 #include "llviewerprecompiledheaders.h"
 #include "llevent.h"
-#include "llavatarlist.h" // for LLAvatarItemRecentSpeakerComparator
 #include "lllistcontextmenu.h"
 #include "llconversationmodel.h"
 
 class LLSpeakerMgr;
-class LLAvatarList;
 class LLUICtrl;
 class LLAvalineUpdater;
 
@@ -46,13 +44,12 @@ public:
 	typedef boost::function<bool (const LLUUID& speaker_id)> validate_speaker_callback_t;
 
 	LLParticipantList(LLSpeakerMgr* data_source, 
-					  LLAvatarList* avatar_list, 
 					  LLFolderViewModelInterface& root_view_model,
 					  bool use_context_menu = true, 
 					  bool exclude_agent = true, 
 					  bool can_toggle_icons = true);
 	~LLParticipantList();
-	void setSpeakingIndicatorsVisible(BOOL visible);
+//	void setSpeakingIndicatorsVisible(BOOL visible);
 
 	enum EParticipantSortOrder
 	{
@@ -70,8 +67,8 @@ public:
 	/**
 	 * Set and sort Avatarlist by given order
 	 */
-	void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME);
-	const EParticipantSortOrder getSortOrder() const;
+	//void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME);
+	//const EParticipantSortOrder getSortOrder() const;
 
 	/**
 	 * Refreshes the participant list.
@@ -101,7 +98,7 @@ protected:
 	/**
 	 * Sorts the Avatarlist by stored order
 	 */
-	void sort();
+	//void sort();
 
 	/**
 	 * List of listeners implementing LLOldEvents::LLSimpleListener.
@@ -159,24 +156,9 @@ protected:
 		/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	};
 
-	/**
-	 * 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(LLUICtrl* ctrl);
-	void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param);
+//	void onAvatarListDoubleClicked(LLUICtrl* ctrl);
+//	void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param);
 
 	void onAvalineCallerFound(const LLUUID& participant_id);
 	void onAvalineCallerRemoved(const LLUUID& participant_id);
@@ -188,10 +170,7 @@ private:
 	 */
 	void adjustParticipant(const LLUUID& speaker_id);
 
-	bool isHovered();
-
 	LLSpeakerMgr*		mSpeakerMgr;
-	LLAvatarList*		mAvatarList;
 
 	std::set<LLUUID>	mModeratorList;
 	std::set<LLUUID>	mModeratorToRemoveList;
@@ -216,7 +195,7 @@ private:
 	boost::signals2::connection mAvatarListReturnConnection;
 	boost::signals2::connection mAvatarListToggleIconsConnection;
 
-	LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers;
+//	LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers;
 	validate_speaker_callback_t mValidateSpeakerCallback;
 	LLAvalineUpdater* mAvalineUpdater;
 };
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
index 56056ed560..771d9fa680 100644
--- a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
@@ -90,7 +90,7 @@
 		     layout="topleft"
 		     left_pad="5"
  		     mouse_opaque="true"
- 		     name="speaking_indicatorn"
+ 		     name="speaking_indicator"
  		     visible="false"
  		     width="20" />
         </layout_panel>
-- 
cgit v1.2.3


From 50615ba69c94441c99f21f861cf0290972162998 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 6 Nov 2012 17:56:25 -0800
Subject: CHUI-507: Updated to the new layout of 'Chat Preferences' according
 to CHUI Notifications spec. The functionality for the new preferences is not
 yet implemented.

---
 .../default/xui/en/panel_preferences_chat.xml      | 449 +++++++++++++++------
 1 file changed, 331 insertions(+), 118 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index c76a3cfaaf..28434a670e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -9,151 +9,364 @@
  name="chat"
  top="1"
  width="517">
-  <text
-   follows="left|top"
-   layout="topleft"
-   left="30"
-   height="12"
-   name="font_size"
-   width="120"
-   top="10">
-    Font size:
-  </text>
-  <radio_group
-     height="30"
-     layout="topleft"
-     left="40"
-	 control_name="ChatFontSize"
-     name="chat_font_size"
-     top_pad="0"
-     width="440">
-        <radio_item
-         height="16"
-         label="Small"
-         layout="topleft"
-         left="0"
-         name="radio"
-         value="0"
-         top="10"
-         width="125" />
-        <radio_item
-         height="16"
-         label="Medium"
-         layout="topleft"
-         left_delta="145"
-         name="radio2"
-         value="1"
-         top_delta="0"
-         width="125" />
-        <radio_item
-         height="16"
-         label="Large"
-         layout="topleft"
-         left_delta="170"
-         name="radio3"
-         value="2"
-         top_delta="0"
-         width="125" />
-    </radio_group>
-    
+
+  <panel
+  border="false"
+  follows="left|top"
+  height="90"
+  layout="topleft"
+  top="10"
+  left="13"
+  width="517">
+
     <check_box
-     control_name="PlayTypingAnim"
-     height="16"
-     initial_value="true"
-     label="Play typing animation when chatting"
-     layout="topleft"
-     left="30"
-     name="play_typing_animation"
-     top_pad="10"
-     width="400" />
+       control_name="PlayTypingAnim"
+       height="16"
+       initial_value="true"
+       label="Play typing animation when chatting"
+       layout="topleft"
+       top="0"
+       name="play_typing_animation"
+       width="330" />
     <check_box
      enabled="false"
      height="16"
      label="Email me IMs when I'm offline"
      layout="topleft"
-     left_delta="0"
      name="send_im_to_email"
-     top_pad="5"
-     width="400" />
+     top_pad="6"
+     width="330" />
+    <check_box
+    height="16"
+    label="Keep a conversation log and transcripts"
+    layout="topleft"
+    name="keep_convo_log_and_transcripts"
+    top_pad="6"
+    width="330" />
     <check_box
      control_name="UseChatBubbles"
      follows="left|top"
      height="16"
      label="Bubble Chat"
      layout="topleft"
-     left_delta="0"
-     top_pad="5"
+     top_pad="6"
      name="bubble_text_chat"
-     width="150" />     
+     width="330" />
     <text
-     name="disable_toast_label"
      follows="left|top"
      layout="topleft"
-     top_pad="20" 
-     left="30" 
-     height="10"
-     width="400">
-      Enable incoming chat popups:
-      </text>
-    <check_box
-     control_name="EnableGroupChatPopups"
-     name="EnableGroupChatPopups"
-     label="Group Chats" 
-     layout="topleft"
-     top_pad="5" 
-     left_delta="10" 
-     height="20"
-     tool_tip="Check to see popups when a Group Chat message arrives"
-     width="400" />
-    <check_box
-     control_name="EnableIMChatPopups"
-     name="EnableIMChatPopups"
-     label="IM Chats" 
-     layout="topleft"
-     top_pad="5"
-     height="16"
-     tool_tip="Check to see popups when an instant message arrives"
-     width="400" />
-    <spinner
-     control_name="NearbyToastLifeTime"
-     decimal_digits="0"
+     left="345"
+     height="12"
+     name="font_size"
+     width="120"
+     top="0">
+      Font size:
+    </text>
+    <radio_group
+       height="90"
+       layout="topleft"
+       left="352"
+     control_name="ChatFontSize"
+       name="chat_font_size"
+       top_pad="0"
+       width="50">
+      <radio_item
+       height="16"
+       label="Small"
+       layout="topleft"
+       name="radio"
+       value="0"
+       top="10"
+       width="125" />
+      <radio_item
+       height="16"
+       label="Medium"
+       layout="topleft"
+       name="radio2"
+       value="1"
+       top_pad="6"
+       width="125" />
+      <radio_item
+       height="16"
+       label="Large"
+       layout="topleft"
+       name="radio3"
+       value="2"
+       top_pad="6"
+       width="125" />
+    </radio_group>    
+    
+  </panel>  
+
+  <panel
+  border="false"
+  follows="left|top"
+  height="193"
+  layout="topleft"
+  left="13"
+  width="517">
+
+    <text
      follows="left|top"
-     height="23"
-     increment="1"
-     initial_value="23"
-     label="Nearby chat toasts life time:"
-     label_width="285"
      layout="topleft"
-     left="45"
-     max_val="60"
-     min_val="1"
-     name="nearby_toasts_lifetime"
-     top_pad="10"
-     width="325" />
-    <spinner
-     control_name="NearbyToastFadingTime"
-     decimal_digits="0"
+     height="12"
+     name="notifications"
+     left="0"
+     width="120">
+      Notifications:
+    </text>
+    <text
      follows="left|top"
-     height="23"
-     increment="1"
-     initial_value="3"
-     label="Nearby chat toasts fading time:"
-     label_width="285"
      layout="topleft"
-     left_delta="0"
-     max_val="60"
-     min_val="0"
-     name="nearby_toasts_fadingtime"
-     top_pad="3"
-     width="325" />
+     height="12"
+     name="friend_ims"
+     width="145"
+     left="0"
+     top_pad="15"
+     >
+      Friend IMs:
+    </text>
+    <combo_box
+             control_name="NotificationFriendIMOptions"
+             height="23"
+             layout="topleft"
+             left_pad="5"
+             top_delta="-6"
+             name="FriendIMOptions"
+             width="223">
+      <combo_box.item
+       label="Pop up the message"
+       name="0"
+       value="0"/>
+      <combo_box.item
+       label="Flash toolbar button"
+       name="1"
+       value="1"/>
+      <combo_box.item
+       label="None"
+       name="2"
+       value="2"/>
+    </combo_box>
+    <text
+        follows="left|top"
+        layout="topleft"
+        height="12"
+        name="non_friend_ims"
+        width="145"
+        left="0"
+     top_pad="15"
+     >
+      Non-friend IMs:
+    </text>
+    <combo_box
+             control_name="NotificationNonFriendIMOptions"
+             height="23"
+             layout="topleft"
+             left_pad="5"
+             top_delta="-6"
+             name="NonFriendIMOptions"
+             width="223">
+      <combo_box.item
+       label="Pop up the message"
+       name="0"
+       value="0"/>
+      <combo_box.item
+       label="Flash toolbar button"
+       name="1"
+       value="1"/>
+      <combo_box.item
+       label="None"
+       name="2"
+       value="2"/>
+    </combo_box>
+    <text
+          follows="left|top"
+          layout="topleft"
+          left="0"
+          height="13"
+          name="conference_ims"
+          width="145"
+          top_pad="14"
+     >
+      Conference IMs:
+    </text>
+    <combo_box
+             control_name="NotificationConferenceIMOptions"
+             height="23"
+             layout="topleft"
+             left_pad="5"
+             top_delta="-6"
+             name="ConferenceIMOptions"
+             width="223">
+      <combo_box.item
+       label="Pop up the message"
+       name="0"
+       value="0"/>
+      <combo_box.item
+       label="Flash toolbar button"
+       name="1"
+       value="1"/>
+      <combo_box.item
+       label="None"
+       name="2"
+       value="2"/>
+    </combo_box>
+    <text
+          follows="left|top"
+          layout="topleft"
+          left="0"
+          height="13"
+          name="group_chat"
+          width="145"
+          top_pad="14"
+     >
+      Group chat:
+    </text>
+    <combo_box
+             control_name="NotificationGroupChatOptions"
+             height="23"
+             layout="topleft"
+             left_pad="5"
+             top_delta="-6"
+             name="GroupChatOptions"
+             width="223">
+      <combo_box.item
+       label="Pop up the message"
+       name="0"
+       value="0"/>
+      <combo_box.item
+       label="Flash toolbar button"
+       name="1"
+       value="1"/>
+      <combo_box.item
+       label="None"
+       name="2"
+       value="2"/>
+    </combo_box>
+    <text
+            follows="left|top"
+            layout="topleft"
+            left="0"
+            height="12"
+            name="nearby_chat"
+            width="145"
+            top_pad="14"
+     >
+      Nearby chat:
+    </text>
+    <combo_box
+             control_name="NotificationNearbyChatOptions"
+             height="23"
+             layout="topleft"
+             left_pad="5"
+             top_delta="-6"
+             name="NearbyChatOptions"
+             width="223">
+      <combo_box.item
+       label="Pop up the message"
+       name="0"
+       value="0"/>
+      <combo_box.item
+       label="Flash toolbar button"
+       name="1"
+       value="1"/>
+      <combo_box.item
+       label="None"
+       name="2"
+       value="2"/>
+    </combo_box>
+    <text
+            follows="left|top"
+            layout="topleft"
+            left="0"
+            height="12"
+            name="notifications_alert"
+            width="350"
+            top_pad="11"
+            visible="true"
+            text_color="DrYellow"
+     >
+      To temporarily stop all notifications, use Me > Status > Busy.
+    </text>
+
+  </panel>
+
+  <panel
+  border="false"
+  follows="left|top"
+  height="1"
+  layout="topleft"
+  left="13"
+  width="517">
+
+    <text
+      follows="left|top"
+      layout="topleft"
+      left="0"
+      name="play_sound"
+      width="100"
+      top_pad="13"
+      visible="true">
+      Play sound:
+    </text>
+    <check_box
+         control_name="NewConversation"
+         height="16"
+         initial_value="true"
+         label="New conversation"
+         layout="topleft"
+         left_pad="15"
+         top_pad="-10"
+         name="new_conversation"
+         width="150" />
+    <check_box
+         control_name="IncomingVoiceCall"
+         height="16"
+         initial_value="true"
+         label="Incoming voice call"
+         layout="topleft"
+         top_pad="6"
+         name="incoming_voice_call"
+         width="150" />
+    <check_box
+         control_name="GroupChatMessages"
+         height="16"
+         initial_value="false"
+         label="Group chat messages"
+         layout="topleft"
+         top_pad="6"
+         name="group_chat_messages"
+         width="150" />
+    <check_box
+         control_name="TeleportOffer"
+         height="16"
+         initial_value="true"
+         label="Teleport offer"
+         layout="topleft"
+         left_pad="35"
+         top_pad="-59"
+         name="teleport_offer"
+         width="150" />
+    <check_box
+         control_name="InventoryOffer"
+         height="16"
+         initial_value="false"
+         label="Inventory offer"
+         layout="topleft"
+         top_pad="6"
+         name="inventory_offer"
+         width="150" />
+
+  </panel>
+    
   <button
    follows="left|top"
    height="23"
    label="Translation..."
    layout="topleft"
-   left="30"
+   left="9"
    name="ok_btn"
-   top="-50"
+   top="-29"
    width="170">
    <button.commit_callback
     function="Pref.TranslationSettings" />
-- 
cgit v1.2.3


From a337d7e59776f0ae6ecf72f67c813c9c60cfd8c7 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 7 Nov 2012 12:47:00 +0200
Subject: Fixed postBuild() for Ad-hoc conference

---
 indra/newview/llconversationview.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index de0c65e24f..0f649361fb 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -133,6 +133,7 @@ BOOL LLConversationViewSession::postBuild()
 			LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
 			icon->setVisible(true);
 			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
+			break;
 		}
 		case LLConversationItem::CONV_SESSION_GROUP:
 		{
-- 
cgit v1.2.3


From 8828eb21e2a8960bbcfd4edb2d113dbada7d4a5d Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 6 Nov 2012 22:02:09 +0200
Subject: CHUI-448 FIXED p2p IM chat conversations show a participant list with
 a carat

---
 indra/llui/llfolderviewitem.h          |  2 +-
 indra/newview/llconversationview.cpp   |  9 ++++++++
 indra/newview/llconversationview.h     |  2 ++
 indra/newview/llimfloatercontainer.cpp | 41 +++++++++++++++++++++-------------
 4 files changed, 38 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 7cbe70fb8b..8bb73bcf5d 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -260,7 +260,7 @@ public:
 
 	//	virtual void handleDropped();
 	virtual void draw();
-	void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
+	virtual void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
     void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
     void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 0f649361fb..2d3a008bf4 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -344,6 +344,15 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
 	}
 }
 
+void LLConversationViewSession::drawOpenFolderArrow(const LLFolderViewItem::Params& default_params, const LLUIColor& fg_color)
+{
+	LLConversationItem * itemp = dynamic_cast<LLConversationItem*>(getViewModelItem());
+	if (itemp && itemp->getType() != LLConversationItem::CONV_SESSION_1_ON_1)
+	{
+		LLFolderViewFolder::drawOpenFolderArrow(default_params, fg_color);
+	}
+}
+
 //
 // Implementation of conversations list participant (avatar) widgets
 //
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 4d77a4ade0..aeca747260 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -71,6 +71,8 @@ public:
 
 	/*virtual*/	bool isMinimized() { return mMinimizedMode; }
 
+	/*virtual*/ void drawOpenFolderArrow(const LLFolderViewItem::Params& default_params, const LLUIColor& fg_color);
+
 	void toggleMinimizedMode(bool is_minimized);
 
 	void setVisibleIfDetached(BOOL visible);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 52deae445b..af43b1ac38 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -424,15 +424,21 @@ bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
 			LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
 			if (session_model)
 			{
-				LLConversationItemParticipant* participant_model = session_model->findParticipant(participant_id);
-				if (participant_model)
+				const LLUUID& uuid = session_model->getUUID();
+
+				LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(uuid);
+
+				if (uuid.isNull() || im_sessionp && !im_sessionp->isP2PSessionType())
 				{
-					participant_view = createConversationViewParticipant(participant_model);
-					participant_view->addToFolder(session_view);
-					participant_view->setVisible(TRUE);
+					LLConversationItemParticipant* participant_model = session_model->findParticipant(participant_id);
+					if (participant_model)
+					{
+						participant_view = createConversationViewParticipant(participant_model);
+						participant_view->addToFolder(session_view);
+						participant_view->setVisible(TRUE);
+					}
 				}
 			}
-
 		}
 	}
 	else if (type == "update_participant")
@@ -1175,17 +1181,22 @@ void LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWi
 	// Add a new conversation widget to the root folder of the folder view
 	widget->addToFolder(mConversationsRoot);
 	widget->requestArrange();
-	
+
+	LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(uuid);
+
 	// Create the participants widgets now
 	// Note: usually, we do not get an updated avatar list at that point
-	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
-	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
-	while (current_participant_model != end_participant_model)
-	{
-		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
-		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
-		participant_view->addToFolder(widget);
-		current_participant_model++;
+	if (uuid.isNull() || im_sessionp && !im_sessionp->isP2PSessionType())
+	{
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+			LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+			participant_view->addToFolder(widget);
+			current_participant_model++;
+		}
 	}
 
 	// set the widget to minimized mode if conversations pane is collapsed
-- 
cgit v1.2.3


From 990a8c6085b43cb0290a631b664b3160938b0536 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Tue, 6 Nov 2012 22:44:22 +0200
Subject: CHUI-462 (Torn-off Nearby Chat can't be closed)

---
 indra/newview/llimconversation.cpp     |  4 ----
 indra/newview/llimfloatercontainer.cpp |  7 +++++++
 indra/newview/llimfloatercontainer.h   |  2 ++
 indra/newview/llnearbychat.cpp         | 22 +++++++++++++++++++++-
 indra/newview/llnearbychat.h           |  2 ++
 5 files changed, 32 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index b687e18cae..44cf300930 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -202,10 +202,6 @@ BOOL LLIMConversation::postBuild()
 
 	if (isChatMultiTab())
 	{
-		if (mIsNearbyChat)
-		{
-			setCanClose(FALSE);
-		}
 		result = LLFloater::postBuild();
 	}
 	else
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index f85aa9a353..c9cd013317 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1475,4 +1475,11 @@ void LLIMFloaterContainer::openNearbyChat()
 	}
 }
 
+void LLIMFloaterContainer::onNearbyChatClosed()
+{
+	// If nearby chat is the only remaining conversation and it is closed, close whole conversation floater as well
+	if (mConversationsItems.size() == 1)
+		closeFloater();
+}
+
 // EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 05ea94019b..16218fc287 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -92,6 +92,8 @@ public:
     LLUUID getSelectedSession() { return mSelectedSession; }
     void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
 
+	void onNearbyChatClosed();
+
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
 	avatarID_panel_map_t mSessions;
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index d1c7c6bfd7..cf42fcb91a 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -293,7 +293,7 @@ void LLNearbyChat::setVisible(BOOL visible)
     setFocus(visible);
 }
 
-
+// virtual
 void LLNearbyChat::onTearOffClicked()
 {
 	LLIMConversation::onTearOffClicked();
@@ -311,6 +311,26 @@ void LLNearbyChat::onOpen(const LLSD& key)
 	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 }
 
+// virtual
+void LLNearbyChat::onClose(bool app_quitting)
+{
+	// Override LLIMConversation::onClose() so that Nearby Chat is not removed from the conversation floater
+}
+
+// virtual
+void LLNearbyChat::onClickCloseBtn()
+{
+	if (!isTornOff())
+		return;
+	onTearOffClicked();
+	
+	LLIMFloaterContainer *im_box = LLIMFloaterContainer::findInstance();
+	if (im_box)
+	{
+		im_box->onNearbyChatClosed();
+	}
+}
+
 void LLNearbyChat::onChatFontChange(LLFontGL* fontp)
 {
 	// Update things with the new font whohoo
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index b155fd3c26..a6c4439b1d 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -52,6 +52,7 @@ public:
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onClose(bool app_quitting);
     /*virtual*/ void setFocus(BOOL focusFlag);
 	/*virtual*/ void setVisible(BOOL visible);
 
@@ -96,6 +97,7 @@ protected:
 	void onChatFontChange(LLFontGL* fontp);
 
 	/*virtual*/ void onTearOffClicked();
+	/*virtual*/ void onClickCloseBtn();
 
 	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
 	EChatType processChatTypeTriggers(EChatType type, std::string &str);
-- 
cgit v1.2.3


From 18011db7f0b60e4ec499e3cbdda4e4f716f458a2 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 6 Nov 2012 15:47:08 -0800
Subject: Altering the line item phone icon.

---
 indra/newview/skins/default/xui/en/panel_conversation_list_item.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
index 56056ed560..67feade9a3 100644
--- a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
@@ -54,14 +54,14 @@
          visible="false"
          width="20">
             <icon
-             height="20"
+             height="18"
              follows="top|right|left"
              image_name="Conv_toolbar_open_call"
              layout="topleft"
              left="0"
              name="selected_icon"
-             top="2"
-             width="20" />
+             top="3"
+             width="18" />
         </layout_panel>
         <layout_panel
          auto_resize="true"
-- 
cgit v1.2.3


From 8c64fbf1b76e46fa3f5a8f8c6baba30d4583b7ec Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 6 Nov 2012 18:32:45 -0800
Subject: CHUI-468 : WIP : More cleanup and fix of the participants sorting in
 LLIMConversation

---
 indra/newview/llimconversation.cpp     | 22 ++++++----------------
 indra/newview/llimconversation.h       |  5 ++---
 indra/newview/llimfloatercontainer.cpp | 13 +++++++++++++
 indra/newview/llimfloatercontainer.h   |  1 +
 indra/newview/llparticipantlist.cpp    |  9 ---------
 indra/newview/llparticipantlist.h      |  1 -
 6 files changed, 22 insertions(+), 29 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index f91c25ef8c..fb247b4604 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -166,7 +166,8 @@ void LLIMConversation::addToHost(const LLUUID& session_id)
 				conversp->setHost(floater_container);
 				conversp->setHost(NULL);
 			}
-
+			// Added floaters share some state (like sort order) with their host
+			conversp->setSortOrder(floater_container->getSortOrder());
 		}
 	}
 }
@@ -483,22 +484,11 @@ LLConversationViewParticipant* LLIMConversation::createConversationViewParticipa
 	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
 }
 
-void LLIMConversation::onSortMenuItemClicked(const LLSD& userdata)
+void LLIMConversation::setSortOrder(const LLConversationSort& order)
 {
-	// *TODO: Check this code when sort order menu will be added. (EM)
-	/*
-	if (!getParticipantList())
-	{
-		return;
-	}
-
-	std::string chosen_item = userdata.asString();
-
-	if (chosen_item == "sort_name")
-	{
-		getParticipantList()->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
-	}
-	 */
+	mConversationViewModel.setSorter(order);
+	mConversationsRoot->arrangeAll();
+	refreshConversation();
 }
 
 void LLIMConversation::onIMSessionMenuItemClicked(const LLSD& userdata)
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index ff248d97ff..edcae5e45d 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -89,7 +89,8 @@ public:
 	void refreshConversation();
 	void buildConversationViewParticipant();
 
-
+	void setSortOrder(const LLConversationSort& order);
+	
 protected:
 
 	// callback for click on any items of the visual states menu
@@ -107,8 +108,6 @@ protected:
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
 
-	void onSortMenuItemClicked(const LLSD& userdata);
-
 	void hideOrShowTitle(); // toggle the floater's drag handle
 	void hideAllStandardButtons();
 
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index e6657260e6..4b992a2e0f 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -764,6 +764,19 @@ void LLIMFloaterContainer::setSortOrder(const LLConversationSort& order)
 	mConversationsRoot->arrangeAll();
 	// try to keep selection onscreen, even if it wasn't to start with
 	mConversationsRoot->scrollToShowSelection();
+	
+	// Notify all conversation (torn off or not) of the change to the sort order
+	// Note: For the moment, the sort order is *unique* across all conversations. That might change in the future.
+	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	{
+		LLUUID session_id = it_session->first;
+		LLIMConversation *conversation_floater = (session_id.isNull() ? (LLIMConversation*)(LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")) : (LLIMConversation*)(LLIMFloater::findInstance(session_id)));
+		if (conversation_floater)
+		{
+			conversation_floater->setSortOrder(order);
+		}
+	}
+	
 	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
 }
 
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index a6f8677e46..5ae3f9f1d4 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -92,6 +92,7 @@ public:
     LLUUID getSelectedSession() { return mSelectedSession; }
     void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
 	LLConversationItem* getSessionModel(const LLUUID& session_id) { return get_ptr_in_map(mConversationsItems,session_id); }
+	LLConversationSort& getSortOrder() { return mConversationViewModel.getSorter(); }
 
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 6afcf21348..e6eef56628 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -302,15 +302,6 @@ LLParticipantList::~LLParticipantList()
 	delete mAvalineUpdater;
 }
 
-/*
-void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
-{
-	if (mAvatarList)
-	{
-		mAvatarList->setSpeakingIndicatorsVisible(visible);
-	}
-}
-*/
 /*
 void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl)
 {
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 97e06dcfea..f4469b03f4 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -49,7 +49,6 @@ public:
 					  bool exclude_agent = true, 
 					  bool can_toggle_icons = true);
 	~LLParticipantList();
-//	void setSpeakingIndicatorsVisible(BOOL visible);
 
 	enum EParticipantSortOrder
 	{
-- 
cgit v1.2.3


From 4ec5ee63e28a427d88dfc0329151eacaf375fdb6 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Wed, 7 Nov 2012 12:07:52 +0200
Subject: CHUI-450 (Your own name does not appear in nearby chat participant
 list if voice chat disabled) Added audio module initialization without faking
 mVoiceEnabled value

---
 indra/newview/llspeakers.cpp   |  2 +-
 indra/newview/llvoicevivox.cpp | 42 +++++++++++++++++-------------------------
 indra/newview/llvoicevivox.h   |  2 ++
 3 files changed, 20 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 46fd8c1290..726199b7aa 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -504,7 +504,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
 void LLSpeakerMgr::updateSpeakerList()
 {
 	// are we bound to the currently active voice channel?
-	if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
+	if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel))
 	{
 	        std::set<LLUUID> participants;
 	        LLVoiceClient::getInstance()->getParticipantList(participants);
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index f236123ef1..839de395a7 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -291,6 +291,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 	mCaptureDeviceDirty(false),
 	mRenderDeviceDirty(false),
 	mSpatialCoordsDirty(false),
+	mIsInitialized(false),
 
 	mMuteMic(false),
 	mMuteMicDirty(false),
@@ -394,15 +395,7 @@ const LLVoiceVersionInfo& LLVivoxVoiceClient::getVersion()
 
 void LLVivoxVoiceClient::updateSettings()
 {
-	if(!mAudioSession)
-	{
-		// If audio module is not initialized, pretend that voice is enabled, thus letting state machine to take a full cycle
-		setVoiceEnabled(true);
-	}
-	else
-	{
-		setVoiceEnabled(gSavedSettings.getBOOL("EnableVoiceChat"));
-	}
+	setVoiceEnabled(gSavedSettings.getBOOL("EnableVoiceChat"));
 	setEarLocation(gSavedSettings.getS32("VoiceEarLocation"));
 
 	std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
@@ -528,7 +521,7 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries)
 {
 	LLViewerRegion *region = gAgent.getRegion();
 	
-	if ( region && mVoiceEnabled )
+	if ( region && (mVoiceEnabled || !mIsInitialized))
 	{
 		std::string url = 
 		region->getCapability("ProvisionVoiceAccountRequest");
@@ -699,7 +692,7 @@ void LLVivoxVoiceClient::stateMachine()
 		setVoiceEnabled(false);
 	}
 	
-	if(mVoiceEnabled)
+	if(mVoiceEnabled || !mIsInitialized)
 	{
 		updatePosition();
 	}
@@ -744,7 +737,7 @@ void LLVivoxVoiceClient::stateMachine()
 		
 		//MARK: stateDisabled
 		case stateDisabled:
-			if(mTuningMode || (mVoiceEnabled && !mAccountName.empty()))
+			if(mTuningMode || ((mVoiceEnabled || !mIsInitialized) && !mAccountName.empty()))
 			{
 				setState(stateStart);
 			}
@@ -899,7 +892,7 @@ void LLVivoxVoiceClient::stateMachine()
 				mTuningExitState = stateIdle;
 				setState(stateMicTuningStart);
 			}
-			else if(!mVoiceEnabled)
+			else if(!mVoiceEnabled && mIsInitialized)
 			{
 				// We never started up the connector.  This will shut down the daemon.
 				setState(stateConnectorStopped);
@@ -1093,7 +1086,7 @@ void LLVivoxVoiceClient::stateMachine()
 
 			//MARK: stateConnectorStart
 		case stateConnectorStart:
-			if(!mVoiceEnabled)
+			if(!mVoiceEnabled && mIsInitialized)
 			{
 				// We were never logged in.  This will shut down the connector.
 				setState(stateLoggedOut);
@@ -1111,7 +1104,7 @@ void LLVivoxVoiceClient::stateMachine()
 		
 		//MARK: stateConnectorStarted
 		case stateConnectorStarted:		// connector handle received
-			if(!mVoiceEnabled)
+			if(!mVoiceEnabled && mIsInitialized)
 			{
 				// We were never logged in.  This will shut down the connector.
 				setState(stateLoggedOut);
@@ -1255,7 +1248,7 @@ void LLVivoxVoiceClient::stateMachine()
 		
 		//MARK: stateCreatingSessionGroup
 		case stateCreatingSessionGroup:
-			if(mSessionTerminateRequested || !mVoiceEnabled)
+			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized)
 			{
 				// *TODO: Question: is this the right way out of this state
 				setState(stateSessionTerminated);
@@ -1271,7 +1264,7 @@ void LLVivoxVoiceClient::stateMachine()
 		//MARK: stateRetrievingParcelVoiceInfo
 		case stateRetrievingParcelVoiceInfo: 
 			// wait until parcel voice info is received.
-			if(mSessionTerminateRequested || !mVoiceEnabled)
+			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized)
 			{
 				// if a terminate request has been received,
 				// bail and go to the stateSessionTerminated
@@ -1291,7 +1284,7 @@ void LLVivoxVoiceClient::stateMachine()
 			// Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync.
 			sendFriendsListUpdates();
 			
-			if(mSessionTerminateRequested || !mVoiceEnabled)
+			if(mSessionTerminateRequested || !mVoiceEnabled && mIsInitialized)
 			{
 				// TODO: Question: Is this the right way out of this state?
 				setState(stateSessionTerminated);
@@ -1372,7 +1365,7 @@ void LLVivoxVoiceClient::stateMachine()
 		    }
 			
 			// joinedAudioSession() will transition from here to stateSessionJoined.
-			if(!mVoiceEnabled)
+			if(!mVoiceEnabled && mIsInitialized)
 			{
 				// User bailed out during connect -- jump straight to teardown.
 				setState(stateSessionTerminated);
@@ -1419,7 +1412,7 @@ void LLVivoxVoiceClient::stateMachine()
 				notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED);
 
 			}
-			else if(!mVoiceEnabled)
+			else if(!mVoiceEnabled && mIsInitialized)
 			{
 				// User bailed out during connect -- jump straight to teardown.
 				setState(stateSessionTerminated);
@@ -1439,7 +1432,7 @@ void LLVivoxVoiceClient::stateMachine()
 		//MARK: stateRunning
 		case stateRunning:				// steady state
 			// Disabling voice or disconnect requested.
-			if(!mVoiceEnabled || mSessionTerminateRequested)
+			if(!mVoiceEnabled && mIsInitialized || mSessionTerminateRequested)
 			{
 				leaveAudioSession();
 			}
@@ -1487,8 +1480,7 @@ void LLVivoxVoiceClient::stateMachine()
 					sendPositionalUpdate();
 				}
 
-				// Now that audio module is fully initialized, check for actual mVoiceEnabled value
-				updateSettings();
+				mIsInitialized = true;
 			}
 		break;
 		
@@ -1522,7 +1514,7 @@ void LLVivoxVoiceClient::stateMachine()
 			// Always reset the terminate request flag when we get here.
 			mSessionTerminateRequested = false;
 
-			if(mVoiceEnabled && !mRelogRequested)
+			if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested)
 			{				
 				// Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state).
 				setState(stateNoChannel);
@@ -1550,7 +1542,7 @@ void LLVivoxVoiceClient::stateMachine()
 			mAccountHandle.clear();
 			cleanUp();
 
-			if(mVoiceEnabled && !mRelogRequested)
+			if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested)
 			{
 				// User was logged out, but wants to be logged in.  Send a new login request.
 				setState(stateNeedsLogin);
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 1142a1a49c..f2a3a7d3dd 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -741,6 +741,8 @@ private:
 	std::string mRenderDevice;
 	bool mCaptureDeviceDirty;
 	bool mRenderDeviceDirty;
+
+	bool mIsInitialized;
 	
 	
 	bool checkParcelChanged(bool update = false);
-- 
cgit v1.2.3


From d1f45654d91762af4e614de2156304d7acad6619 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 7 Nov 2012 18:45:02 +0200
Subject: CHUI-473, CHUI-482 FIXED (Clicking on nearby chat toast to open
 Conversation floater does not show Nearby Chat conversation selected in list;
 Nearby chat conversation is not selected in list by default when it is the
 only conversation ): implement. new logic in LLIMFloaterContainer for the
 syncronous select the conv. list's item and corresponding convers. floater;
 removed floater selecting from conv. items; fixed bug with item select

---
 indra/llui/llfolderviewitem.cpp        |  2 +-
 indra/newview/llconversationview.cpp   | 76 +++++++++++++---------------------
 indra/newview/llconversationview.h     |  6 ++-
 indra/newview/llimconversation.cpp     | 23 +++++++++-
 indra/newview/llimconversation.h       |  2 +
 indra/newview/llimfloater.cpp          | 13 ------
 indra/newview/llimfloater.h            |  3 +-
 indra/newview/llimfloatercontainer.cpp | 41 ++++++++++++++++++
 indra/newview/llimfloatercontainer.h   |  2 +
 indra/newview/llnearbychat.cpp         | 18 +++-----
 indra/newview/llnearbychat.h           |  1 -
 11 files changed, 107 insertions(+), 80 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 7c63cad1b7..21fb9bff90 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -410,8 +410,8 @@ void LLFolderViewItem::selectItem(void)
 {
 	if (mIsSelected == FALSE)
 	{
-		getViewModelItem()->selectItem();
 		mIsSelected = TRUE;
+		getViewModelItem()->selectItem();
 	}
 }
 
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 2d3a008bf4..34b5976e3e 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -203,6 +203,17 @@ void LLConversationViewSession::draw()
 	LLView::draw();
 }
 
+BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
+    LLUUID session_id = item? item->getUUID() : LLUUID();
+
+	(LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container"))->
+    		selectConversationPair(session_id, false);
+
+	return LLFolderViewFolder::handleMouseDown(x, y, mask);
+}
+
 // virtual
 S32 LLConversationViewSession::arrange(S32* width, S32* height)
 {
@@ -233,29 +244,6 @@ void LLConversationViewSession::toggleOpen()
 	}
 }
 
-void LLConversationViewSession::selectItem()
-{
-	
-	LLConversationItem* item = dynamic_cast<LLConversationItem*>(mViewModelItem);
-	LLFloater* session_floater = LLIMConversation::getConversation(item->getUUID());
-	LLMultiFloater* host_floater = session_floater->getHost();
-	
-	if (host_floater == mContainer)
-	{
-		// Always expand the message pane if the panel is hosted by the container
-		mContainer->collapseMessagesPane(false);
-		// Switch to the conversation floater that is being selected
-		mContainer->selectFloater(session_floater);
-	}
-	
-	// Set the focus on the selected floater
-	session_floater->setFocus(TRUE);
-    // Store the active session
-    LLIMFloaterContainer::getInstance()->setSelectedSession(item->getUUID());
-
-
-	LLFolderViewItem::selectItem();
-}
 
 void LLConversationViewSession::toggleMinimizedMode(bool is_minimized)
 {
@@ -441,31 +429,6 @@ void LLConversationViewParticipant::draw()
     LLView::draw();
 }
 
-void LLConversationViewParticipant::selectItem()
-{
-    LLConversationItem* vmi = this->getParentFolder() ? static_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
-    LLIMFloaterContainer* container = LLIMFloaterContainer::getInstance();
-    LLFloater* session_floater;
-
-    if(vmi)
-    {
-        session_floater = LLIMConversation::getConversation(vmi->getUUID());
-
-        //Only execute when switching floaters (conversations)
-        if(vmi->getUUID() != container->getSelectedSession())
-        {
-            container->selectFloater(session_floater);
-            // Store the active session
-            container->setSelectedSession(vmi->getUUID());
-        }
-
-        //Redirect focus to the conversation floater
-        session_floater->setFocus(TRUE);
-    }
-
-    LLFolderViewItem::selectItem();
-}
-
 void LLConversationViewParticipant::refresh()
 {
 	// Refresh the participant view from its model data
@@ -514,6 +477,23 @@ void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
     LLFolderViewItem::onMouseLeave(x, y, mask);
 }
 
+BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	LLConversationItem* item = NULL;
+	LLConversationViewSession* session_widget =
+			dynamic_cast<LLConversationViewSession *>(this->getParentFolder());
+	if (session_widget)
+	{
+	    item = dynamic_cast<LLConversationItem*>(session_widget->getViewModelItem());
+	}
+    LLUUID session_id = item? item->getUUID() : LLUUID();
+
+	(LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container"))->
+    		selectConversationPair(session_id, false);
+
+	return LLFolderViewItem::handleMouseDown(x, y, mask);
+}
+
 S32 LLConversationViewParticipant::getLabelXPos()
 {
     return mAvatarIcon->getRect().mRight + mIconPad;
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index aeca747260..ac91d2d26f 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -60,10 +60,10 @@ protected:
 	
 public:
 	virtual ~LLConversationViewSession();
-	virtual void selectItem();	
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
+	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
 
 	/*virtual*/ S32 arrange(S32* width, S32* height);
 
@@ -117,11 +117,13 @@ public:
 	};
 	
     virtual ~LLConversationViewParticipant( void ) { }
-    void selectItem();	
+
     bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
     virtual void refresh();
     void addToFolder(LLFolderViewFolder* folder);
 
+    /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+
     void onMouseEnter(S32 x, S32 y, MASK mask);
     void onMouseLeave(S32 x, S32 y, MASK mask);
 
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index 833feff3c4..827059513f 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -128,6 +128,22 @@ void LLIMConversation::setVisible(BOOL visible)
     setFocus(visible);
 }
 
+/*virtual*/
+void LLIMConversation::setFocus(BOOL focus)
+{
+	LLTransientDockableFloater::setFocus(focus);
+
+    //Redirect focus to input editor
+    if (focus)
+	{
+    	updateMessages();
+
+        if (mInputEditor)
+        {
+    	    mInputEditor->setFocus(TRUE);
+        }
+	}
+}
 
 
 void LLIMConversation::addToHost(const LLUUID& session_id)
@@ -247,7 +263,6 @@ void LLIMConversation::enableDisableCallBtn()
     		&& mSession->mCallBackEnabled);
 }
 
-
 void LLIMConversation::onFocusReceived()
 {
 	setBackgroundOpaque(true);
@@ -258,6 +273,12 @@ void LLIMConversation::onFocusReceived()
 	}
 
 	LLTransientDockableFloater::onFocusReceived();
+
+	LLIMFloaterContainer* container = LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
+	if (container)
+	{
+		container->selectConversationPair(mSessionID, true);
+	}
 }
 
 void LLIMConversation::onFocusLost()
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index bff4cb4a31..d1e2bfff55 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -79,7 +79,9 @@ public:
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
 	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void setFocus(BOOL focus);
 
+	virtual void updateMessages() {}
 
 protected:
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 3545b8ff18..2ff883da67 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -671,19 +671,6 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 	}
 }
 
-void LLIMFloater::setFocus(BOOL focusFlag)
-{
-    LLTransientDockableFloater::setFocus(focusFlag);
-
-    //Redirect focus to input editor
-    if (focusFlag)
-    {
-        updateMessages();
-        mInputEditor->setFocus(TRUE);
-    }
-    
-}
-
 void LLIMFloater::setVisible(BOOL visible)
 {
 	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 6c69ed3462..1fae3cff50 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -65,7 +65,6 @@ public:
 
 	// LLView overrides
 	/*virtual*/ BOOL postBuild();
-    /*virtual*/ void setFocus(BOOL focusFlag);
 	/*virtual*/ void setVisible(BOOL visible);
 	/*virtual*/ BOOL getVisible();
 	// Check typing timeout timer.
@@ -86,7 +85,7 @@ public:
 	void sessionInitReplyReceived(const LLUUID& im_session_id);
 
 	// get new messages from LLIMModel
-	void updateMessages();
+	/*virtual*/ void updateMessages();
 	void reloadMessages();
 	static void onSendMsg(LLUICtrl*, void*);
 	void sendMsgFromInputEditor();
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index af43b1ac38..c2ad94c423 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1091,6 +1091,47 @@ void LLIMFloaterContainer::selectConversation(const LLUUID& session_id)
 	}
 }
 
+// Synchronous select the conversation item and the conversation floater
+BOOL LLIMFloaterContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
+{
+    BOOL handled = TRUE;
+
+    /* widget processing */
+    if (select_widget)
+    {
+    	LLFolderViewItem* widget = mConversationsWidgets[session_id];
+    	if (widget && widget->getParentFolder())
+    	{
+    		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
+    	}
+    }
+
+    /* floater processing */
+
+    if (session_id != getSelectedSession())
+    {
+        // Store the active session
+        setSelectedSession(session_id);
+
+		LLIMConversation* session_floater = LLIMConversation::getConversation(session_id);
+
+		if (session_floater->getHost())
+		{
+			// Always expand the message pane if the panel is hosted by the container
+			collapseMessagesPane(false);
+			// Switch to the conversation floater that is being selected
+			selectFloater(session_floater);
+		}
+
+		// Set the focus on the selected floater
+		if (!session_floater->hasFocus())
+		{
+			session_floater->setFocus(TRUE);
+		}
+    }
+
+    return handled;
+}
 
 void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
 {
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
index 05ea94019b..25387fe83b 100644
--- a/indra/newview/llimfloatercontainer.h
+++ b/indra/newview/llimfloatercontainer.h
@@ -68,6 +68,8 @@ public:
     
     void showConversation(const LLUUID& session_id);
     void selectConversation(const LLUUID& session_id);
+    BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
+
 	/*virtual*/ void tabClose();
 
 	static LLFloater* getCurrentVoiceFloater();
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index d1c7c6bfd7..a30d8b685e 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -195,8 +195,13 @@ BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
 	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
 
 	if(mChatHistory)
+	{
 		mChatHistory->setFocus(TRUE);
-	return LLPanel::handleMouseDown(x, y, mask);
+	}
+
+	BOOL handled = LLPanel::handleMouseDown(x, y, mask);
+	setFocus(handled);
+	return handled;
 }
 
 void LLNearbyChat::reloadMessages()
@@ -270,17 +275,6 @@ void LLNearbyChat::removeScreenChat()
 	}
 }
 
-void LLNearbyChat::setFocus(BOOL focusFlag)
-{
-    LLTransientDockableFloater::setFocus(focusFlag);
-    
-    //Redirect focus to input editor
-    if (focusFlag)
-    {
-        mInputEditor->setFocus(TRUE);
-    }
-    
-}
 
 void LLNearbyChat::setVisible(BOOL visible)
 {
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index b155fd3c26..11346a313c 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -52,7 +52,6 @@ public:
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
-    /*virtual*/ void setFocus(BOOL focusFlag);
 	/*virtual*/ void setVisible(BOOL visible);
 
 	void loadHistory();
-- 
cgit v1.2.3


From bfb22638f865c2270fad95c35eff273b134772e3 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Wed, 7 Nov 2012 14:12:58 -0800
Subject: CHUI-514: Updating to Leo's latest icon batch.

---
 .../default/textures/icons/Conv_toolbar_add_person.png  | Bin 322 -> 373 bytes
 .../default/textures/icons/Conv_toolbar_arrow_ne.png    | Bin 301 -> 215 bytes
 .../default/textures/icons/Conv_toolbar_arrow_sw.png    | Bin 293 -> 211 bytes
 .../skins/default/textures/icons/Conv_toolbar_close.png | Bin 262 -> 275 bytes
 .../default/textures/icons/Conv_toolbar_collapse.png    | Bin 663 -> 345 bytes
 .../default/textures/icons/Conv_toolbar_expand.png      | Bin 662 -> 342 bytes
 .../default/textures/icons/Conv_toolbar_hang_up.png     | Bin 460 -> 459 bytes
 .../default/textures/icons/Conv_toolbar_open_call.png   | Bin 485 -> 366 bytes
 .../skins/default/textures/icons/Conv_toolbar_plus.png  | Bin 195 -> 144 bytes
 .../skins/default/textures/icons/Conv_toolbar_sort.png  | Bin 196 -> 230 bytes
 .../skins/default/textures/icons/nearby_chat_icon.png   | Bin 553 -> 399 bytes
 11 files changed, 0 insertions(+), 0 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png
index f024c733f3..0631f16f3b 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png
index a19e720d42..578482f5ed 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png
index 7f3f42639d..7676131790 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png
index 25a939d7f5..d009c8f446 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png
index 82baabde47..8d82960e28 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png
index 7d64abb042..f718d3fc60 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png
index f0da962c2d..315e2c581a 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png
index 0db001dcdb..732ab02a20 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png
index 0cf7edc2d4..25a32cb2ba 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png
index a0c15a6d3e..08debeb91f 100755
Binary files a/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png and b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png differ
diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png
index 48c2379133..5ac4258b9d 100644
Binary files a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png and b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png differ
-- 
cgit v1.2.3


From 626d07daa1219e6834bf371547cc8c4852840fb9 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 7 Nov 2012 15:36:16 -0800
Subject: CHUI-468 : WIP : Clean up LLAvatarList and all sorting code left over
 in LLParticipantList

---
 indra/newview/app_settings/settings.xml |  11 ---
 indra/newview/llimfloatercontainer.cpp  |   2 +-
 indra/newview/llparticipantlist.cpp     | 126 +-------------------------------
 indra/newview/llparticipantlist.h       |  37 +---------
 4 files changed, 4 insertions(+), 172 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0537487ca3..5694cb9f30 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12395,17 +12395,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>SpeakerParticipantDefaultOrder</key>
-    <map>
-      <key>Comment</key>
-      <string>Order for displaying speakers in voice controls.  0 = alphabetical. 1 = recent.</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>U32</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
     <key>SpeakerParticipantRemoveDelay</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index 4b992a2e0f..c0465c6956 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -1177,7 +1177,7 @@ LLConversationItem* LLIMFloaterContainer::addConversationListItem(const LLUUID&
 	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
 	if (speaker_manager)
 	{
-		item = new LLParticipantList(speaker_manager, getRootViewModel(), true, false);
+		item = new LLParticipantList(speaker_manager, getRootViewModel());
 	}
 	if (!item)
 	{
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index e6eef56628..0124f8a143 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -187,14 +187,9 @@ private:
 	uuid_set_t mAvalineCallers;
 };
 
-LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
-									 LLFolderViewModelInterface& root_view_model,
-									 bool use_context_menu/* = true*/,
-									 bool exclude_agent /*= true*/,
-									 bool can_toggle_icons /*= true*/) :
+LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItemSession(data_source->getSessionID(), root_view_model),
 	mSpeakerMgr(data_source),
-	mExcludeAgent(exclude_agent),
 	mValidateSpeakerCallback(NULL)
 {
 
@@ -215,33 +210,7 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 	mSpeakerMgr->addListener(mSpeakerUpdateListener, "update_speaker");
 
 	setSessionID(mSpeakerMgr->getSessionID());
-	/*
-	if (mAvatarList)
-	{
-		mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
-		LL_DEBUGS("SpeakingIndicator") << "Set session for speaking indicators: " << mSpeakerMgr->getSessionID() << LL_ENDL;
-		mAvatarList->setSessionID(mSpeakerMgr->getSessionID());
-		mAvatarListDoubleClickConnection = mAvatarList->setItemDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, _1));
-		mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2));
-		// Set onAvatarListDoubleClicked as default on_return action.
-		mAvatarListReturnConnection = mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
-
-		if (use_context_menu)
-		{
-			mAvatarList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
-		}
-		else
-		{
-			mAvatarList->setContextMenu(NULL);
-		}
 
-		if (use_context_menu && can_toggle_icons)
-		{
-			mAvatarList->setShowIcons("ParticipantListShowIcons");
-			mAvatarListToggleIconsConnection = gSavedSettings.getControl("ParticipantListShowIcons")->getSignal()->connect(boost::bind(&LLAvatarList::toggleIcons, mAvatarList));
-		}
-	}
-	 */
 	//Lets fill avatarList with existing speakers
 	LLSpeakerMgr::speaker_list_t speaker_list;
 	mSpeakerMgr->getSpeakerList(&speaker_list, true);
@@ -284,21 +253,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 
 LLParticipantList::~LLParticipantList()
 {
-	/*
-	if (mAvatarList)
-	{
-		mAvatarListDoubleClickConnection.disconnect();
-		mAvatarListRefreshConnection.disconnect();
-		mAvatarListReturnConnection.disconnect();
-		mAvatarListToggleIconsConnection.disconnect();
-	}
-
-	if (mAvatarList)
-	{
-		mAvatarList->setContextMenu(NULL);
-		mAvatarList->setComparator(NULL);
-	}
-	 */
 	delete mAvalineUpdater;
 }
 
@@ -429,24 +383,7 @@ void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
 
 	mSpeakerMgr->removeAvalineSpeaker(participant_id);
 }
-/*
-void LLParticipantList::setSortOrder(EParticipantSortOrder order)
-{
-	const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
-
-	if ( speaker_sort_order != order )
-	{
-		gSavedSettings.setU32("SpeakerParticipantDefaultOrder", (U32)order);
-		sort();
-	}
-}
 
-const LLParticipantList::EParticipantSortOrder LLParticipantList::getSortOrder() const
-{
-	const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
-	return EParticipantSortOrder(speaker_sort_order);
-}
-*/
 void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
 {
 	mValidateSpeakerCallback = cb;
@@ -455,15 +392,6 @@ void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t c
 void LLParticipantList::update()
 {
 	mSpeakerMgr->update(true);
-
-	/*
-	// Need to resort the participant list if it's in sort by recent speaker order.
-	if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder())
-	{
-		// Resort avatar list
-		sort();
-	}
-	 */
 }
 
 bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
@@ -528,8 +456,6 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> e
 				}
 			}
 			// *TODO : do we have to fire an event so that LLIMConversation::refreshConversation() gets called
-			// apply changes immediately
-			//onAvatarListRefreshed(mAvatarList, LLSD());
 		}
 	}
 	return true;
@@ -548,44 +474,9 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
 	return true;
 }
 
-/*
-void LLParticipantList::sort()
-{
-	// *TODO : Merov : Need to plan for sort() for LLConversationModel
-	if ( !mAvatarList )
-		return;
-
-	switch ( getSortOrder() ) 
-	{
-		case E_SORT_BY_NAME :
-			// if mExcludeAgent == true , then no need to keep agent on top of the list
-			if(mExcludeAgent)
-			{
-				mAvatarList->sortByName();
-			}
-			else
-			{
-				mAvatarList->setComparator(&AGENT_ON_TOP_NAME_COMPARATOR);
-				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;
-	}
-}
-*/
-
 void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 {
 	// Do not add if already in there or excluded for some reason
-	if (mExcludeAgent && gAgent.getID() == avatar_id) return;
 	if (findParticipant(avatar_id)) return;
 
 	bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id);
@@ -599,29 +490,16 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 		bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
 		participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.mDisplayName , avatar_id, mRootViewModel);
 		participant->fetchAvatarName();
-		/*
-		if (mAvatarList)
-		{
-			mAvatarList->getIDs().push_back(avatar_id);
-			mAvatarList->setDirty();
-		}
-		 */
 	}
 	else
 	{
 		std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
 		// Create a participant view model instance
 		participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
-		/*
-		if (mAvatarList)
-		{
-			mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
-		}
-		 */
 		mAvalineUpdater->watchAvalineCaller(avatar_id);
 	}
 
-	// *TODO : Merov : need to update the online/offline status of the participant.
+	// *TODO : Need to update the online/offline status of the participant
 	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
 
 	// Add the participant model to the session's children list
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index f4469b03f4..9332634c31 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -43,19 +43,9 @@ public:
 
 	typedef boost::function<bool (const LLUUID& speaker_id)> validate_speaker_callback_t;
 
-	LLParticipantList(LLSpeakerMgr* data_source, 
-					  LLFolderViewModelInterface& root_view_model,
-					  bool use_context_menu = true, 
-					  bool exclude_agent = true, 
-					  bool can_toggle_icons = true);
+	LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model);
 	~LLParticipantList();
 
-	enum EParticipantSortOrder
-	{
-		E_SORT_BY_NAME = 0,
-		E_SORT_BY_RECENT_SPEAKERS = 1,
-	};
-
 	/**
 	 * Adds specified avatar ID to the existing list if it is not Agent's ID
 	 *
@@ -63,12 +53,6 @@ public:
 	 */
 	void addAvatarIDExceptAgent(const LLUUID& avatar_id);
 
-	/**
-	 * Set and sort Avatarlist by given order
-	 */
-	//void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME);
-	//const EParticipantSortOrder getSortOrder() const;
-
 	/**
 	 * Refreshes the participant list.
 	 */
@@ -94,11 +78,6 @@ protected:
 	bool onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	bool onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 
-	/**
-	 * Sorts the Avatarlist by stored order
-	 */
-	//void sort();
-
 	/**
 	 * List of listeners implementing LLOldEvents::LLSimpleListener.
 	 * There is no way to handle all the events in one listener as LLSpeakerMgr registers
@@ -181,20 +160,6 @@ private:
 	LLPointer<SpeakerModeratorUpdateListener>	mSpeakerModeratorListener;
 	LLPointer<SpeakerMuteListener>				mSpeakerMuteListener;
 
-	/**
-	 * This field manages an adding  a new avatar_id in the mAvatarList
-	 * If true, then agent_id wont  be added into mAvatarList
-	 * Also by default this field is controlling a sort procedure, @c sort() 
-	 */
-	bool mExcludeAgent;
-
-	// boost::connections
-	boost::signals2::connection mAvatarListDoubleClickConnection;
-	boost::signals2::connection mAvatarListRefreshConnection;
-	boost::signals2::connection mAvatarListReturnConnection;
-	boost::signals2::connection mAvatarListToggleIconsConnection;
-
-//	LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers;
 	validate_speaker_callback_t mValidateSpeakerCallback;
 	LLAvalineUpdater* mAvalineUpdater;
 };
-- 
cgit v1.2.3


From 7701d421e53da63731d969f66d743792fe72976f Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Wed, 7 Nov 2012 16:48:45 -0800
Subject: CHUI-484: Ensuring that the busy/do-no-disturb message is sent when
 the user is in the busy/do-not-disturb mode.

---
 indra/newview/llviewermessage.cpp | 40 +++++++++++++--------------------------
 indra/newview/llviewermessage.h   |  1 -
 2 files changed, 13 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 775280ca34..c5d25ebd1b 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -179,6 +179,8 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
 	FALSE	// TeleportYourAgent
 };
 
+static void busy_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null);
+
 bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -2358,12 +2360,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
 		// object IMs contain sender object id in session_id (STORM-1209)
 		|| dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id);
-	BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
 	BOOL is_owned_by_me = FALSE;
 	BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
 	BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
 	
-	chat.mMuted = is_muted && !is_linden;
+	chat.mMuted = is_muted;
 	chat.mFromID = from_id;
 	chat.mFromName = name;
 	chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
@@ -2401,7 +2402,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			// do nothing -- don't distract newbies in
 			// Prelude with global IMs
 		}
-		else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM)
+		else if (offline == IM_ONLINE && is_busy && name != SYSTEM_FROM)
 		{
 			// return a standard "busy" message, but only do it to online IM 
 			// (i.e. not other auto responses and not store-and-forward IM)
@@ -2409,21 +2410,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{
 				// if there is not a panel for this conversation (i.e. it is a new IM conversation
 				// initiated by the other party) then...
-				std::string my_name;
-				LLAgentUI::buildFullname(my_name);
-				std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
-				pack_instant_message(
-					gMessageSystem,
-					gAgent.getID(),
-					FALSE,
-					gAgent.getSessionID(),
-					from_id,
-					my_name,
-					response,
-					IM_ONLINE,
-					IM_BUSY_AUTO_RESPONSE,
-					session_id);
-				gAgent.sendReliableMessage();
+				busy_message(msg, from_id, session_id);
 			}
 
 			// now store incoming IM in chat history
@@ -2484,7 +2471,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 				mute_im = true;
 			}
-			if (!mute_im || is_linden) 
+			if (!mute_im) 
 			{
 				gIMMgr->addMessage(
 					session_id,
@@ -2658,11 +2645,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		break;
 	case IM_GROUP_INVITATION:
 		{
-			//if (!is_linden && (is_busy || is_muted))
-			if ((is_busy || is_muted))
+			if (is_busy || is_muted)
 			{
-				LLMessageSystem *msg = gMessageSystem;
-				busy_message(msg,from_id);
+				busy_message(msg, from_id);
 			}
 			else
 			{
@@ -2974,7 +2959,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			}
 			else if (is_busy) 
 			{
-				busy_message(msg,from_id);
+				busy_message(msg, from_id);
 			}
 			else
 			{
@@ -3261,7 +3246,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	}
 }
 
-void busy_message (LLMessageSystem* msg, LLUUID from_id) 
+static void busy_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
 {
 	if (gAgent.getBusy())
 	{
@@ -3269,7 +3254,7 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)
 		LLAgentUI::buildFullname(my_name);
 		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
 		pack_instant_message(
-			gMessageSystem,
+			msg,
 			gAgent.getID(),
 			FALSE,
 			gAgent.getSessionID(),
@@ -3277,7 +3262,8 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)
 			my_name,
 			response,
 			IM_ONLINE,
-			IM_BUSY_AUTO_RESPONSE);
+			IM_BUSY_AUTO_RESPONSE,
+			session_id);
 		gAgent.sendReliableMessage();
 	}
 }
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 594c22ed9c..b298f0060b 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -67,7 +67,6 @@ enum InventoryOfferResponse
 BOOL can_afford_transaction(S32 cost);
 void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE,
 				S32 trx_type = TRANS_GIFT, const std::string& desc = LLStringUtil::null);
-void busy_message (LLMessageSystem* msg, LLUUID from_id);
 
 void process_logout_reply(LLMessageSystem* msg, void**);
 void process_layer_data(LLMessageSystem *mesgsys, void **user_data);
-- 
cgit v1.2.3


From 87c94625d39a72ce8b19b2c295c3824fb45717a3 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 7 Nov 2012 16:49:03 -0800
Subject: CHUI-468 : Fixed. Final clean up of LLParticipantList, including
 dependencies.

---
 indra/newview/llparticipantlist.cpp | 112 +-----------------------------------
 indra/newview/llparticipantlist.h   |   7 +--
 2 files changed, 2 insertions(+), 117 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 0124f8a143..9a4d1166db 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file llparticipantlist.cpp
- * @brief LLParticipantList widgets of a conversation list
+ * @brief LLParticipantList : model of a conversation session with added speaker events handling
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -26,22 +26,11 @@
 
 #include "llviewerprecompiledheaders.h"
 
-// common includes
-#include "lltrans.h"
-#include "llavataractions.h"
 #include "llavatarnamecache.h"
-#include "llavatarname.h"
-#include "llagent.h"
-
 #include "llimview.h"
 #include "llimfloatercontainer.h"
-#include "llpanelpeoplemenus.h"
-#include "llnotificationsutil.h"
 #include "llparticipantlist.h"
 #include "llspeakers.h"
-#include "llviewercontrol.h"
-#include "llviewermenu.h"
-#include "llvoiceclient.h"
 
 //LLParticipantList retrieves add, clear and remove events and updates view accordingly 
 #if LL_MSVC
@@ -256,105 +245,6 @@ LLParticipantList::~LLParticipantList()
 	delete mAvalineUpdater;
 }
 
-/*
-void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl)
-{
-	LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl);
-	if(!item)
-	{
-		return;
-	}
-
-	LLUUID clicked_id = item->getAvatarId();
-
-	if (clicked_id.isNull() || clicked_id == gAgent.getID())
-		return;
-	
-	LLAvatarActions::startIM(clicked_id);
-}
-*/
-/*
-void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
-{
-	LLAvatarList* list = dynamic_cast<LLAvatarList*>(ctrl);
-	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 )
-		{
-			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);
-			}
-		}
-		setParticipantIsModerator(*moderator_list_it,false);
-	}
-
-	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)
-	{
-		LLAvatarListItem* item = (list ? dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it)) : NULL);
-		if ( item )
-		{
-			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);
-			}
-		}
-		setParticipantIsModerator(*moderator_list_it,true);
-	}
-
-	// 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;
-
-		if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
-		{
-			setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
-		}
-	}
-}
-*/
 /*
   Seems this method is not necessary after onAvalineCallerRemoved was implemented;
 
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 9332634c31..3a3ae76604 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -1,6 +1,6 @@
 /** 
  * @file llparticipantlist.h
- * @brief LLParticipantList widgets of a conversation list
+ * @brief LLParticipantList : model of a conversation session with added speaker events handling
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -28,8 +28,6 @@
 #define LL_PARTICIPANTLIST_H
 
 #include "llviewerprecompiledheaders.h"
-#include "llevent.h"
-#include "lllistcontextmenu.h"
 #include "llconversationmodel.h"
 
 class LLSpeakerMgr;
@@ -135,9 +133,6 @@ protected:
 	};
 
 private:
-//	void onAvatarListDoubleClicked(LLUICtrl* ctrl);
-//	void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param);
-
 	void onAvalineCallerFound(const LLUUID& participant_id);
 	void onAvalineCallerRemoved(const LLUUID& participant_id);
 
-- 
cgit v1.2.3


From fa85e16d63b09326b9facb4850d50cd163f87bc7 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Wed, 7 Nov 2012 17:47:35 -0800
Subject: Removing unused code.

---
 indra/llmessage/lldbstrings.h        | 12 ---------
 indra/llmessage/llinstantmessage.cpp | 17 +-----------
 indra/llmessage/llinstantmessage.h   | 51 ------------------------------------
 3 files changed, 1 insertion(+), 79 deletions(-)

(limited to 'indra')

diff --git a/indra/llmessage/lldbstrings.h b/indra/llmessage/lldbstrings.h
index 9bf1b3eda4..e23d17d5b6 100644
--- a/indra/llmessage/lldbstrings.h
+++ b/indra/llmessage/lldbstrings.h
@@ -156,18 +156,6 @@ const S32 DB_USER_SKILLS_BUF_SIZE		= 255;
 const S32 DB_NV_NAME_STR_LEN			= 128;
 const S32 DB_NV_NAME_BUF_SIZE			= 129;
 
-// votes.vote_text						varchar(254)
-const S32 DB_VOTE_TEXT_STR_LEN			= 254;
-const S32 DB_VOTE_TEXT_BUF_SIZE			= 255;
-
-// vpte type text						varchar(9)
-const S32 DB_VOTE_TYPE_STR_LEN			= 9;
-const S32 DB_VOTE_TYPE_BUF_SIZE			= 10;
-
-// vote result text
-const S32 DB_VOTE_RESULT_BUF_LEN		= 8;
-const S32 DB_VOTE_RESULT_BUF_SIZE		= 9;
-
 // user_start_location.location_name	varchar(254)
 const S32 DB_START_LOCATION_STR_LEN		= 254;
 const S32 DB_START_LOCATION_BUF_SIZE	= 255;
diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp
index d68e0c423e..b0275c161b 100644
--- a/indra/llmessage/llinstantmessage.cpp
+++ b/indra/llmessage/llinstantmessage.cpp
@@ -43,14 +43,6 @@
 const U8 IM_ONLINE = 0;
 const U8 IM_OFFLINE = 1;
 
-const S32 VOTE_YES = 1;
-const S32 VOTE_NO = 0;
-const S32 VOTE_ABSTAIN = -1;
-
-const S32 VOTE_MAJORITY = 0;
-const S32 VOTE_SUPER_MAJORITY = 1;
-const S32 VOTE_UNANIMOUS = 2;
-
 const char EMPTY_BINARY_BUCKET[] = "";
 const S32 EMPTY_BINARY_BUCKET_SIZE = 1;
 const U32 NO_TIMESTAMP = 0;
@@ -69,7 +61,6 @@ LLIMInfo::LLIMInfo() :
 	mViewerThinksToIsOnline(false),
 	mIMType(IM_NOTHING_SPECIAL),
 	mTimeStamp(0),
-	mSource(IM_FROM_SIM),
 	mTTL(IM_TTL)
 {
 }
@@ -88,7 +79,6 @@ LLIMInfo::LLIMInfo(
 	LLSD data,
 	U8 offline,
 	U32 timestamp,
-	EIMSource source,
 	S32 ttl) :
 	mFromID(from_id),
 	mFromGroup(from_group),
@@ -104,14 +94,12 @@ LLIMInfo::LLIMInfo(
 	mName(name),
 	mMessage(message),
 	mData(data),
-	mSource(source),
 	mTTL(ttl)
 {
 }
 
-LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
+LLIMInfo::LLIMInfo(LLMessageSystem* msg, S32 ttl) :
 	mViewerThinksToIsOnline(false),
-	mSource(source),
 	mTTL(ttl)
 {
 	unpackMessageBlock(msg);
@@ -326,7 +314,6 @@ LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
 	param_message["region_id"] = im_info->mRegionID;
 	param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
 	param_message["data"] = im_info->mData;
-	param_message["source"]= im_info->mSource;
 	param_message["ttl"] = im_info->mTTL;
 
 	LLSD param_agent;
@@ -359,7 +346,6 @@ LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
 		param_message["data"],
 		(U8) param_message["offline"].asInteger(),
 		(U32) param_message["timestamp"].asInteger(),
-		(EIMSource)param_message["source"].asInteger(),
 		param_message["ttl"].asInteger());
 
 	return im_info;
@@ -381,7 +367,6 @@ LLPointer<LLIMInfo> LLIMInfo::clone()
 			mData,
 			mOffline,
 			mTimeStamp,
-			mSource,
 			mTTL);
 }
 
diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h
index e0dae376b4..12e4e79475 100644
--- a/indra/llmessage/llinstantmessage.h
+++ b/indra/llmessage/llinstantmessage.h
@@ -164,57 +164,9 @@ enum EInstantMessage
 };
 
 
-// Hooks for quickly hacking in experimental admin debug messages 
-// without needing to recompile the viewer
-// *NOTE: This functionality has been moved to be a string based
-// operation so that we don't even have to do a full recompile. This
-// enumeration will be phased out soon.
-enum EGodlikeRequest
-{
-	GOD_WANTS_NOTHING,
-
-	// for requesting physics information about an object
-	GOD_WANTS_PHYSICS_INFO,
-	
-	// two unused requests that can be appropriated for debug 
-	// purposes (no viewer recompile necessary)
-	GOD_WANTS_FOO,
-	GOD_WANTS_BAR,
-
-	// to dump simulator terrain data to terrain.raw file
-	GOD_WANTS_TERRAIN_SAVE,
-	// to load simulator terrain data from terrain.raw file
-	GOD_WANTS_TERRAIN_LOAD,
-
-	GOD_WANTS_TOGGLE_AVATAR_GEOMETRY,	// HACK for testing new avatar geom
-
-	// real-time telehub operations
-	GOD_WANTS_TELEHUB_INFO,
-	GOD_WANTS_CONNECT_TELEHUB,
-	GOD_WANTS_DELETE_TELEHUB,
-	GOD_WANTS_ADD_TELEHUB_SPAWNPOINT,
-	GOD_WANTS_REMOVE_TELEHUB_SPAWNPOINT,
-
-};
-
-enum EIMSource
-{
-	IM_FROM_VIEWER,
-	IM_FROM_DATASERVER,
-	IM_FROM_SIM
-};
-
 extern const U8 IM_ONLINE;
 extern const U8 IM_OFFLINE;
 
-extern const S32 VOTE_YES;
-extern const S32 VOTE_NO;
-extern const S32 VOTE_ABSTAIN;
-
-extern const S32 VOTE_MAJORITY;
-extern const S32 VOTE_SUPER_MAJORITY;
-extern const S32 VOTE_UNANIMOUS;
-
 extern const char EMPTY_BINARY_BUCKET[];
 extern const S32 EMPTY_BINARY_BUCKET_SIZE;
 
@@ -234,7 +186,6 @@ protected:
 
 public:
 	LLIMInfo(LLMessageSystem* msg, 
-			EIMSource source = IM_FROM_SIM, 
 			S32 ttl = IM_TTL);
 
 	LLIMInfo(
@@ -251,7 +202,6 @@ public:
 		LLSD data,
 		U8 offline,
 		U32 timestamp,
-		EIMSource source,
 		S32 ttl = IM_TTL);
 
 	void packInstantMessage(LLMessageSystem* msg) const;
@@ -274,7 +224,6 @@ public:
 	std::string mMessage;
 	LLSD mData;
 
-	EIMSource mSource;
 	S32 mTTL;
 };
 
-- 
cgit v1.2.3


From 93f9c6991819f53ea03b36dff1af77bbd74ff43b Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 8 Nov 2012 17:00:42 +0200
Subject: CHUI-387 FIXED (Conversation toasts not shown for open conversations
 when conversation floater is in a minimized state or undocked conversation is
 minimized): added checking of the minimized state

---
 indra/newview/llimview.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d5f1e81933..11337c358f 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -121,7 +121,14 @@ void toast_callback(const LLSD& msg){
 
     // Skip toasting if we have open window of IM with this session id
     LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]);
-    if (open_im_floater && open_im_floater->isInVisibleChain() && open_im_floater->hasFocus())
+    if (
+           open_im_floater
+           && open_im_floater->isInVisibleChain()
+           && open_im_floater->hasFocus()
+           && !open_im_floater->isMinimized()
+           && !(open_im_floater->getHost()
+                   && open_im_floater->getHost()->isMinimized())
+       )
     {
         return;
     }
-- 
cgit v1.2.3


From c4eaaa3d6a08330863119d550d365315ba7526bb Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Thu, 8 Nov 2012 12:35:15 -0800
Subject: CHUI-484: Updating the code to rather than refer to it as Busy Mode,
 it now refers to it as Do Not Disturb mode.

---
 indra/llcharacter/llanimationstates.cpp            |  4 +-
 indra/llcharacter/llanimationstates.h              |  2 +-
 indra/llmessage/llinstantmessage.h                 |  4 +-
 .../newview/app_settings/settings_per_account.xml  |  8 +--
 indra/newview/llagent.cpp                          | 36 ++++------
 indra/newview/llagent.h                            |  9 ++-
 indra/newview/llappearancemgr.cpp                  |  6 --
 indra/newview/llavataractions.cpp                  |  8 +--
 indra/newview/llfloaterpreference.cpp              | 46 +++++-------
 indra/newview/llfloaterpreference.h                |  8 +--
 indra/newview/llimview.cpp                         |  8 +--
 indra/newview/llinventorybridge.cpp                | 21 ------
 indra/newview/llnearbychathandler.cpp              |  2 +-
 indra/newview/llviewermenu.cpp                     | 24 +++----
 indra/newview/llviewermenu.h                       |  2 +-
 indra/newview/llviewermessage.cpp                  | 83 ++++++++++------------
 indra/newview/llviewerwindow.cpp                   |  4 +-
 indra/newview/llvoavatar.cpp                       | 16 ++---
 indra/newview/llvoavatar.h                         |  2 +-
 indra/newview/llvoicevivox.cpp                     |  6 +-
 indra/newview/skins/default/xui/en/menu_viewer.xml |  4 +-
 .../newview/skins/default/xui/en/notifications.xml | 14 ++--
 .../default/xui/en/panel_preferences_general.xml   |  4 +-
 indra/newview/skins/default/xui/en/strings.xml     |  8 +--
 24 files changed, 137 insertions(+), 192 deletions(-)

(limited to 'indra')

diff --git a/indra/llcharacter/llanimationstates.cpp b/indra/llcharacter/llanimationstates.cpp
index 155226cf17..c16cae1bbc 100644
--- a/indra/llcharacter/llanimationstates.cpp
+++ b/indra/llcharacter/llanimationstates.cpp
@@ -46,7 +46,7 @@ LLUUID const ANIM_AGENT_BLOW_KISS             ("db84829b-462c-ee83-1e27-9bbee66b
 LLUUID const ANIM_AGENT_BORED                 ("b906c4ba-703b-1940-32a3-0c7f7d791510");
 LLUUID const ANIM_AGENT_BOW                   ("82e99230-c906-1403-4d9c-3889dd98daba");
 LLUUID const ANIM_AGENT_BRUSH                 ("349a3801-54f9-bf2c-3bd0-1ac89772af01");
-LLUUID const ANIM_AGENT_BUSY                  ("efcf670c-2d18-8128-973a-034ebc806b67");
+LLUUID const ANIM_AGENT_DO_NOT_DISTURB        ("efcf670c-2d18-8128-973a-034ebc806b67");
 LLUUID const ANIM_AGENT_CLAP                  ("9b0c1c4e-8ac7-7969-1494-28c874c4f668");
 LLUUID const ANIM_AGENT_COURTBOW              ("9ba1c942-08be-e43a-fb29-16ad440efc50");
 LLUUID const ANIM_AGENT_CROUCH                ("201f3fdf-cb1f-dbec-201f-7333e328ae7c");
@@ -211,7 +211,7 @@ LLAnimationLibrary::LLAnimationLibrary() :
 	mAnimMap[ANIM_AGENT_BORED]=				mAnimStringTable.addString("express_bored");
 	mAnimMap[ANIM_AGENT_BOW]=				mAnimStringTable.addString("bow");
 	mAnimMap[ANIM_AGENT_BRUSH]=				mAnimStringTable.addString("brush");
-	mAnimMap[ANIM_AGENT_BUSY]=				mAnimStringTable.addString("busy");
+	mAnimMap[ANIM_AGENT_DO_NOT_DISTURB]=	mAnimStringTable.addString("busy");
 	mAnimMap[ANIM_AGENT_CLAP]=				mAnimStringTable.addString("clap");
 	mAnimMap[ANIM_AGENT_COURTBOW]=			mAnimStringTable.addString("courtbow");
 	mAnimMap[ANIM_AGENT_CROUCH]=			mAnimStringTable.addString("crouch");
diff --git a/indra/llcharacter/llanimationstates.h b/indra/llcharacter/llanimationstates.h
index aa6579ac8e..84185c3f92 100644
--- a/indra/llcharacter/llanimationstates.h
+++ b/indra/llcharacter/llanimationstates.h
@@ -56,7 +56,7 @@ extern const LLUUID ANIM_AGENT_BLOW_KISS;
 extern const LLUUID ANIM_AGENT_BORED;
 extern const LLUUID ANIM_AGENT_BOW;
 extern const LLUUID ANIM_AGENT_BRUSH;
-extern const LLUUID ANIM_AGENT_BUSY;
+extern const LLUUID ANIM_AGENT_DO_NOT_DISTURB;
 extern const LLUUID ANIM_AGENT_CLAP;
 extern const LLUUID ANIM_AGENT_COURTBOW;
 extern const LLUUID ANIM_AGENT_CROUCH;
diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h
index 12e4e79475..db4a38ea9e 100644
--- a/indra/llmessage/llinstantmessage.h
+++ b/indra/llmessage/llinstantmessage.h
@@ -115,8 +115,8 @@ enum EInstantMessage
 	// viewer, since you can't IM an object yet.
 	IM_FROM_TASK = 19,
 
-	// sent an IM to a busy user, this is the auto response
-	IM_BUSY_AUTO_RESPONSE = 20,
+	// sent an IM to a do not disturb user, this is the auto response
+	IM_DO_NOT_DISTURB_AUTO_RESPONSE = 20,
 
 	// Shows the message in the console and chat history
 	IM_CONSOLE_AND_CHAT_HISTORY = 21,
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 1f637ef3ff..8126e20b1b 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -1,9 +1,9 @@
 <llsd>
     <map>
-    <key>BusyResponseChanged</key>
+    <key>DoNotDisturbResponseChanged</key>
         <map>
         <key>Comment</key>
-            <string>Does user's busy mode message differ from default?</string>
+            <string>Does user's do not disturb mode message differ from default?</string>
         <key>Persist</key>
             <integer>1</integer>
         <key>Type</key>
@@ -11,10 +11,10 @@
         <key>Value</key>
             <integer>0</integer>
         </map>
-    <key>BusyModeResponse</key>
+    <key>DoNotDisturbModeResponse</key>
         <map>
         <key>Comment</key>
-            <string>Auto response to instant messages while in busy mode.</string>
+            <string>Auto response to instant messages while in do not disturb mode.</string>
         <key>Persist</key>
             <integer>1</integer>
         <key>Type</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index bb0dbc7ff0..cefd5c72e8 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -376,7 +376,7 @@ LLAgent::LLAgent() :
 	mShowAvatar(TRUE),
 	mFrameAgent(),
 
-	mIsBusy(FALSE),
+	mIsDoNotDisturb(false),
 
 	mControlFlags(0x00000000),
 	mbFlagsDirty(FALSE),
@@ -1397,39 +1397,27 @@ BOOL LLAgent::getAFK() const
 }
 
 //-----------------------------------------------------------------------------
-// setBusy()
+// setDoNotDisturb()
 //-----------------------------------------------------------------------------
-void LLAgent::setBusy()
+void LLAgent::setDoNotDisturb(bool pIsDotNotDisturb)
 {
-	sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_START);
-	mIsBusy = TRUE;
-	if (gBusyMenu)
-	{
-		gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy"));
-	}
-	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(true);
-}
+	mIsDoNotDisturb = pIsDotNotDisturb;
+	EAnimRequest animRequest = (pIsDotNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
 
-//-----------------------------------------------------------------------------
-// clearBusy()
-//-----------------------------------------------------------------------------
-void LLAgent::clearBusy()
-{
-	mIsBusy = FALSE;
-	sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_STOP);
-	if (gBusyMenu)
+	sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, animRequest);
+	if (gDoNotDisturbMenu)
 	{
-		gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy"));
+		gDoNotDisturbMenu->setLabel(LLTrans::getString((pIsDotNotDisturb ? "AvatarSetAvailable" : "AvatarSetDoNotDisturb")));
 	}
-	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(false);
+	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDotNotDisturb);
 }
 
 //-----------------------------------------------------------------------------
-// getBusy()
+// isDoNotDisturb()
 //-----------------------------------------------------------------------------
-BOOL LLAgent::getBusy() const
+bool LLAgent::isDoNotDisturb() const
 {
-	return mIsBusy;
+	return mIsDoNotDisturb;
 }
 
 
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 99904e118c..daa15b0c1a 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -378,14 +378,13 @@ public:
 	void			sitDown();
 
 	//--------------------------------------------------------------------
-	// Busy
+	// Do Not Disturb
 	//--------------------------------------------------------------------
 public:
-	void			setBusy();
-	void			clearBusy();
-	BOOL			getBusy() const;
+	void			setDoNotDisturb(bool pIsDoNotDisturb);
+	bool			isDoNotDisturb() const;
 private:
-	BOOL			mIsBusy;
+	bool			mIsDoNotDisturb;
 
 	//--------------------------------------------------------------------
 	// Grab
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 510abf198a..658da0205f 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1602,8 +1602,6 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
 	{
 		gAgentWearables.setWearableOutfit(items, wearables, !append);
 	}
-
-//	dec_busy_count();
 }
 
 static void remove_non_link_items(LLInventoryModel::item_array_t &items)
@@ -2004,7 +2002,6 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
 void LLAppearanceMgr::wearOutfitByName(const std::string& name)
 {
 	LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL;
-	//inc_busy_count();
 
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
@@ -2044,8 +2041,6 @@ void LLAppearanceMgr::wearOutfitByName(const std::string& name)
 		llwarns << "Couldn't find outfit " <<name<< " in wearOutfitByName()"
 				<< llendl;
 	}
-
-	//dec_busy_count();
 }
 
 bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventoryItem *b)
@@ -2967,7 +2962,6 @@ public:
 		{
 			llwarns << "Nothing fetched in category " << mComplete.front()
 					<< llendl;
-			//dec_busy_count();
 			gInventory.removeObserver(this);
 
 			// lets notify observers that loading is finished.
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 13262efb3b..130428f3c0 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -386,12 +386,12 @@ void LLAvatarActions::showOnMap(const LLUUID& id)
 // static
 void LLAvatarActions::pay(const LLUUID& id)
 {
-	LLNotification::Params params("BusyModePay");
+	LLNotification::Params params("DoNotDisturbModePay");
 	params.functor.function(boost::bind(&LLAvatarActions::handlePay, _1, _2, id));
 
-	if (gAgent.getBusy())
+	if (gAgent.isDoNotDisturb())
 	{
-		// warn users of being in busy mode during a transaction
+		// warn users of being in do not disturb mode during a transaction
 		LLNotifications::instance().add(params);
 	}
 	else
@@ -982,7 +982,7 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response,
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	if (option == 0)
 	{
-		gAgent.clearBusy();
+		gAgent.setDoNotDisturb(false);
 	}
 
 	LLFloaterPayUtil::payDirectly(&give_money, avatar_id, /*is_group=*/false);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index c78a803bf3..b60af1a635 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -443,23 +443,23 @@ BOOL LLFloaterPreference::postBuild()
 
 	getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
 
-	// if floater is opened before login set default localized busy message
+	// if floater is opened before login set default localized do not disturb message
 	if (LLStartUp::getStartupState() < STATE_STARTED)
 	{
-		gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault"));
+		gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
 	}
 
 	return TRUE;
 }
 
-void LLFloaterPreference::onBusyResponseChanged()
+void LLFloaterPreference::onDoNotDisturbResponseChanged()
 {
-	// set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
-	bool busy_flag =
-			LLTrans::getString("BusyModeResponseDefault")
-					!= getChild<LLUICtrl>("busy_response")->getValue().asString();
+	// set "DoNotDisturbResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
+	bool response_changed_flag =
+			LLTrans::getString("DoNotDisturbModeResponseDefault")
+					!= getChild<LLUICtrl>("do_not_disturb_response")->getValue().asString();
 
-	gSavedPerAccountSettings.setBOOL("BusyResponseChanged", busy_flag );
+	gSavedPerAccountSettings.setBOOL("DoNotDisturbResponseChanged", response_changed_flag );
 }
 
 LLFloaterPreference::~LLFloaterPreference()
@@ -542,12 +542,8 @@ void LLFloaterPreference::apply()
 		LLViewerMedia::setProxyConfig(proxy_enable, proxy_address, proxy_port);
 	}
 	
-//	LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString());
-//	LLWStringUtil::replaceTabsWithSpaces(busy_response, 4);
-	
 	if (mGotPersonalInfo)
 	{ 
-//		gSavedSettings.setString("BusyModeResponse2", std::string(wstring_to_utf8str(busy_response)));
 		bool new_im_via_email = getChild<LLUICtrl>("send_im_to_email")->getValue().asBoolean();
 		bool new_hide_online = getChild<LLUICtrl>("online_visibility")->getValue().asBoolean();		
 	
@@ -633,21 +629,21 @@ void LLFloaterPreference::cancel()
 void LLFloaterPreference::onOpen(const LLSD& key)
 {
 	
-	// this variable and if that follows it are used to properly handle busy mode response message
+	// this variable and if that follows it are used to properly handle do not disturb mode response message
 	static bool initialized = FALSE;
-	// if user is logged in and we haven't initialized busy_response yet, do it
+	// if user is logged in and we haven't initialized do not disturb mode response yet, do it
 	if (!initialized && LLStartUp::getStartupState() == STATE_STARTED)
 	{
-		// Special approach is used for busy response localization, because "BusyModeResponse" is
+		// Special approach is used for do not disturb response localization, because "DoNotDisturbModeResponse" is
 		// in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized.
-		// To keep track of whether busy response is default or changed by user additional setting BusyResponseChanged
+		// To keep track of whether do not disturb response is default or changed by user additional setting DoNotDisturbResponseChanged
 		// was added into per account settings.
 
 		// initialization should happen once,so setting variable to TRUE
 		initialized = TRUE;
-		// this connection is needed to properly set "BusyResponseChanged" setting when user makes changes in
-		// busy response message.
-		gSavedPerAccountSettings.getControl("BusyModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onBusyResponseChanged, this));
+		// this connection is needed to properly set "DoNotDisturbResponseChanged" setting when user makes changes in
+		// do not disturb response message.
+		gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onDoNotDisturbResponseChanged, this));
 	}
 	gAgent.sendAgentUserInfoRequest();
 
@@ -709,12 +705,12 @@ void LLFloaterPreference::onVertexShaderEnable()
 }
 
 //static
-void LLFloaterPreference::initBusyResponse()
+void LLFloaterPreference::initDoNotDisturbResponse()
 	{
-		if (!gSavedPerAccountSettings.getBOOL("BusyResponseChanged"))
+		if (!gSavedPerAccountSettings.getBOOL("DoNotDisturbResponseChanged"))
 		{
-			//LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885)
-			gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault"));
+			//LLTrans::getString("DoNotDisturbModeResponseDefault") is used here for localization (EXT-5885)
+			gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
 		}
 	}
 
@@ -1431,14 +1427,11 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
 	getChildView("log_instant_messages")->setEnabled(TRUE);
 //	getChildView("log_chat")->setEnabled(TRUE);
-//	getChildView("busy_response")->setEnabled(TRUE);
 //	getChildView("log_instant_messages_timestamp")->setEnabled(TRUE);
 //	getChildView("log_chat_timestamp")->setEnabled(TRUE);
 	getChildView("log_chat_IM")->setEnabled(TRUE);
 	getChildView("log_date_timestamp")->setEnabled(TRUE);
 	
-//	getChild<LLUICtrl>("busy_response")->setValue(gSavedSettings.getString("BusyModeResponse2"));
-	
 	getChildView("favorites_on_login_check")->setEnabled(TRUE);
 	getChildView("log_nearby_chat")->setEnabled(TRUE);
 	getChildView("log_instant_messages")->setEnabled(TRUE);
@@ -1662,7 +1655,6 @@ BOOL LLPanelPreference::postBuild()
 	if (hasChild("online_visibility") && hasChild("send_im_to_email"))
 	{
 		getChild<LLUICtrl>("email_address")->setValue(getString("log_in_to_change") );
-//		getChild<LLUICtrl>("busy_response")->setValue(getString("log_in_to_change"));		
 	}
 	
 	//////////////////////PanelPrivacy ///////////////////
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index b71f7c647b..10a416beb5 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -75,8 +75,8 @@ public:
 	// refresh all the graphics preferences menus
 	static void refreshEnabledGraphics();
 	
-	// translate user's busy response message according to current locale if message is default, otherwise do nothing
-	static void initBusyResponse();
+	// translate user's do not disturb response message according to current locale if message is default, otherwise do nothing
+	static void initDoNotDisturbResponse();
 
 	void processProperties( void* pData, EAvatarProcessorType type );
 	void processProfileProperties(const LLAvatarData* pAvatarData );
@@ -93,9 +93,9 @@ protected:
 	void		onLanguageChange();
 	void		onNameTagOpacityChange(const LLSD& newvalue);
 
-	// set value of "BusyResponseChanged" in account settings depending on whether busy response
+	// set value of "DoNotDisturbResponseChanged" in account settings depending on whether do not disturb response
 	// string differs from default after user changes.
-	void onBusyResponseChanged();
+	void onDoNotDisturbResponseChanged();
 	// if the custom settings box is clicked
 	void onChangeCustom();
 	void updateMeterText(LLUICtrl* ctrl);
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d5f1e81933..9b14a77c08 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -113,8 +113,8 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 }
 
 void toast_callback(const LLSD& msg){
-	// do not show toast in busy mode or it goes from agent
-	if (gAgent.getBusy() || gAgent.getID() == msg["from_id"])
+	// do not show toast in do not disturb mode or it goes from agent
+	if (gAgent.isDoNotDisturb() || gAgent.getID() == msg["from_id"])
 	{
 		return;
 	}
@@ -3292,13 +3292,13 @@ public:
 			time_t timestamp =
 				(time_t) message_params["timestamp"].asInteger();
 
-			BOOL is_busy = gAgent.getBusy();
+			BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
 			BOOL is_muted = LLMuteList::getInstance()->isMuted(
 				from_id,
 				name,
 				LLMute::flagTextChat);
 
-			if (is_busy || is_muted)
+			if (is_do_not_disturb || is_muted)
 			{
 				return;
 			}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 5d8d82b226..8b04af71c7 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -92,21 +92,6 @@ struct LLMoveInv
 
 using namespace LLOldEvents;
 
-// Helpers
-// bug in busy count inc/dec right now, logic is complex... do we really need it?
-void inc_busy_count()
-{
-// 	gViewerWindow->getWindow()->incBusyCount();
-//  check balance of these calls if this code is changed to ever actually
-//  *do* something!
-}
-void dec_busy_count()
-{
-// 	gViewerWindow->getWindow()->decBusyCount();
-//  check balance of these calls if this code is changed to ever actually
-//  *do* something!
-}
-
 // Function declarations
 void remove_inventory_category_from_avatar(LLInventoryCategory* category);
 void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
@@ -167,7 +152,6 @@ public:
 	{
 		if (clear_observer)
 		{
-			dec_busy_count();
 			gInventory.removeObserver(this);
 			delete this;
 		}
@@ -2668,7 +2652,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
 		llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl;
 		if (clear_observer)
 		{
-		dec_busy_count();
 		gInventory.removeObserver(this);
 		delete this;
 		}
@@ -2682,7 +2665,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
 	// could notify observers and throw us into an infinite loop.
 	if (clear_observer)
 	{
-		dec_busy_count();
 		gInventory.removeObserver(this);
 		delete this;
 	}
@@ -2744,7 +2726,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
 	{
 				// it's all on its way - add an observer, and the inventory
 	// will call done for us when everything is here.
-				inc_busy_count();
 	gInventory.addObserver(outfit);
 			}
 			*/
@@ -2763,7 +2744,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
 			{
 				// it's all on its way - add an observer, and the inventory
 				// will call done for us when everything is here.
-				inc_busy_count();
 				gInventory.addObserver(categories);
 			}
 		}
@@ -3475,7 +3455,6 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 		else
 		{
 			// it's all on its way - add an observer, and the inventory will call done for us when everything is here.
-			inc_busy_count();
 			gInventory.addObserver(fetch);
 	}
 }
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 7834f6d320..1494d9d6ee 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -560,7 +560,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") )
 		|| mChannel.isDead()
-		|| !mChannel.get()->getShowToasts() ) // to prevent toasts in Busy mode
+		|| !mChannel.get()->getShowToasts() ) // to prevent toasts in Do Not Disturb mode
 		return;//no need in toast if chat is visible or if bubble chat is enabled
 
 	// arrange a channel on a screen
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 7990b81d92..ac6110f84f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -179,7 +179,7 @@ LLContextMenu* gDetachScreenPieMenu = NULL;
 LLContextMenu* gDetachBodyPartPieMenus[8];
 
 LLMenuItemCallGL* gAFKMenu = NULL;
-LLMenuItemCallGL* gBusyMenu = NULL;
+LLMenuItemCallGL* gDoNotDisturbMenu = NULL;
 
 //
 // Local prototypes
@@ -471,7 +471,7 @@ void init_menus()
 	gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
 	
 	gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE);
-	gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE);
+	gDoNotDisturbMenu = gMenuBarView->getChild<LLMenuItemCallGL>("set_do_not_disturb", TRUE);
 	gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
 	gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
 
@@ -5564,18 +5564,18 @@ class LLWorldSetAway : public view_listener_t
 	}
 };
 
-class LLWorldSetBusy : public view_listener_t
+class LLWorldSetDoNotDisturb : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		if (gAgent.getBusy())
+		if (gAgent.isDoNotDisturb())
 		{
-			gAgent.clearBusy();
+			gAgent.setDoNotDisturb(false);
 		}
 		else
 		{
-			gAgent.setBusy();
-			LLNotificationsUtil::add("BusyModeSet");
+			gAgent.setDoNotDisturb(true);
+			LLNotificationsUtil::add("DoNotDisturbModeSet");
 		}
 		return true;
 	}
@@ -5737,7 +5737,7 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	if (option == 0)
 	{
-		gAgent.clearBusy();
+		gAgent.setDoNotDisturb(false);
 	}
 
 	LLViewerObject* objectp = selection->getPrimaryObject();
@@ -5770,12 +5770,12 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec
 
 void handle_give_money_dialog()
 {
-	LLNotification::Params params("BusyModePay");
+	LLNotification::Params params("DoNotDisturbModePay");
 	params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
 
-	if (gAgent.getBusy())
+	if (gAgent.isDoNotDisturb())
 	{
-		// warn users of being in busy mode during a transaction
+		// warn users of being in do not disturb mode during a transaction
 		LLNotifications::instance().add(params);
 	}
 	else
@@ -8288,7 +8288,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation");
 	view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
 	view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
-	view_listener_t::addMenu(new LLWorldSetBusy(), "World.SetBusy");
+	view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb");
 
 	view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
 	view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 3515aa4302..e8665a6ef6 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -188,7 +188,7 @@ extern LLContextMenu* gAttachBodyPartPieMenus[8];
 extern LLContextMenu* gDetachBodyPartPieMenus[8];
 
 extern LLMenuItemCallGL* gAFKMenu;
-extern LLMenuItemCallGL* gBusyMenu;
+extern LLMenuItemCallGL* gDoNotDisturbMenu;
 extern LLMenuItemCallGL* gMutePieMenu;
 extern LLMenuItemCallGL* gMuteObjectPieMenu;
 extern LLMenuItemCallGL* gBuyPassPieMenu;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index c5d25ebd1b..d500fd78ff 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -179,7 +179,7 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
 	FALSE	// TeleportYourAgent
 };
 
-static void busy_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null);
+static void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null);
 
 bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 {
@@ -258,11 +258,6 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
 static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback);
 
-//const char BUSY_AUTO_RESPONSE[] =	"The Resident you messaged is in 'busy mode' which means they have "
-//									"requested not to be disturbed. Your message will still be shown in their IM "
-//									"panel for later viewing.";
-
-//
 // Functions
 //
 
@@ -1520,8 +1515,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	// TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
 	from_string = chatHistory_string = mFromName;
 	
-	bool busy = gAgent.getBusy();
-	
 	LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm());
 
 	switch(button)
@@ -1623,9 +1616,9 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			}
 			
 			
-			if (busy &&	(!mFromGroup && !mFromObject))
+			if (gAgent.isDoNotDisturb() && (!mFromGroup && !mFromObject))
 			{
-				busy_message(gMessageSystem, mFromID);
+				send_do_not_disturb_message(gMessageSystem, mFromID);
 			}
 
 			if (modified_form != NULL)
@@ -1750,7 +1743,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 		from_string = chatHistory_string = mFromName;
 	}
 	
-	bool busy = gAgent.getBusy();
+	bool is_do_not_disturb = gAgent.isDoNotDisturb();
 	
 	switch(button)
 	{
@@ -1823,9 +1816,9 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 				LLNotificationsUtil::add("SystemMessageTip", args);
 			}
 			
-			if (busy &&	(!mFromGroup && !mFromObject))
+			if (is_do_not_disturb &&	(!mFromGroup && !mFromObject))
 			{
-				busy_message(msg,mFromID);
+				send_do_not_disturb_message(msg,mFromID);
 			}
 			break;
 	}
@@ -2207,7 +2200,7 @@ static std::string clean_name_from_im(const std::string& name, EInstantMessage t
 	case IM_SESSION_SEND:
 	case IM_SESSION_LEAVE:
 	//IM_FROM_TASK
-	case IM_BUSY_AUTO_RESPONSE:
+	case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
 	case IM_CONSOLE_AND_CHAT_HISTORY:
 	case IM_LURE_USER:
 	case IM_LURE_ACCEPTED:
@@ -2356,7 +2349,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	// IDEVO convert new-style "Resident" names for display
 	name = clean_name_from_im(name, dialog);
 
-	BOOL is_busy = gAgent.getBusy();
+	BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
 	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
 		// object IMs contain sender object id in session_id (STORM-1209)
 		|| dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id);
@@ -2402,15 +2395,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			// do nothing -- don't distract newbies in
 			// Prelude with global IMs
 		}
-		else if (offline == IM_ONLINE && is_busy && name != SYSTEM_FROM)
+		else if (offline == IM_ONLINE && is_do_not_disturb && name != SYSTEM_FROM)
 		{
-			// return a standard "busy" message, but only do it to online IM 
+			// return a standard "do not disturb" message, but only do it to online IM 
 			// (i.e. not other auto responses and not store-and-forward IM)
 			if (!gIMMgr->hasSession(session_id))
 			{
 				// if there is not a panel for this conversation (i.e. it is a new IM conversation
 				// initiated by the other party) then...
-				busy_message(msg, from_id, session_id);
+				send_do_not_disturb_message(msg, from_id, session_id);
 			}
 
 			// now store incoming IM in chat history
@@ -2645,9 +2638,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		break;
 	case IM_GROUP_INVITATION:
 		{
-			if (is_busy || is_muted)
+			if (is_do_not_disturb || is_muted)
 			{
-				busy_message(msg, from_id);
+				send_do_not_disturb_message(msg, from_id);
 			}
 			else
 			{
@@ -2730,7 +2723,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			info->mFromName = name;
 			info->mDesc = message;
 			info->mHost = msg->getSender();
-			//if (((is_busy && !is_owned_by_me) || is_muted))
+			//if (((is_do_not_disturb && !is_owned_by_me) || is_muted))
 			if (is_muted)
 			{
 				// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
@@ -2741,9 +2734,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				// Same as closing window
 				info->forceResponse(IOR_DECLINE);
 			}
-			else if (is_busy && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565)
+			else if (is_do_not_disturb && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565)
 			{
-				// Until throttling is implemented, busy mode should reject inventory instead of silently
+				// Until throttling is implemented, do not disturb mode should reject inventory instead of silently
 				// accepting it.  SEE SL-39554
 				info->forceResponse(IOR_DECLINE);
 			}
@@ -2788,7 +2781,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	
 	case IM_SESSION_SEND:
 	{
-		if (is_busy)
+		if (is_do_not_disturb)
 		{
 			return;
 		}
@@ -2829,7 +2822,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 	case IM_FROM_TASK:
 		{
-			if (is_busy && !is_owned_by_me)
+			if (is_do_not_disturb && !is_owned_by_me)
 			{
 				return;
 			}
@@ -2926,7 +2919,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		}
 		break;
 	case IM_FROM_TASK_AS_ALERT:
-		if (is_busy && !is_owned_by_me)
+		if (is_do_not_disturb && !is_owned_by_me)
 		{
 			return;
 		}
@@ -2937,10 +2930,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			LLNotificationsUtil::add("ObjectMessage", args);
 		}
 		break;
-	case IM_BUSY_AUTO_RESPONSE:
+	case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
 		if (is_muted)
 		{
-			LL_DEBUGS("Messaging") << "Ignoring busy response from " << from_id << LL_ENDL;
+			LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL;
 			return;
 		}
 		else
@@ -2957,9 +2950,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{ 
 				return;
 			}
-			else if (is_busy) 
+			else if (is_do_not_disturb) 
 			{
-				busy_message(msg, from_id);
+				send_do_not_disturb_message(msg, from_id);
 			}
 			else
 			{
@@ -3180,9 +3173,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			payload["online"] = (offline == IM_ONLINE);
 			payload["sender"] = msg->getSender().getIPandPort();
 
-			if (is_busy)
+			if (is_do_not_disturb)
 			{
-				busy_message(msg, from_id);
+				send_do_not_disturb_message(msg, from_id);
 				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
 			}
 			else if (is_muted)
@@ -3246,13 +3239,13 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	}
 }
 
-static void busy_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
+static void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
 {
-	if (gAgent.getBusy())
+	if (gAgent.isDoNotDisturb())
 	{
 		std::string my_name;
 		LLAgentUI::buildFullname(my_name);
-		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
+		std::string response = gSavedPerAccountSettings.getString("DoNotDisturbModeResponse");
 		pack_instant_message(
 			msg,
 			gAgent.getID(),
@@ -3262,7 +3255,7 @@ static void busy_message (LLMessageSystem* msg, const LLUUID& from_id, const LLU
 			my_name,
 			response,
 			IM_ONLINE,
-			IM_BUSY_AUTO_RESPONSE,
+			IM_DO_NOT_DISTURB_AUTO_RESPONSE,
 			session_id);
 		gAgent.sendReliableMessage();
 	}
@@ -3298,7 +3291,7 @@ bool callingcard_offer_callback(const LLSD& notification, const LLSD& response)
 		msg->nextBlockFast(_PREHASH_TransactionBlock);
 		msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
 		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
-		busy_message(msg, notification["payload"]["source_id"].asUUID());
+		send_do_not_disturb_message(msg, notification["payload"]["source_id"].asUUID());
 		break;
 	default:
 		// close button probably, possibly timed out
@@ -3340,7 +3333,7 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
 
 	if(!source_name.empty())
 	{
-		if (gAgent.getBusy() 
+		if (gAgent.isDoNotDisturb() 
 			|| LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
 		{
 			// automatically decline offer
@@ -3469,7 +3462,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		chat.mFromName = from_name;
 	}
 
-	BOOL is_busy = gAgent.getBusy();
+	BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
 
 	BOOL is_muted = FALSE;
 	BOOL is_linden = FALSE;
@@ -3503,7 +3496,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 
 		// record last audible utterance
 		if (is_audible
-			&& (is_linden || (!is_muted && !is_busy)))
+			&& (is_linden || (!is_muted && !is_do_not_disturb)))
 		{
 			if (chat.mChatType != CHAT_TYPE_START 
 				&& chat.mChatType != CHAT_TYPE_STOP)
@@ -3598,7 +3591,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 			LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
 			((LLVOAvatar*)chatter)->stopTyping();
 			
-			if (!is_muted && !is_busy)
+			if (!is_muted && !is_do_not_disturb)
 			{
 				visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
 				std::string formated_msg = "";
@@ -4136,14 +4129,14 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 		gAgent.setFlying(gAgent.canFly());
 	}
 
-	// force simulator to recognize busy state
-	if (gAgent.getBusy())
+	// force simulator to recognize do not disturb state
+	if (gAgent.isDoNotDisturb())
 	{
-		gAgent.setBusy();
+		gAgent.setDoNotDisturb(true);
 	}
 	else
 	{
-		gAgent.clearBusy();
+		gAgent.setDoNotDisturb(false);
 	}
 
 	if (isAgentAvatarValid())
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 3b2292c04d..ee838b19b7 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1824,8 +1824,8 @@ void LLViewerWindow::initBase()
 	gDebugView->init();
 	gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view");
 
-	// Initialize busy response message when logged in
-	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse));
+	// Initialize do not disturb response message when logged in
+	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initDoNotDisturbResponse));
 
 	// Add the progress bar view (startup view), which overrides everything
 	mProgressView = getRootView()->findChild<LLProgressView>("progress_view");
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 7b08744598..4cdba0fba9 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -680,7 +680,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mNameString(),
 	mTitle(),
 	mNameAway(false),
-	mNameBusy(false),
+	mNameDoNotDisturb(false),
 	mNameMute(false),
 	mNameAppearance(false),
 	mNameFriend(false),
@@ -1366,7 +1366,7 @@ void LLVOAvatar::initInstance(void)
 	if (LLCharacter::sInstances.size() == 1)
 	{
 		LLKeyframeMotion::setVFS(gStaticVFS);
-		registerMotion( ANIM_AGENT_BUSY,					LLNullMotion::create );
+		registerMotion( ANIM_AGENT_DO_NOT_DISTURB,					LLNullMotion::create );
 		registerMotion( ANIM_AGENT_CROUCH,					LLKeyframeStandMotion::create );
 		registerMotion( ANIM_AGENT_CROUCHWALK,				LLKeyframeWalkMotion::create );
 		registerMotion( ANIM_AGENT_EXPRESS_AFRAID,			LLEmote::create );
@@ -3100,7 +3100,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 	if (!firstname || !lastname) return;
 
 	bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY)  != mSignaledAnimations.end();
-	bool is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end();
+	bool is_do_not_disturb = mSignaledAnimations.find(ANIM_AGENT_DO_NOT_DISTURB) != mSignaledAnimations.end();
 	bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
 	bool is_muted;
 	if (isSelf())
@@ -3132,7 +3132,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		|| (!title && !mTitle.empty())
 		|| (title && mTitle != title->getString())
 		|| is_away != mNameAway 
-		|| is_busy != mNameBusy 
+		|| is_do_not_disturb != mNameDoNotDisturb 
 		|| is_muted != mNameMute
 		|| is_appearance != mNameAppearance 
 		|| is_friend != mNameFriend
@@ -3142,7 +3142,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 
 		clearNameTag();
 
-		if (is_away || is_muted || is_busy || is_appearance)
+		if (is_away || is_muted || is_do_not_disturb || is_appearance)
 		{
 			std::string line;
 			if (is_away)
@@ -3150,9 +3150,9 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 				line += LLTrans::getString("AvatarAway");
 				line += ", ";
 			}
-			if (is_busy)
+			if (is_do_not_disturb)
 			{
-				line += LLTrans::getString("AvatarBusy");
+				line += LLTrans::getString("AvatarDoNotDisturb");
 				line += ", ";
 			}
 			if (is_muted)
@@ -3222,7 +3222,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		}
 
 		mNameAway = is_away;
-		mNameBusy = is_busy;
+		mNameDoNotDisturb = is_do_not_disturb;
 		mNameMute = is_muted;
 		mNameAppearance = is_appearance;
 		mNameFriend = is_friend;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index e45069dbfe..c59a3a150c 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -942,7 +942,7 @@ private:
 	std::string		mNameString;		// UTF-8 title + name + status
 	std::string  	mTitle;
 	bool	  		mNameAway;
-	bool	  		mNameBusy;
+	bool	  		mNameDoNotDisturb;
 	bool	  		mNameMute;
 	bool      		mNameAppearance;
 	bool			mNameFriend;
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index f1bf4a6d75..71006d38d2 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -3939,7 +3939,7 @@ void LLVivoxVoiceClient::messageEvent(
 		sessionState *session = findSession(sessionHandle);
 		if(session)
 		{
-			bool is_busy = gAgent.getBusy();
+			bool is_do_not_disturb = gAgent.isDoNotDisturb();
 			bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat);
 			bool is_linden = LLMuteList::getInstance()->isLinden(session->mName);
 			bool quiet_chat = false;
@@ -3953,10 +3953,10 @@ void LLVivoxVoiceClient::messageEvent(
 				chat.mFromName = session->mName;
 				chat.mSourceType = CHAT_SOURCE_AGENT;
 
-				if(is_busy && !is_linden)
+				if(is_do_not_disturb && !is_linden)
 				{
 					quiet_chat = true;
-					// TODO: Question: Return busy mode response here?  Or maybe when session is started instead?
+					// TODO: Question: Return do not disturb mode response here?  Or maybe when session is started instead?
 				}
 				
 				LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL;
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index c805b6db42..f6a307d9d0 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -138,9 +138,9 @@
         </menu_item_call>
         <menu_item_call
          label="Busy"
-         name="Set Busy">
+         name="set_do_not_disturb">
           <menu_item_call.on_click
-           function="World.SetBusy"/>
+           function="World.SetDoNotDisturb"/>
         </menu_item_call>
       </menu>
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 4410f41e29..1c1642abac 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3691,12 +3691,12 @@ Cannot offer friendship at this time. Please try again in a moment.
 
   <notification
    icon="alert.tga"
-   name="BusyModeSet"
+   name="DoNotDisturbModeSet"
    type="alert">
 Busy mode is set.
 Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash.
     <usetemplate
-     ignoretext="I change my status to Busy mode"
+     ignoretext="I change my status to Do Not Disturb mode"
      name="okignore"
      yestext="OK"/>
   </notification>
@@ -5167,8 +5167,8 @@ Do you want to replace it with the selected object?
 
   <notification
    icon="alert.tga"
-   label="Busy Mode Warning"
-   name="BusyModePay"
+   label="Do Not Disturb Mode Warning"
+   name="DoNotDisturbModePay"
    type="alert">
 You are in Busy Mode, which means you will not receive any items offered in exchange for this payment.
 
@@ -5177,15 +5177,15 @@ Would you like to leave Busy Mode before completing this transaction?
     <form name="form">
       <ignore name="ignore"
        save_option="true"
-       text="I am about to pay a person or object while I am in Busy mode"/>
+       text="I am about to pay a person or object while I am in Do Not Disturb mode"/>
       <button
        default="true"
-       ignore="Always leave Busy Mode"
+       ignore="Always leave Do Not Disturb Mode"
        index="0"
        name="Yes"
        text="OK"/>
       <button
-       ignore="Never leave Busy Mode"
+       ignore="Never leave Do Not Disturb Mode"
        index="1"
        name="No"
        text="Cancel"/>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 24882988b0..2cb063e8ee 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -412,7 +412,7 @@
        Busy mode response:
     </text>
     <text_editor
-     control_name="BusyModeResponse"
+     control_name="DoNotDisturbModeResponse"
       text_readonly_color="LabelDisabledColor"
       bg_writeable_color="LtGray"
       use_ellipses="false"
@@ -421,7 +421,7 @@
      height="29"
      layout="topleft"
      left="30"
-     name="busy_response"
+     name="do_not_disturb_response"
      width="470"
      word_wrap="true">
        log_in_to_change
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 01da0a3686..04b6326769 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -295,7 +295,7 @@ Please try logging in again in a minute.</string>
 	<!-- llvoavatar. Displayed in the avatar chat bubble -->
 	<string name="AvatarEditingAppearance">(Editing Appearance)</string>
 	<string name="AvatarAway">Away</string>
-	<string name="AvatarBusy">Busy</string>
+	<string name="AvatarDoNotDisturb">Busy</string>
 	<string name="AvatarMuted">Blocked</string>
 
 	<!-- animations -->
@@ -2077,8 +2077,8 @@ For AI Character: Get the closest navigable point to the point provided.
   <!-- Avatar busy/away mode -->
 	<string name="AvatarSetNotAway">Not Away</string>
 	<string name="AvatarSetAway">Away</string>
-	<string name="AvatarSetNotBusy">Not Busy</string>
-	<string name="AvatarSetBusy">Busy</string>
+	<string name="AvatarSetAvailable">Not Busy</string>
+	<string name="AvatarSetDoNotDisturb">Busy</string>
 
 	<!-- Wearable Types -->
 	<string name="shape">Shape</string>
@@ -2526,7 +2526,7 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="PanelContentsNewScript">New Script</string>
 
   <!-- panel preferences general -->
-  <string name="BusyModeResponseDefault">The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>
+  <string name="DoNotDisturbModeResponseDefault">The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>
 
 	<!-- Mute -->
 	<string name="MuteByName">(By name)</string>
-- 
cgit v1.2.3


From 5aa5a77af66425dd90599b0b0cad5b8f58d7669a Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Thu, 8 Nov 2012 15:15:27 -0800
Subject: CHUI-516: Correcting crash when receiving a god-like teleport lure
 request while in do-not-disturb mode.

---
 indra/newview/llviewermessage.cpp | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index d500fd78ff..1ddfc51f27 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2033,11 +2033,14 @@ bool lure_callback(const LLSD& notification, const LLSD& response)
 
 	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
 
-	LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
-	modified_form->setElementEnabled("Teleport", false);
-	modified_form->setElementEnabled("Cancel", false);
-	notification_ptr->updateForm(modified_form);
-	notification_ptr->repost();
+	if (notification_ptr)
+	{
+		LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+		modified_form->setElementEnabled("Teleport", false);
+		modified_form->setElementEnabled("Cancel", false);
+		notification_ptr->updateForm(modified_form);
+		notification_ptr->repost();
+	}
 
 	return false;
 }
-- 
cgit v1.2.3


From 1d590cd5fdecabbbf6e96be37a2673de347e2224 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 8 Nov 2012 17:09:23 -0800
Subject: CHUI-464, CHUI-466, CHUI-474 : Fixed! Better, unified and more
 consistent use of refreshConversation() to update torn off dialogs.

---
 indra/newview/llimconversation.cpp | 25 ++++++++-----------------
 indra/newview/llimconversation.h   |  1 -
 2 files changed, 8 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
index e031b0e829..d1fa6e2103 100644
--- a/indra/newview/llimconversation.cpp
+++ b/indra/newview/llimconversation.cpp
@@ -51,7 +51,6 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
   ,  mTearOffBtn(NULL)
   ,  mCloseBtn(NULL)
   ,  mSessionID(session_id.asUUID())
-//  , mParticipantList(NULL)
   , mConversationsRoot(NULL)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
@@ -77,14 +76,6 @@ LLIMConversation::LLIMConversation(const LLSD& session_id)
 
 LLIMConversation::~LLIMConversation()
 {
-	/*
-	if (mParticipantList)
-	{
-		delete mParticipantList;
-		mParticipantList = NULL;
-	}
-	 */
-
 	delete mRefreshTimer;
 }
 
@@ -246,8 +237,6 @@ BOOL LLIMConversation::postBuild()
 
 	buildConversationViewParticipant();
 
-	updateHeaderAndToolbar();
-
 	mSaveRect = isTornOff();
 	initRectControl();
 
@@ -264,6 +253,8 @@ BOOL LLIMConversation::postBuild()
 		result = LLDockableFloater::postBuild();
 	}
 
+	refreshConversation();
+	
 	return result;
 }
 
@@ -274,8 +265,6 @@ LLParticipantList* LLIMConversation::getParticipantList()
 
 void LLIMConversation::draw()
 {
-	LLTransientDockableFloater::draw();
-
 	if (mRefreshTimer->hasExpired())
 	{
 		if (getParticipantList())
@@ -283,12 +272,13 @@ void LLIMConversation::draw()
 			getParticipantList()->update();
 		}
 
-		refresh();
-		updateHeaderAndToolbar();
+		refreshConversation();
 
 		// Restart the refresh timer
 		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
 	}
+	
+	LLTransientDockableFloater::draw();
 }
 
 void LLIMConversation::enableDisableCallBtn()
@@ -488,6 +478,8 @@ void LLIMConversation::refreshConversation()
 	mConversationViewModel.requestSortAll();
 	mConversationsRoot->arrangeAll();
 	mConversationsRoot->update();
+	updateHeaderAndToolbar();
+	refresh();
 }
 
 // Copied from LLIMFloaterContainer::createConversationViewParticipant(). Refactor opportunity!
@@ -731,7 +723,6 @@ void LLIMConversation::onTearOffClicked()
     mSaveRect = isTornOff();
     initRectControl();
 	LLFloater::onClickTearOff(this);
-	updateHeaderAndToolbar();
 	refreshConversation();
 }
 
@@ -749,7 +740,7 @@ bool LLIMConversation::checkIfTornOff()
 	if (isTorn != isTornOff())
 	{
 		setTornOff(isTorn);
-		updateHeaderAndToolbar();
+		refreshConversation();
 	}
 
 	return isTorn;
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
index 49cfcb68c4..93a1ab847e 100644
--- a/indra/newview/llimconversation.h
+++ b/indra/newview/llimconversation.h
@@ -142,7 +142,6 @@ protected:
 	
 	LLUUID mSessionID; 
 	LLLayoutPanel* mParticipantListPanel;	// add the widgets to that see mConversationsListPanel
-	//LLParticipantList* mParticipantList; get this from the mConversationsItems for the moment
 	LLParticipantList* getParticipantList();
 	conversations_widgets_map mConversationsWidgets;
 	LLConversationViewModel mConversationViewModel;
-- 
cgit v1.2.3


From 486bdf32845e248ec4923224f1f4ea5d239ac0f3 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 9 Nov 2012 12:45:36 +0200
Subject: CHUI-337 FIXED: To avoid confusion with a classes
 "...conversation..." and in accordance with the naming convention in the
 project, some classes and corresponding files should be renamed:
 LLIMConversation -> LLFloaterIMSessionTab LLIMFloater -> LLFloaterIMSession
 LLNearbyChat -> LLFloaterIMNearbyChat LLIMFloaterContainer ->
 LLFloaterIMContainer LLNearbyChatBarListener -> LLFloaterIMNearbyChatListener
 LLNearbyChatHandler -> LLFloaterIMNearbyChatHandler

---
 indra/newview/CMakeLists.txt                    |   24 +-
 indra/newview/llagent.cpp                       |    6 +-
 indra/newview/llappviewer.cpp                   |    4 +-
 indra/newview/llavataractions.cpp               |    6 +-
 indra/newview/llavatariconctrl.cpp              |    2 +-
 indra/newview/llchatbar.cpp                     |    2 +-
 indra/newview/llchatitemscontainerctrl.cpp      |   38 +-
 indra/newview/llchatitemscontainerctrl.h        |    8 +-
 indra/newview/llchiclet.cpp                     |   16 +-
 indra/newview/llchiclet.h                       |    2 +-
 indra/newview/llchicletbar.cpp                  |   10 +-
 indra/newview/llconversationlog.cpp             |    6 +-
 indra/newview/llconversationlog.h               |    4 +-
 indra/newview/llconversationloglistitem.cpp     |    6 +-
 indra/newview/llconversationloglistitem.h       |    2 +-
 indra/newview/llconversationview.cpp            |   14 +-
 indra/newview/llconversationview.h              |    8 +-
 indra/newview/llfloaterconversationpreview.cpp  |    4 +-
 indra/newview/llfloaterimcontainer.cpp          | 1557 +++++++++++++++++++++++
 indra/newview/llfloaterimcontainer.h            |  178 +++
 indra/newview/llfloaterimnearbychat.cpp         |  867 +++++++++++++
 indra/newview/llfloaterimnearbychat.h           |  125 ++
 indra/newview/llfloaterimnearbychathandler.cpp  |  630 +++++++++
 indra/newview/llfloaterimnearbychathandler.h    |   54 +
 indra/newview/llfloaterimnearbychatlistener.cpp |  100 ++
 indra/newview/llfloaterimnearbychatlistener.h   |   50 +
 indra/newview/llfloaterimsession.cpp            | 1202 +++++++++++++++++
 indra/newview/llfloaterimsession.h              |  196 +++
 indra/newview/llfloaterimsessiontab.cpp         |  743 +++++++++++
 indra/newview/llfloaterimsessiontab.h           |  176 +++
 indra/newview/llfloaterpreference.cpp           |    6 +-
 indra/newview/llfloatertranslationsettings.cpp  |    4 +-
 indra/newview/llgesturemgr.cpp                  |    4 +-
 indra/newview/llgroupactions.cpp                |    4 +-
 indra/newview/llgroupiconctrl.cpp               |    2 +-
 indra/newview/llimconversation.cpp              |  743 -----------
 indra/newview/llimconversation.h                |  176 ---
 indra/newview/llimfloater.cpp                   | 1202 -----------------
 indra/newview/llimfloater.h                     |  196 ---
 indra/newview/llimfloatercontainer.cpp          | 1557 -----------------------
 indra/newview/llimfloatercontainer.h            |  178 ---
 indra/newview/llimpanel.cpp                     |    2 +-
 indra/newview/llimview.cpp                      |   36 +-
 indra/newview/llinventorybridge.cpp             |    4 +-
 indra/newview/llinventorypanel.cpp              |    4 +-
 indra/newview/llnearbychat.cpp                  |  867 -------------
 indra/newview/llnearbychat.h                    |  125 --
 indra/newview/llnearbychatbarlistener.cpp       |  100 --
 indra/newview/llnearbychatbarlistener.h         |   50 -
 indra/newview/llnearbychathandler.cpp           |  630 ---------
 indra/newview/llnearbychathandler.h             |   54 -
 indra/newview/llnotificationhandler.h           |    2 +-
 indra/newview/llnotificationhandlerutil.cpp     |   10 +-
 indra/newview/llnotificationmanager.cpp         |    4 +-
 indra/newview/llnotificationmanager.h           |    2 +-
 indra/newview/llnotificationtiphandler.cpp      |    6 +-
 indra/newview/llparticipantlist.cpp             |    6 +-
 indra/newview/llscreenchannel.cpp               |    2 +-
 indra/newview/llscriptfloater.cpp               |    2 +-
 indra/newview/llstartup.cpp                     |    8 +-
 indra/newview/lltoastnotifypanel.cpp            |    2 +-
 indra/newview/llviewerfloaterreg.cpp            |   12 +-
 indra/newview/llviewergesture.cpp               |    4 +-
 indra/newview/llviewerkeyboard.cpp              |   10 +-
 indra/newview/llviewermessage.cpp               |    6 +-
 indra/newview/llviewerwindow.cpp                |    6 +-
 66 files changed, 6033 insertions(+), 6033 deletions(-)
 create mode 100644 indra/newview/llfloaterimcontainer.cpp
 create mode 100644 indra/newview/llfloaterimcontainer.h
 create mode 100644 indra/newview/llfloaterimnearbychat.cpp
 create mode 100644 indra/newview/llfloaterimnearbychat.h
 create mode 100644 indra/newview/llfloaterimnearbychathandler.cpp
 create mode 100644 indra/newview/llfloaterimnearbychathandler.h
 create mode 100644 indra/newview/llfloaterimnearbychatlistener.cpp
 create mode 100644 indra/newview/llfloaterimnearbychatlistener.h
 create mode 100644 indra/newview/llfloaterimsession.cpp
 create mode 100644 indra/newview/llfloaterimsession.h
 create mode 100644 indra/newview/llfloaterimsessiontab.cpp
 create mode 100644 indra/newview/llfloaterimsessiontab.h
 delete mode 100644 indra/newview/llimconversation.cpp
 delete mode 100644 indra/newview/llimconversation.h
 delete mode 100644 indra/newview/llimfloater.cpp
 delete mode 100644 indra/newview/llimfloater.h
 delete mode 100644 indra/newview/llimfloatercontainer.cpp
 delete mode 100644 indra/newview/llimfloatercontainer.h
 delete mode 100644 indra/newview/llnearbychat.cpp
 delete mode 100644 indra/newview/llnearbychat.h
 delete mode 100644 indra/newview/llnearbychatbarlistener.cpp
 delete mode 100644 indra/newview/llnearbychatbarlistener.h
 delete mode 100644 indra/newview/llnearbychathandler.cpp
 delete mode 100644 indra/newview/llnearbychathandler.h

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2c7e96f1e4..45c719f28d 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -299,9 +299,9 @@ set(viewer_SOURCE_FILES
     llhudrender.cpp
     llhudtext.cpp
     llhudview.cpp
-    llimconversation.cpp
-    llimfloater.cpp
-    llimfloatercontainer.cpp
+    llfloaterimsessiontab.cpp
+    llfloaterimsession.cpp
+    llfloaterimcontainer.cpp
     llimhandler.cpp
     llimview.cpp
     llinspect.cpp
@@ -353,9 +353,9 @@ set(viewer_SOURCE_FILES
     llnameeditor.cpp
     llnamelistctrl.cpp
     llnavigationbar.cpp
-    llnearbychat.cpp
-    llnearbychathandler.cpp
-    llnearbychatbarlistener.cpp
+    llfloaterimnearbychat.cpp
+    llfloaterimnearbychathandler.cpp
+    llfloaterimnearbychatlistener.cpp
     llnetmap.cpp
     llnotificationalerthandler.cpp
     llnotificationgrouphandler.cpp
@@ -882,9 +882,9 @@ set(viewer_HEADER_FILES
     llhudrender.h
     llhudtext.h
     llhudview.h
-    llimconversation.h
-    llimfloater.h
-    llimfloatercontainer.h
+    llfloaterimsessiontab.h
+    llfloaterimsession.h
+    llfloaterimcontainer.h
     llimview.h
     llinspect.h
     llinspectavatar.h
@@ -936,9 +936,9 @@ set(viewer_HEADER_FILES
     llnameeditor.h
     llnamelistctrl.h
     llnavigationbar.h
-    llnearbychat.h
-    llnearbychathandler.h
-    llnearbychatbarlistener.h
+    llfloaterimnearbychat.h
+    llfloaterimnearbychathandler.h
+    llfloaterimnearbychatlistener.h
     llnetmap.h
     llnotificationhandler.h
     llnotificationmanager.h
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index cefd5c72e8..9c3a7ac45b 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -54,7 +54,7 @@
 #include "llmorphview.h"
 #include "llmoveview.h"
 #include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotificationsutil.h"
 #include "llpanelpathfindingrebakenavmesh.h"
 #include "llpaneltopinfobar.h"
@@ -1899,7 +1899,7 @@ void LLAgent::startTyping()
 	{
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
 	}
-	(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
 			sendChatFromViewer("", CHAT_TYPE_START, FALSE);
 }
 
@@ -1912,7 +1912,7 @@ void LLAgent::stopTyping()
 	{
 		clearRenderState(AGENT_STATE_TYPING);
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
-		(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+		(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
 				sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
 	}
 }
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index b23e5866dc..8abe9bcfc1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -42,7 +42,7 @@
 #include "llagentcamera.h"
 #include "llagentlanguage.h"
 #include "llagentwearables.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
 #include "llwindow.h"
 #include "llviewerstats.h"
 #include "llviewerstatsrecorder.h"
@@ -1204,7 +1204,7 @@ bool LLAppViewer::mainLoop()
 
 	LLVoiceChannel::initClass();
 	LLVoiceClient::getInstance()->init(gServicePump);
-	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLIMFloaterContainer::onCurrentChannelChanged, _1), true);
+	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
 	LLTimer frameTimer,idleTimer;
 	LLTimer debugTime;
 	LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 130428f3c0..4f57498506 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -56,7 +56,7 @@
 #include "llinventorybridge.h"
 #include "llinventorymodel.h"	// for gInventory.findCategoryUUIDForType
 #include "llinventorypanel.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h"			// for gIMMgr
 #include "llmutelist.h"
 #include "llnotificationsutil.h"	// for LLNotificationsUtil
@@ -184,7 +184,7 @@ static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
 	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id);
 	if (session_id != LLUUID::null)
 	{
-		LLIMFloaterContainer::getInstance()->showConversation(session_id);
+		LLFloaterIMContainer::getInstance()->showConversation(session_id);
 	}
 	make_ui_sound("UISndStartIM");
 }
@@ -302,7 +302,7 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& float
 		return;
 	}
 	
-	LLIMFloaterContainer::getInstance()->showConversation(session_id);
+	LLFloaterIMContainer::getInstance()->showConversation(session_id);
 	
 	make_ui_sound("UISndStartIM");
 }
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 6355f0db56..b7278d4a3a 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -38,7 +38,7 @@
 #include "llmenugl.h"
 #include "lluictrlfactory.h"
 #include "llagentdata.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 
 // library includes
 #include "llavatarnamecache.h"
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index d6095cce07..27138e6c06 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -672,7 +672,7 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
 
 
 /* Cruft - global gChatHandler declared below has been commented out,
-   so this class is never used.  See similar code in llnearbychatbar.cpp
+   so this class is never used.  See similar code in llfloaterimnearbychatbar.cpp
 class LLChatHandler : public LLCommandHandler
 {
 public:
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index f1b5c42ef3..a1a9463d43 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -35,7 +35,7 @@
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
 #include "lltrans.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 
 #include "llviewercontrol.h"
 #include "llagentdata.h"
@@ -81,18 +81,18 @@ public:
 LLObjectHandler gObjectHandler;
 
 //*******************************************************************************************************************
-//LLNearbyChatToastPanel
+//LLFloaterIMNearbyChatToastPanel
 //*******************************************************************************************************************
 
-LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
+LLFloaterIMNearbyChatToastPanel* LLFloaterIMNearbyChatToastPanel::createInstance()
 {
-	LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
+	LLFloaterIMNearbyChatToastPanel* item = new LLFloaterIMNearbyChatToastPanel();
 	item->buildFromFile("panel_chat_item.xml");
 	item->setFollows(FOLLOWS_NONE);
 	return item;
 }
 
-void	LLNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_parent )
+void	LLFloaterIMNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_parent )
 {
 	LLPanel::reshape(width, height,called_from_parent);
 
@@ -121,12 +121,12 @@ void	LLNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_p
 	msg_text->setRect(msg_text_rect);
 }
 
-BOOL LLNearbyChatToastPanel::postBuild()
+BOOL LLFloaterIMNearbyChatToastPanel::postBuild()
 {
 	return LLPanel::postBuild();
 }
 
-void LLNearbyChatToastPanel::addMessage(LLSD& notification)
+void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)
 {
 	std::string		messageText = notification["message"].asString();		// UTF-8 line of text
 
@@ -178,7 +178,7 @@ void LLNearbyChatToastPanel::addMessage(LLSD& notification)
 
 }
 
-void LLNearbyChatToastPanel::init(LLSD& notification)
+void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
 {
 	std::string		messageText = notification["message"].asString();		// UTF-8 line of text
 	std::string		fromName = notification["from"].asString();	// agent or object name
@@ -273,7 +273,7 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
 	mIsDirty = true;//will set Avatar Icon in draw
 }
 
-void	LLNearbyChatToastPanel::snapToMessageHeight	()
+void	LLFloaterIMNearbyChatToastPanel::snapToMessageHeight	()
 {
 	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
 	S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25);
@@ -288,22 +288,22 @@ void	LLNearbyChatToastPanel::snapToMessageHeight	()
 
 }
 
-void LLNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)
+void LLFloaterIMNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)
 {
 	
 }
-void LLNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)
+void LLFloaterIMNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)
 {
 	if(mSourceType != CHAT_SOURCE_AGENT)
 		return;
 }
 
-BOOL	LLNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)
+BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)
 {
 	return LLPanel::handleMouseDown(x,y,mask);
 }
 
-BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
+BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
 {
 	/*
 	fix for request  EXT-4780
@@ -323,16 +323,16 @@ BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
 			return TRUE;
 		else
 		{
-			(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->showHistory();
+			(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory();
 			return FALSE;
 		}
 	}
 
-	(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->showHistory();
+	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory();
 	return LLPanel::handleMouseUp(x,y,mask);
 }
 
-void	LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
+void	LLFloaterIMNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
 {
 	LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
 	if(icon)
@@ -340,7 +340,7 @@ void	LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
 
 }
 
-bool	LLNearbyChatToastPanel::canAddText	()
+bool	LLFloaterIMNearbyChatToastPanel::canAddText	()
 {
 	LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
 	if(!msg_text)
@@ -348,7 +348,7 @@ bool	LLNearbyChatToastPanel::canAddText	()
 	return msg_text->getLineCount()<10;
 }
 
-BOOL	LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
+BOOL	LLFloaterIMNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false);
 
@@ -360,7 +360,7 @@ BOOL	LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
 		return TRUE;
 	return LLPanel::handleRightMouseDown(x,y,mask);
 }
-void LLNearbyChatToastPanel::draw()
+void LLFloaterIMNearbyChatToastPanel::draw()
 {
 	LLPanel::draw();
 
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index 89b0c4f37a..54b6499d52 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -40,18 +40,18 @@ typedef enum e_show_item_header
 	CHATITEMHEADER_SHOW_BOTH
 } EShowItemHeader;
 
-class LLNearbyChatToastPanel : public LLPanel
+class LLFloaterIMNearbyChatToastPanel : public LLPanel
 {
 protected:
-        LLNearbyChatToastPanel()
+        LLFloaterIMNearbyChatToastPanel()
 		: 
 	mIsDirty(false),
 	mSourceType(CHAT_SOURCE_OBJECT)
 	{};
 public:
-	~LLNearbyChatToastPanel(){}
+	~LLFloaterIMNearbyChatToastPanel(){}
 	
-	static LLNearbyChatToastPanel* createInstance();
+	static LLFloaterIMNearbyChatToastPanel* createInstance();
 
 	const LLUUID& getFromID() const { return mFromID;}
 	const std::string& getFromName() const { return mFromName; }
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index e328186fd6..64d8a68a99 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -33,8 +33,8 @@
 #include "lleventtimer.h"
 #include "llgroupactions.h"
 #include "lliconctrl.h"
-#include "llimfloater.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h"
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
@@ -605,7 +605,7 @@ bool LLIMChiclet::getShowNewMessagesIcon()
 
 void LLIMChiclet::onMouseDown()
 {
-	LLIMFloater::toggle(getSessionId());
+	LLFloaterIMSession::toggle(getSessionId());
 	setCounter(0);
 }
 
@@ -754,7 +754,7 @@ void LLIMP2PChiclet::updateMenuItems()
 	if(getSessionId().isNull())
 		return;
 
-	LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId());
+	LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(getSessionId());
 	bool open_window_exists = open_im_floater && open_im_floater->getVisible();
 	mPopupMenu->getChild<LLUICtrl>("Send IM")->setEnabled(!open_window_exists);
 	
@@ -1030,7 +1030,7 @@ void LLIMGroupChiclet::updateMenuItems()
 	if(getSessionId().isNull())
 		return;
 
-	LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId());
+	LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(getSessionId());
 	bool open_window_exists = open_im_floater && open_im_floater->getVisible();
 	mPopupMenu->getChild<LLUICtrl>("Chat")->setEnabled(!open_window_exists);
 }
@@ -1116,7 +1116,7 @@ void LLChicletPanel::onMessageCountChanged(const LLSD& data)
 	LLUUID session_id = data["session_id"].asUUID();
 	S32 unread = data["participant_unread"].asInteger();
 
-	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 	if (im_floater && im_floater->getVisible() && im_floater->hasFocus())
 	{
 		unread = 0;
@@ -1197,7 +1197,7 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
 			chiclet->setShowSpeaker(true);
 			if (gSavedSettings.getBOOL("OpenIMOnVoice"))
 			{
-				LLIMFloaterContainer::getInstance()->showConversation(session_id);
+				LLFloaterIMContainer::getInstance()->showConversation(session_id);
 			}
 		}
 	}
@@ -1688,7 +1688,7 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
 	for (chiclet_list_t::iterator it = mChicletList.begin(); it
 			!= mChicletList.end(); it++)
 	{
-		LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>(
+		LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>(
 				"impanel", (*it)->getSessionId());
 		if (im_floater != NULL && im_floater->getVisible()
 				&& !im_floater->isMinimized() && im_floater->isDocked())
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 6395f5b694..3c8389e20d 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -37,7 +37,7 @@
 #include "llnotifications.h"
 
 class LLMenuGL;
-class LLIMFloater;
+class LLFloaterIMSession;
 
 /**
  * Class for displaying amount of messages/notifications(unread).
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index 3ebb83b336..ad7890b47a 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -34,7 +34,7 @@
 
 // newview includes
 #include "llchiclet.h"
-#include "llimfloater.h" // for LLIMFloater
+#include "llfloaterimsession.h" // for LLFloaterIMSession
 #include "llpaneltopinfobar.h"
 #include "llsyswellwindow.h"
 
@@ -95,9 +95,9 @@ void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& nam
 	if (session->isP2P() && session->isOtherParticipantAvaline()) return;
 
 	// Do not spawn chiclet when using the new multitab conversation UI
-	if (LLIMConversation::isChatMultiTab())
+	if (LLFloaterIMSessionTab::isChatMultiTab())
 	{
-		LLIMConversation::addToHost(session_id);
+		LLFloaterIMSessionTab::addToHost(session_id);
 		return;
 	}
 	
@@ -109,7 +109,7 @@ void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& nam
 		chiclet->setIMSessionName(name);
 		chiclet->setOtherParticipantId(other_participant_id);
 
-		LLIMFloater::onIMChicletCreated(session_id);
+		LLFloaterIMSession::onIMChicletCreated(session_id);
 
 	}
 	else
@@ -124,7 +124,7 @@ void LLChicletBar::sessionRemoved(const LLUUID& session_id)
 	if(getChicletPanel())
 	{
 		// IM floater should be closed when session removed and associated chiclet closed
-		LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+		LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
 		if (im_floater != NULL && !im_floater->getStartConferenceInSameFloater())
 		{
 			// Close the IM floater only if we are not planning to close the P2P chat
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 7a5a476efb..3d2b6a5c00 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -140,15 +140,15 @@ bool LLConversation::isOlderThan(U32 days) const
 
 void LLConversation::setListenIMFloaterOpened()
 {
-	LLIMFloater* floater = LLIMFloater::findInstance(mSessionID);
+	LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(mSessionID);
 
-	bool offline_ims_visible = LLIMFloater::isVisible(floater) && floater->hasFocus();
+	bool offline_ims_visible = LLFloaterIMSession::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 (mHasOfflineIMs && !offline_ims_visible)
 	{
-		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
+		mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
 	}
 	else
 	{
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index b92cf0f5e2..7d0b9113c6 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -27,7 +27,7 @@
 #define LLCONVERSATIONLOG_H_
 
 #include "llcallingcard.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llimview.h"
 
 class LLConversationLogObserver;
@@ -80,7 +80,7 @@ public:
 private:
 
 	/*
-	 * If conversation has unread offline messages sets callback for opening LLIMFloater
+	 * If conversation has unread offline messages sets callback for opening LLFloaterIMSession
 	 * with this conversation.
 	 */
 	void setListenIMFloaterOpened();
diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
index b4ae5f19da..9fad0e603e 100644
--- a/indra/newview/llconversationloglistitem.cpp
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -47,13 +47,13 @@ LLConversationLogListItem::LLConversationLogListItem(const LLConversation* conve
 {
 	buildFromFile("panel_conversation_log_list_item.xml");
 
-	LLIMFloater* floater = LLIMFloater::findInstance(mConversation->getSessionID());
+	LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(mConversation->getSessionID());
 
-	bool ims_are_read = LLIMFloater::isVisible(floater) && floater->hasFocus();
+	bool ims_are_read = LLFloaterIMSession::isVisible(floater) && floater->hasFocus();
 
 	if (mConversation->hasOfflineMessages() && !ims_are_read)
 	{
-		mIMFloaterShowedConnection = LLIMFloater::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
+		mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
 	}
 }
 
diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h
index 1bf7a0ed93..57f72db382 100644
--- a/indra/newview/llconversationloglistitem.h
+++ b/indra/newview/llconversationloglistitem.h
@@ -26,7 +26,7 @@
 #ifndef LLCONVERSATIONLOGLISTITEM_H_
 #define LLCONVERSATIONLOGLISTITEM_H_
 
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llpanel.h"
 
 class LLTextBox;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index ac5b2ad6ac..3495d74191 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -32,10 +32,10 @@
 #include <boost/bind.hpp>
 #include "llagentdata.h"
 #include "llconversationmodel.h"
-#include "llimfloater.h"
-#include "llnearbychat.h"
-#include "llimconversation.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimnearbychat.h"
+#include "llfloaterimsessiontab.h"
+#include "llfloaterimcontainer.h"
 #include "llfloaterreg.h"
 #include "llgroupiconctrl.h"
 #include "lluictrlfactory.h"
@@ -208,7 +208,7 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
 	LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
     LLUUID session_id = item? item->getUUID() : LLUUID();
 
-	(LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container"))->
+	(LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
     		selectConversationPair(session_id, false);
 
 	return LLFolderViewFolder::handleMouseDown(x, y, mask);
@@ -262,7 +262,7 @@ void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
 	// Note: minimized dockable floaters are brought to front hence unminimized when made visible and we don't want that here
 	LLFolderViewModelItem* item = mViewModelItem;
 	LLUUID session_uuid = dynamic_cast<LLConversationItem*>(item)->getUUID();
-	LLFloater* session_floater = LLIMConversation::getConversation(session_uuid);
+	LLFloater* session_floater = LLFloaterIMSessionTab::getConversation(session_uuid);
 	
 	if (session_floater && !session_floater->getHost() && !session_floater->isMinimized())
 	{
@@ -505,7 +505,7 @@ BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
 	}
     LLUUID session_id = item? item->getUUID() : LLUUID();
 
-	(LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container"))->
+	(LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
     		selectConversationPair(session_id, false);
 
 	return LLFolderViewItem::handleMouseDown(x, y, mask);
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 43547d155b..cc6995c207 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -34,7 +34,7 @@
 #include "lloutputmonitorctrl.h"
 
 class LLTextBox;
-class LLIMFloaterContainer;
+class LLFloaterIMContainer;
 class LLConversationViewSession;
 class LLConversationViewParticipant;
 
@@ -47,7 +47,7 @@ class LLConversationViewSession : public LLFolderViewFolder
 public:
 	struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
 	{
-		Optional<LLIMFloaterContainer*>			container;
+		Optional<LLFloaterIMContainer*>			container;
 
 		Params();
 	};
@@ -56,7 +56,7 @@ protected:
 	friend class LLUICtrlFactory;
 	LLConversationViewSession( const Params& p );
 	
-	LLIMFloaterContainer* mContainer;
+	LLFloaterIMContainer* mContainer;
 	
 public:
 	virtual ~LLConversationViewSession();
@@ -107,7 +107,7 @@ public:
 
 	struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
 	{
-        Optional<LLIMFloaterContainer*>			container;
+        Optional<LLFloaterIMContainer*>			container;
 		Optional<LLUUID>	                    participant_id;
         Optional<LLAvatarIconCtrl::Params>	    avatar_icon;
 		Optional<LLButton::Params>				info_button;
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index a3825eafc8..c93181c0a1 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -29,7 +29,7 @@
 #include "llfloaterconversationpreview.h"
 #include "llimview.h"
 #include "lllineeditor.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llspinctrl.h"
 #include "lltrans.h"
 
@@ -149,7 +149,7 @@ void LLFloaterConversationPreview::showHistory()
 		}
 		else if (from_id.isNull())
 		{
-			chat.mSourceType = LLNearbyChat::isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
+			chat.mSourceType = LLFloaterIMNearbyChat::isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
 		}
 
 		mChatHistory->appendMessage(chat);
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
new file mode 100644
index 0000000000..b20d19d0fd
--- /dev/null
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -0,0 +1,1557 @@
+/** 
+ * @file llfloaterimcontainer.cpp
+ * @brief Multifloater containing active IM sessions in separate tab container tabs
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
+
+#include "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "llfloaterimnearbychat.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llavatarnamecache.h"
+#include "llcallbacklist.h"
+#include "llgroupactions.h"
+#include "llgroupiconctrl.h"
+#include "llfloateravatarpicker.h"
+#include "llfloaterpreference.h"
+#include "llimview.h"
+#include "llnotificationsutil.h"
+#include "lltransientfloatermgr.h"
+#include "llviewercontrol.h"
+#include "llconversationview.h"
+#include "llcallbacklist.h"
+#include "llworld.h"
+
+#include "llsdserialize.h"
+//
+// LLFloaterIMContainer
+//
+LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed)
+:	LLMultiFloater(seed),
+	mExpandCollapseBtn(NULL),
+	mConversationsRoot(NULL),
+	mConversationsEventStream("ConversationsEvents"),
+	mInitialized(false)
+{
+    mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
+	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction,  this, _2));
+	
+    mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMContainer::checkContextMenuItem,	this, _2));
+    mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem,	this, _2));
+    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelected, this, _2));
+    
+    mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelectedGroup, this, _2));
+
+	// Firstly add our self to IMSession observers, so we catch session events
+    LLIMMgr::getInstance()->addSessionObserver(this);
+
+	mAutoResize = FALSE;
+	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+}
+
+LLFloaterIMContainer::~LLFloaterIMContainer()
+{
+	mConversationsEventStream.stopListening("ConversationsRefresh");
+
+	gIdleCallbacks.deleteFunction(idle, this);
+
+	mNewMessageConnection.disconnect();
+	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
+
+	gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed());
+	gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
+
+	if (!LLSingleton<LLIMMgr>::destroyed())
+	{
+		LLIMMgr::getInstance()->removeSessionObserver(this);
+	}
+}
+
+void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+	addConversationListItem(session_id);
+	LLFloaterIMSessionTab::addToHost(session_id);
+}
+
+void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+    selectConversation(session_id);
+}
+
+void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
+{
+	addConversationListItem(session_id);
+	LLFloaterIMSessionTab::addToHost(session_id);
+}
+
+void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+	// *TODO: We should do this *without* delete and recreate
+	addConversationListItem(new_session_id, removeConversationListItem(old_session_id));
+}
+
+void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id)
+{
+	removeConversationListItem(session_id);
+}
+
+// static
+void LLFloaterIMContainer::onCurrentChannelChanged(const LLUUID& session_id)
+{
+    if (session_id != LLUUID::null)
+    {
+    	LLFloaterIMContainer::getInstance()->showConversation(session_id);
+    }
+}
+
+
+BOOL LLFloaterIMContainer::postBuild()
+{
+	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLFloaterIMContainer::onNewMessageReceived, this, _1));
+	// Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
+	// mTabContainer will be initialized in LLMultiFloater::addChild()
+	
+	setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
+
+	mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
+	mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel");
+	mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel");
+	
+	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
+
+	// Open IM session with selected participant on double click event
+	mConversationsListPanel->setDoubleClickCallback(boost::bind(&LLFloaterIMContainer::doToSelected, this, LLSD("im")));
+
+	// Create the root model and view for all conversation sessions
+	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
+
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    p.name = getName();
+    p.title = getLabel();
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mConversationsListPanel;
+    p.tool_tip = p.name;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
+    p.use_ellipses = true;
+    p.options_menu = "menu_conversation.xml";
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+
+	// Add listener to conversation model events
+	mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1));
+
+	// a scroller for folder view
+	LLRect scroller_view_rect = mConversationsListPanel->getRect();
+	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
+	scroller_params.rect(scroller_view_rect);
+
+	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+	scroller->setFollowsAll();
+	mConversationsListPanel->addChild(scroller);
+	scroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(scroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+
+	addConversationListItem(LLUUID()); // manually add nearby chat
+
+	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onExpandCollapseButtonClicked, this));
+
+	childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this));
+
+	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
+	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
+	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
+
+	if (! mMessagesPane->isCollapsed())
+	{
+		S32 list_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
+		LLRect list_size = mConversationsPane->getRect();
+        S32 left_pad = mConversationsListPanel->getRect().mLeft;
+		list_size.mRight = list_size.mLeft + list_width - left_pad;
+
+        mConversationsPane->handleReshape(list_size, TRUE);
+	}
+
+	// Init the sort order now that the root had been created
+	setSortOrder(LLConversationSort(gSavedSettings.getU32("ConversationSortOrder")));
+	
+	mInitialized = true;
+
+	// Add callbacks:
+	// We'll take care of view updates on idle
+	gIdleCallbacks.addFunction(idle, this);
+	// When display name option change, we need to reload all participant names
+	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));
+
+	return TRUE;
+}
+
+void LLFloaterIMContainer::onOpen(const LLSD& key)
+{
+	LLMultiFloater::onOpen(key);
+	openNearbyChat();
+}
+
+// virtual
+void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
+									  BOOL select_added_floater,
+									  LLTabContainer::eInsertionPoint insertion_point)
+{
+	if(!floaterp) return;
+
+	// already here
+	if (floaterp->getHost() == this)
+	{
+		openFloater(floaterp->getKey());
+		return;
+	}
+	
+	// Make sure the message panel is open when adding a floater or it stays mysteriously hidden
+	collapseMessagesPane(false);
+
+	// Add the floater
+	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
+
+	LLUUID session_id = floaterp->getKey();
+	
+	LLIconCtrl* icon = 0;
+
+	if(gAgent.isInGroup(session_id, TRUE))
+	{
+		LLGroupIconCtrl::Params icon_params;
+		icon_params.group_id = session_id;
+		icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
+
+		mSessions[session_id] = floaterp;
+		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
+	}
+	else
+	{   LLUUID avatar_id = session_id.notNull()?
+		    LLIMModel::getInstance()->getOtherParticipantID(session_id) : LLUUID();
+
+		LLAvatarIconCtrl::Params icon_params;
+		icon_params.avatar_id = avatar_id;
+		icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
+
+		mSessions[session_id] = floaterp;
+		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
+	}
+
+	// forced resize of the floater
+	LLRect wrapper_rect = this->mTabContainer->getLocalRect();
+	floaterp->setRect(wrapper_rect);
+
+	mTabContainer->setTabImage(floaterp, icon);
+}
+
+
+void LLFloaterIMContainer::onCloseFloater(LLUUID& id)
+{
+	mSessions.erase(id);
+	setFocus(TRUE);
+}
+
+// virtual
+void LLFloaterIMContainer::computeResizeLimits(S32& new_min_width, S32& new_min_height)
+{
+	// possibly increase floater's minimum height according to children's minimums
+	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+	{
+		LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getPanelByIndex(tab_idx));
+		if (floaterp)
+		{
+			new_min_height = llmax(new_min_height, floaterp->getMinHeight());
+		}
+	}
+
+	S32 conversations_pane_min_dim = mConversationsPane->getRelevantMinDim();
+	S32 messages_pane_min_dim = mMessagesPane->getRelevantMinDim();
+
+	// set floater's minimum width according to relevant minimal children's dimensionals
+	new_min_width = conversations_pane_min_dim + messages_pane_min_dim + LLPANEL_BORDER_WIDTH*2;
+}
+
+void LLFloaterIMContainer::onNewMessageReceived(const LLSD& data)
+{
+	LLUUID session_id = data["session_id"].asUUID();
+	LLFloater* floaterp = get_ptr_in_map(mSessions, session_id);
+	LLFloater* current_floater = LLMultiFloater::getActiveFloater();
+
+	if(floaterp && current_floater && floaterp != current_floater)
+	{
+		if(LLMultiFloater::isFloaterFlashing(floaterp))
+			LLMultiFloater::setFloaterFlashing(floaterp, FALSE);
+		LLMultiFloater::setFloaterFlashing(floaterp, TRUE);
+	}
+}
+
+void LLFloaterIMContainer::onExpandCollapseButtonClicked()
+{
+	if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()
+			&& gSavedPerAccountSettings.getBOOL("ConversationsExpandMessagePaneFirst"))
+	{
+		// Expand the messages pane from ultra minimized state
+		// if it was collapsed last in order.
+		collapseMessagesPane(false);
+	}
+	else
+	{
+		collapseConversationsPane(!mConversationsPane->isCollapsed());
+	}
+	selectConversation(mSelectedSession);
+}
+
+LLFloaterIMContainer* LLFloaterIMContainer::findInstance()
+{
+	return LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
+}
+
+LLFloaterIMContainer* LLFloaterIMContainer::getInstance()
+{
+	return LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+}
+
+// Update all participants in the conversation lists
+void LLFloaterIMContainer::processParticipantsStyleUpdate()
+{
+	// On each session in mConversationsItems
+	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	{
+		// Get the current session descriptors
+		LLConversationItem* session_model = it_session->second;
+		// Iterate through each model participant child
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+			// Get the avatar name for this participant id from the cache and update the model
+			participant_model->fetchAvatarName();
+			// Next participant
+			current_participant_model++;
+		}
+	}
+}
+
+// static
+void LLFloaterIMContainer::idle(void* user_data)
+{
+	LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data);
+	
+	// Update the distance to agent in the nearby chat session if required
+	// Note: it makes no sense of course to update the distance in other session
+	if (self->mConversationViewModel.getSorter().getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE)
+	{
+		self->setNearbyDistances();
+	}
+	self->mConversationsRoot->update();
+}
+
+bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
+{
+	// For debug only
+	//std::ostringstream llsd_value;
+	//llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
+	//llinfos << "LLFloaterIMContainer::onConversationModelEvent, event = " << llsd_value.str() << llendl;
+	// end debug
+	
+	// Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
+	// the model could change substantially and the view could echo only a portion of this model (though currently the 
+	// conversation view does echo the conversation model 1 to 1).
+	// Consequently, the participant views need to be created either by the session view or by the container panel.
+	// For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp 
+	// (see LLInventoryPanel::buildNewViews()).
+
+	std::string type = event.get("type").asString();
+	LLUUID session_id = event.get("session_uuid").asUUID();
+	LLUUID participant_id = event.get("participant_uuid").asUUID();
+
+	LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,session_id));
+	if (!session_view)
+	{
+		// We skip events that are not associated with a session
+		return false;
+	}
+	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+    LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id)));
+
+	if (type == "remove_participant")
+	{
+		// Remove a participant view from the hierarchical conversation list
+		if (participant_view)
+		{
+			session_view->extractItem(participant_view);
+			delete participant_view;
+			session_view->refresh();
+			mConversationsRoot->arrangeAll();
+		}
+		// Remove a participant view from the conversation floater 
+		if (conversation_floater)
+		{
+			conversation_floater->removeConversationViewParticipant(participant_id);
+		}
+	}
+	else if (type == "add_participant")
+	{
+		LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
+		LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL);
+		if (!participant_view && session_model && participant_model)
+		{
+			LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);
+			if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType()))
+			{
+				participant_view = createConversationViewParticipant(participant_model);
+				participant_view->addToFolder(session_view);
+				participant_view->setVisible(TRUE);
+			}
+		}
+		// Add a participant view to the conversation floater 
+		if (conversation_floater && participant_model)
+		{
+			conversation_floater->addConversationViewParticipant(participant_model);
+		}
+	}
+	else if (type == "update_participant")
+	{
+		// Update the participant view in the hierarchical conversation list
+		if (participant_view)
+		{
+			participant_view->refresh();
+		}
+		// Update the participant view in the conversation floater 
+		if (conversation_floater)
+		{
+			conversation_floater->updateConversationViewParticipant(participant_id);
+		}
+	}
+	else if (type == "update_session")
+	{
+		session_view->refresh();
+		if (conversation_floater)
+		{
+			conversation_floater->refreshConversation();
+		}
+	}
+	
+	mConversationViewModel.requestSortAll();
+	mConversationsRoot->arrangeAll();
+	
+	return false;
+}
+
+void LLFloaterIMContainer::draw()
+{
+	if (mTabContainer->getTabCount() == 0)
+	{
+		// Do not close the container when every conversation is torn off because the user
+		// still needs the conversation list. Simply collapse the message pane in that case.
+		collapseMessagesPane(true);
+	}
+	LLFloater::draw();
+}
+
+void LLFloaterIMContainer::tabClose()
+{
+	if (mTabContainer->getTabCount() == 0)
+	{
+		// Do not close the container when every conversation is torn off because the user
+		// still needs the conversation list. Simply collapse the message pane in that case.
+		collapseMessagesPane(true);
+	}
+}
+
+void LLFloaterIMContainer::setVisible(BOOL visible)
+{	LLFloaterIMNearbyChat* nearby_chat;
+	if (visible)
+	{
+		// Make sure we have the Nearby Chat present when showing the conversation container
+		nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+		if (nearby_chat == NULL)
+		{
+			// If not found, force the creation of the nearby chat conversation panel
+			// *TODO: find a way to move this to XML as a default panel or something like that
+			LLSD name("nearby_chat");
+			LLFloaterReg::toggleInstanceOrBringToFront(name);
+		}
+		openNearbyChat();
+	}
+
+	nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
+	{
+		LLFloaterIMSessionTab::addToHost(LLUUID());
+	}
+
+	// We need to show/hide all the associated conversations that have been torn off
+	// (and therefore, are not longer managed by the multifloater),
+	// so that they show/hide with the conversations manager.
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+		    widget->setVisibleIfDetached(visible);
+		}
+	}
+	
+	// Now, do the normal multifloater show/hide
+	LLMultiFloater::setVisible(visible);
+	
+}
+
+void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
+{
+	if (mMessagesPane->isCollapsed() == collapse)
+	{
+		return;
+	}
+
+	if (collapse)
+	{
+		// Save the messages pane width before collapsing it.
+		gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", mMessagesPane->getRect().getWidth());
+
+		// Save the order in which the panels are closed to reverse user's last action.
+		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
+	}
+
+	// Save left pane rectangle before collapsing/expanding right pane.
+	LLRect prevRect = mConversationsPane->getRect();
+
+	// Show/hide the messages pane.
+	mConversationsStack->collapsePanel(mMessagesPane, collapse);
+
+	if (!collapse)
+	{
+		// Make sure layout is updated before resizing conversation pane.
+		mConversationsStack->updateLayout();
+	}
+
+	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+	if (!collapse)
+	{
+		// Restore conversation's pane previous width after expanding messages pane.
+		mConversationsPane->setTargetDim(prevRect.getWidth());
+	}
+}
+void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
+{
+	if (mConversationsPane->isCollapsed() == collapse)
+	{
+		return;
+	}
+
+	LLView* button_panel = getChild<LLView>("conversations_pane_buttons_expanded");
+	button_panel->setVisible(!collapse);
+	mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon"));
+
+	if (collapse)
+	{
+		// Save the conversations pane width before collapsing it.
+		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", mConversationsPane->getRect().getWidth());
+
+		// Save the order in which the panels are closed to reverse user's last action.
+		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", !mMessagesPane->isCollapsed());
+	}
+
+	mConversationsStack->collapsePanel(mConversationsPane, collapse);
+
+	S32 collapsed_width = mConversationsPane->getMinDim();
+	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - collapsed_width);
+
+	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+			widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+		    widget->toggleMinimizedMode(collapse);
+
+		    // force closing all open conversations when collapsing to minimized state
+		    if (collapse)
+		    {
+		    	widget->setOpen(false);
+		    }
+}
+	}
+}
+
+void LLFloaterIMContainer::updateState(bool collapse, S32 delta_width)
+{
+	LLRect floater_rect = getRect();
+	floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
+
+	// Set by_user = true so that reshaped rect is saved in user_settings.
+	setShape(floater_rect, true);
+
+	updateResizeLimits();
+
+	bool is_left_pane_expanded = !mConversationsPane->isCollapsed();
+	bool is_right_pane_expanded = !mMessagesPane->isCollapsed();
+
+	setCanResize(is_left_pane_expanded || is_right_pane_expanded);
+	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
+
+    // force set correct size for the title after show/hide minimize button
+	LLRect cur_rect = getRect();
+	LLRect force_rect = cur_rect;
+	force_rect.mRight = cur_rect.mRight + 1;
+    setRect(force_rect);
+    setRect(cur_rect);
+
+    // restore floater's resize limits (prevent collapse when left panel is expanded)
+	if (is_left_pane_expanded && !is_right_pane_expanded)
+	{
+		S32 expanded_min_size = mConversationsPane->getExpandedMinDim();
+        setResizeLimits(expanded_min_size, expanded_min_size);
+	}
+
+}
+
+void LLFloaterIMContainer::onAddButtonClicked()
+{
+    LLView * button = findChild<LLView>("conversations_pane_buttons_expanded")->findChild<LLButton>("add_btn");
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE, root_floater->getName(), button);
+    
+    if (picker && root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
+}
+
+void LLFloaterIMContainer::onAvatarPicked(const uuid_vec_t& ids)
+{
+    if (ids.size() == 1)
+    {
+        LLAvatarActions::startIM(ids.back());
+    }
+    else
+    {
+        LLAvatarActions::startConference(ids);
+    }
+}
+
+void LLFloaterIMContainer::onCustomAction(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+
+	if ("sort_sessions_by_type" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_SESSION_TYPE);
+	}
+	if ("sort_sessions_by_name" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_NAME);
+	}
+	if ("sort_sessions_by_recent" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_name" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_NAME);
+	}
+	if ("sort_participants_by_recent" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_distance" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_DISTANCE);
+	}
+	if ("chat_preferences" == command)
+	{
+		LLFloaterPreference* floater_prefs = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+		if (floater_prefs)
+		{
+			LLTabContainer* tab_container = floater_prefs->getChild<LLTabContainer>("pref core");
+			LLPanel* chat_panel = tab_container->getPanelByName("chat");
+			if (tab_container && chat_panel)
+			{
+				tab_container->selectTabPanel(chat_panel);
+			}
+		}
+	}
+}
+
+BOOL LLFloaterIMContainer::isActionChecked(const LLSD& userdata)
+{
+	LLConversationSort order = mConversationViewModel.getSorter();
+	std::string command = userdata.asString();
+	if ("sort_sessions_by_type" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_SESSION_TYPE);
+	}
+	if ("sort_sessions_by_name" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_NAME);
+	}
+	if ("sort_sessions_by_recent" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_name" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_NAME);
+	}
+	if ("sort_participants_by_recent" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_distance" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE);
+	}
+	
+	return FALSE;
+}
+
+void LLFloaterIMContainer::setSortOrderSessions(const LLConversationFilter::ESortOrderType order)
+{
+	LLConversationSort old_order = mConversationViewModel.getSorter();
+	if (order != old_order.getSortOrderSessions())
+	{
+		old_order.setSortOrderSessions(order);
+		setSortOrder(old_order);
+	}
+}
+
+void LLFloaterIMContainer::setSortOrderParticipants(const LLConversationFilter::ESortOrderType order)
+{
+	LLConversationSort old_order = mConversationViewModel.getSorter();
+	if (order != old_order.getSortOrderParticipants())
+	{
+		old_order.setSortOrderParticipants(order);
+		setSortOrder(old_order);
+	}
+}
+
+void LLFloaterIMContainer::setSortOrder(const LLConversationSort& order)
+{
+	mConversationViewModel.setSorter(order);
+	mConversationsRoot->arrangeAll();
+	// try to keep selection onscreen, even if it wasn't to start with
+	mConversationsRoot->scrollToShowSelection();
+	
+	// Notify all conversation (torn off or not) of the change to the sort order
+	// Note: For the moment, the sort order is *unique* across all conversations. That might change in the future.
+	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	{
+		LLUUID session_id = it_session->first;
+		LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id)));
+		if (conversation_floater)
+		{
+			conversation_floater->setSortOrder(order);
+		}
+	}
+	
+	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
+}
+
+void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
+{
+    const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList();
+
+    std::set<LLFolderViewItem*>::const_iterator it = selectedItems.begin();
+    const std::set<LLFolderViewItem*>::const_iterator it_end = selectedItems.end();
+    LLConversationItem * conversationItem;
+
+    for (; it != it_end; ++it)
+    {
+        conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem());
+        selected_uuids.push_back(conversationItem->getUUID());
+    }
+}
+
+const LLConversationItem * LLFloaterIMContainer::getCurSelectedViewModelItem()
+{
+    LLConversationItem * conversationItem = NULL;
+
+    if(mConversationsRoot && 
+        mConversationsRoot->getCurSelectedItem() && 
+        mConversationsRoot->getCurSelectedItem()->getViewModelItem())
+    {
+        conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
+    }
+
+    return conversationItem;
+}
+
+void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
+{
+    //Find the conversation floater associated with the selected id
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+
+    if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
+    {
+        getSelectedUUIDs(selected_uuids);
+    }
+    //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
+    else if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+    {
+        LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(conversationItem->getUUID());
+        LLUUID participantID = conversationFloater->getOtherParticipantUUID();
+        selected_uuids.push_back(participantID);
+    }    
+}
+
+void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
+{
+	if(selectedIDS.size() > 0)
+	{
+		const LLUUID& userID = selectedIDS.front();
+		if(gAgent.getID() != userID)
+		{
+			if ("view_profile" == command)
+			{
+				LLAvatarActions::showProfile(userID);
+			}
+			else if("im" == command)
+			{
+				LLAvatarActions::startIM(userID);
+			}
+			else if("offer_teleport" == command)
+			{
+				LLAvatarActions::offerTeleport(selectedIDS);
+			}
+			else if("voice_call" == command)
+			{
+				LLAvatarActions::startCall(userID);
+			}
+			else if("chat_history" == command)
+			{
+				LLAvatarActions::viewChatHistory(userID);
+			}
+			else if("add_friend" == command)
+			{
+				LLAvatarActions::requestFriendshipDialog(userID);
+			}
+			else if("remove_friend" == command)
+			{
+				LLAvatarActions::removeFriendDialog(userID);
+			}
+			else if("invite_to_group" == command)
+			{
+				LLAvatarActions::inviteToGroup(userID);
+			}
+			else if("map" == command)
+			{
+				LLAvatarActions::showOnMap(userID);
+			}
+			else if("share" == command)
+			{
+				LLAvatarActions::share(userID);
+			}
+			else if("pay" == command)
+			{
+				LLAvatarActions::pay(userID);
+			}
+			else if("block_unblock" == command)
+			{
+				LLAvatarActions::toggleBlock(userID);
+			}
+			else if("selected" == command || "mute_all" == command || "unmute_all" == command)
+			{
+				moderateVoice(command, userID);
+			}
+			else if ("toggle_allow_text_chat" == command)
+			{
+				toggleAllowTextChat(userID);
+			}
+		}
+	}
+}
+
+void LLFloaterIMContainer::doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS)
+{
+    //Find the conversation floater associated with the selected id
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+    LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(conversationItem->getUUID());
+
+    if(conversationFloater)
+    {
+        //Close the selected conversation
+        if("close_conversation" == command)
+        {
+            LLFloater::onClickClose(conversationFloater);
+        }
+        else if("open_voice_conversation" == command)
+        {
+            gIMMgr->startCall(conversationItem->getUUID());
+        }
+        else if("disconnect_from_voice" == command)
+        {
+            gIMMgr->endCall(conversationItem->getUUID());
+        }
+        else if("chat_history" == command)
+        {
+			const LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(conversationItem->getUUID());
+
+			if (NULL != session)
+			{
+				const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
+				LLFloaterReg::showInstance("preview_conversation", session_id, true);
+			}
+        }
+        else
+        {
+            doToParticipants(command, selectedIDS);
+        }
+    }
+}
+
+void LLFloaterIMContainer::doToSelected(const LLSD& userdata)
+{
+    std::string command = userdata.asString();
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+    uuid_vec_t selected_uuids;
+
+    if(conversationItem != NULL)
+    {
+    	getParticipantUUIDs(selected_uuids);
+
+    	if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
+    	{
+    		doToParticipants(command, selected_uuids);
+    	}
+    	else
+    	{
+    		doToSelectedConversation(command, selected_uuids);
+    	}
+    }
+}
+
+void LLFloaterIMContainer::doToSelectedGroup(const LLSD& userdata)
+{
+    std::string action = userdata.asString();
+    LLUUID selected_group = getCurSelectedViewModelItem()->getUUID();
+
+    if (action == "group_profile")
+    {
+        LLGroupActions::show(selected_group);
+    }
+    else if (action == "activate_group")
+    {
+        LLGroupActions::activate(selected_group);
+    }
+    else if (action == "leave_group")
+    {
+        LLGroupActions::leave(selected_group);
+    }
+}
+
+bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
+{
+    std::string item = userdata.asString();
+	uuid_vec_t uuids;
+	getParticipantUUIDs(uuids);
+
+    if(item == std::string("can_activate_group"))
+    {
+    	LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
+    	return gAgent.getGroupID() != selected_group_id;
+    }
+
+	if(uuids.size() <= 0)
+    {
+        return false;
+    }
+
+    // Note: can_block and can_delete is used only for one person selected menu
+    // so we don't need to go over all uuids.
+
+    if (item == std::string("can_block"))
+    {
+		const LLUUID& id = uuids.front();
+        return LLAvatarActions::canBlock(id);
+    }
+    else if (item == std::string("can_add"))
+    {
+        // We can add friends if:
+        // - there are selected people
+        // - and there are no friends among selection yet.
+
+        //EXT-7389 - disable for more than 1
+		if(uuids.size() > 1)
+        {
+            return false;
+        }
+
+        bool result = true;
+
+        uuid_vec_t::const_iterator
+			id = uuids.begin(),
+			uuids_end = uuids.end();
+
+        for (;id != uuids_end; ++id)
+        {
+            if ( LLAvatarActions::isFriend(*id) )
+            {
+                result = false;
+                break;
+            }
+        }
+
+        return result;
+    }
+    else if (item == std::string("can_delete"))
+    {
+        // We can remove friends if:
+        // - there are selected people
+        // - and there are only friends among selection.
+
+        bool result = (uuids.size() > 0);
+
+        uuid_vec_t::const_iterator
+			id = uuids.begin(),
+			uuids_end = uuids.end();
+
+        for (;id != uuids_end; ++id)
+        {
+            if ( !LLAvatarActions::isFriend(*id) )
+            {
+                result = false;
+                break;
+            }
+        }
+
+        return result;
+    }
+    else if (item == std::string("can_call"))
+    {
+        return LLAvatarActions::canCall();
+    }
+    else if (item == std::string("can_show_on_map"))
+    {
+		const LLUUID& id = uuids.front();
+
+        return (LLAvatarTracker::instance().isBuddyOnline(id) && is_agent_mappable(id))
+            || gAgent.isGodlike();
+    }
+    else if(item == std::string("can_offer_teleport"))
+    {
+		return LLAvatarActions::canOfferTeleport(uuids);
+    }
+	else if("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item)
+	{
+		return enableModerateContextMenuItem(item);
+	}
+
+    return false;
+}
+
+bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata)
+{
+    std::string item = userdata.asString();
+    uuid_vec_t mUUIDs;
+    getParticipantUUIDs(mUUIDs);
+
+    if(mUUIDs.size() > 0 )
+    {
+		if ("is_blocked" == item)
+		{
+			return LLAvatarActions::isBlocked(mUUIDs.front());
+		}
+		else if ("is_allowed_text_chat" == item)
+		{
+			const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+
+			if (NULL != speakerp)
+			{
+				return !speakerp->mModeratorMutedText;
+			}
+		}
+    }
+
+    return false;
+}
+
+void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
+{
+    setVisibleAndFrontmost(false);
+    selectConversation(session_id);    
+}
+
+// Will select only the conversation item
+void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
+{
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
+	if (widget)
+	{
+		(widget->getRoot())->setSelection(widget, FALSE, FALSE);
+	}
+}
+
+// Synchronous select the conversation item and the conversation floater
+BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
+{
+    BOOL handled = TRUE;
+
+    /* widget processing */
+    if (select_widget)
+    {
+    	LLFolderViewItem* widget = mConversationsWidgets[session_id];
+    	if (widget && widget->getParentFolder())
+    	{
+    		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
+    	}
+    }
+
+    /* floater processing */
+
+    if (session_id != getSelectedSession())
+    {
+        // Store the active session
+        setSelectedSession(session_id);
+
+		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+
+		if (session_floater->getHost())
+		{
+			// Always expand the message pane if the panel is hosted by the container
+			collapseMessagesPane(false);
+			// Switch to the conversation floater that is being selected
+			selectFloater(session_floater);
+		}
+
+		// Set the focus on the selected floater
+		if (!session_floater->hasFocus())
+		{
+			session_floater->setFocus(TRUE);
+		}
+    }
+
+    return handled;
+}
+
+void LLFloaterIMContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
+{
+	LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
+	if (item)
+	{
+		item->setTimeNow(participant_id);
+		mConversationViewModel.requestSortAll();
+		mConversationsRoot->arrangeAll();
+	}
+}
+
+void LLFloaterIMContainer::setNearbyDistances()
+{
+	// Get the nearby chat session: that's the one with uuid nul
+	LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,LLUUID()));
+	if (item)
+	{
+		// Get the positions of the nearby avatars and their ids
+		std::vector<LLVector3d> positions;
+		uuid_vec_t avatar_ids;
+		LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+		// Get the position of the agent
+		const LLVector3d& me_pos = gAgent.getPositionGlobal();
+		// For each nearby avatar, compute and update the distance
+		int avatar_count = positions.size();
+		for (int i = 0; i < avatar_count; i++)
+		{
+			F64 dist = dist_vec_squared(positions[i], me_pos);
+			item->setDistance(avatar_ids[i],dist);
+		}
+		// Also does it for the agent itself
+		item->setDistance(gAgent.getID(),0.0f);
+		// Request resort
+		mConversationViewModel.requestSortAll();
+		mConversationsRoot->arrangeAll();
+	}
+}
+
+LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
+{
+	bool is_nearby_chat = uuid.isNull();
+
+    // Stores the display name for the conversation line item
+	std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatLabel") : LLIMModel::instance().getName(uuid);
+
+	// Check if the item is not already in the list, exit (nothing to do)
+	// Note: this happens often, when reattaching a torn off conversation for instance
+	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
+	if (item_it != mConversationsItems.end())
+	{
+		return item_it->second;
+	}
+
+	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
+	// and nothing wrong will happen removing it if it doesn't exist
+	removeConversationListItem(uuid,false);
+
+	// Create a conversation session model
+	LLConversationItemSession* item = NULL;
+	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
+	if (speaker_manager)
+	{
+		item = new LLParticipantList(speaker_manager, getRootViewModel());
+	}
+	if (!item)
+	{
+		llwarns << "Couldn't create conversation session item : " << display_name << llendl;
+		return NULL;
+	}
+	item->renameItem(display_name);
+	item->updateParticipantName(NULL);
+	
+	mConversationsItems[uuid] = item;
+
+	// Create a widget from it
+	LLConversationViewSession* widget = createConversationItemWidget(item);
+	mConversationsWidgets[uuid] = widget;
+
+	// Add a new conversation widget to the root folder of the folder view
+	widget->addToFolder(mConversationsRoot);
+	widget->requestArrange();
+
+	LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(uuid);
+
+	// Create the participants widgets now
+	// Note: usually, we do not get an updated avatar list at that point
+	if (uuid.isNull() || im_sessionp && !im_sessionp->isP2PSessionType())
+	{
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+			LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+			participant_view->addToFolder(widget);
+			current_participant_model++;
+		}
+	}
+	// Do that too for the conversation dialog
+    LLFloaterIMSessionTab *conversation_floater = (uuid.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(uuid)));
+	if (conversation_floater)
+	{
+		conversation_floater->buildConversationViewParticipant();
+	}
+
+	// set the widget to minimized mode if conversations pane is collapsed
+	widget->toggleMinimizedMode(mConversationsPane->isCollapsed());
+
+    if (isWidgetSelected)
+    {
+        selectConversation(uuid);
+        // scroll to newly added item
+        mConversationsRoot->scrollToShowSelection();
+    }
+
+	return item;
+}
+
+bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
+{
+	// Delete the widget and the associated conversation item
+	// Note : since the mConversationsItems is also the listener to the widget, deleting 
+	// the widget will also delete its listener
+	bool isWidgetSelected = false;
+	LLFolderViewItem* new_selection = NULL;
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+	if (widget)
+	{
+		isWidgetSelected = widget->isSelected();
+		new_selection = mConversationsRoot->getNextFromChild(widget);
+		if(new_selection == NULL)
+		{
+			new_selection = mConversationsRoot->getPreviousFromChild(widget);
+		}
+		widget->destroyView();
+	}
+	
+	// Suppress the conversation items and widgets from their respective maps
+	mConversationsItems.erase(uuid);
+	mConversationsWidgets.erase(uuid);
+	
+	// Don't let the focus fall IW, select and refocus on the first conversation in the list
+	if (change_focus)
+	{
+		setFocus(TRUE);
+		if(new_selection != NULL)
+		{
+			LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+			if(vmi != NULL)
+			{
+				selectConversation(vmi->getUUID());
+			}
+		}
+	}
+	return isWidgetSelected;
+}
+
+LLConversationViewSession* LLFloaterIMContainer::createConversationItemWidget(LLConversationItem* item)
+{
+	LLConversationViewSession::Params params;
+	
+	params.name = item->getDisplayName();
+	params.root = mConversationsRoot;
+	params.listener = item;
+	params.tool_tip = params.name;
+	params.container = this;
+	
+	return LLUICtrlFactory::create<LLConversationViewSession>(params);
+}
+
+LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParticipant(LLConversationItem* item)
+{
+	LLConversationViewParticipant::Params params;
+    LLRect panel_rect = mConversationsListPanel->getRect();
+	
+	params.name = item->getDisplayName();
+	params.root = mConversationsRoot;
+	params.listener = item;
+
+    //24 is the the current hight of an item (itemHeight) loaded from conversation_view_participant.xml.
+	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
+	params.tool_tip = params.name;
+	params.participant_id = item->getUUID();
+    params.folder_indentation = 42;
+
+	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
+bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata)
+{
+	// only group moderators can perform actions related to this "enable callback"
+	if (!isGroupModerator())
+	{
+		return false;
+	}
+
+	LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+	if (NULL == speakerp)
+	{
+		return false;
+	}
+
+	bool voice_channel = speakerp->isInVoiceChannel();
+
+	if ("can_moderate_voice" == userdata)
+	{
+		return voice_channel;
+	}
+	else if ("can_mute" == userdata)
+	{
+		return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+	else if ("can_unmute" == userdata)
+	{
+		return voice_channel && isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+
+	// The last invoke is used to check whether the "can_allow_text_chat" will enabled
+	return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
+}
+
+bool LLFloaterIMContainer::isGroupModerator()
+{
+	LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant();
+	if (NULL == speaker_manager)
+	{
+		llwarns << "Speaker manager is missing" << llendl;
+		return false;
+	}
+
+	// Is session a group call/chat?
+	if(gAgent.isInGroup(speaker_manager->getSessionID()))
+	{
+		LLSpeaker * speaker = speaker_manager->findSpeaker(gAgentID).get();
+
+		// Is agent a moderator?
+		return speaker && speaker->mIsModerator;
+	}
+
+	return false;
+}
+
+void LLFloaterIMContainer::moderateVoice(const std::string& command, const LLUUID& userID)
+{
+	if (!gAgent.getRegion()) return;
+
+	if (command.compare("selected"))
+	{
+		moderateVoiceAllParticipants(command.compare("mute_all"));
+	}
+	else
+	{
+		moderateVoiceParticipant(userID, isMuted(userID));
+	}
+}
+
+bool LLFloaterIMContainer::isMuted(const LLUUID& avatar_id)
+{
+	const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+	return NULL == speakerp ? true : speakerp->mStatus == LLSpeaker::STATUS_MUTED;
+}
+
+void LLFloaterIMContainer::moderateVoiceAllParticipants(bool unmute)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
+
+	if (NULL != speaker_managerp)
+	{
+		if (!unmute)
+		{
+			LLSD payload;
+			payload["session_id"] = speaker_managerp->getSessionID();
+			LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
+			return;
+		}
+
+		speaker_managerp->moderateVoiceAllParticipants(unmute);
+	}
+}
+
+// static
+void LLFloaterIMContainer::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	// if Cancel pressed
+	if (option == 1)
+	{
+		return;
+	}
+
+	const LLSD& payload = notification["payload"];
+	const LLUUID& session_id = payload["session_id"];
+
+	LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
+		LLIMModel::getInstance()->getSpeakerManager(session_id));
+	if (speaker_manager)
+	{
+		speaker_manager->moderateVoiceAllParticipants(false);
+	}
+
+	return;
+}
+
+void LLFloaterIMContainer::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr *>(getSpeakerMgrForSelectedParticipant());
+
+	if (NULL != speaker_managerp)
+	{
+		speaker_managerp->moderateVoiceParticipant(avatar_id, unmute);
+	}
+}
+
+LLSpeakerMgr * LLFloaterIMContainer::getSpeakerMgrForSelectedParticipant()
+{
+	LLFolderViewItem * selected_folder_itemp = mConversationsRoot->getCurSelectedItem();
+	if (NULL == selected_folder_itemp)
+	{
+		llwarns << "Current selected item is null" << llendl;
+		return NULL;
+	}
+
+	LLFolderViewFolder * conversation_itemp = selected_folder_itemp->getParentFolder();
+
+	conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin();
+	conversations_widgets_map::const_iterator end = mConversationsWidgets.end();
+	const LLUUID * conversation_uuidp = NULL;
+	while(iter != end)
+	{
+		if (iter->second == conversation_itemp)
+		{
+			conversation_uuidp = &iter->first;
+			break;
+		}
+		++iter;
+	}
+	if (NULL == conversation_uuidp)
+	{
+		llwarns << "Cannot find conversation item widget" << llendl;
+		return NULL;
+	}
+
+	return conversation_uuidp->isNull() ? (LLSpeakerMgr *)LLLocalSpeakerMgr::getInstance()
+		: LLIMModel::getInstance()->getSpeakerManager(*conversation_uuidp);
+}
+
+LLSpeaker * LLFloaterIMContainer::getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp)
+{
+	if (NULL == speaker_managerp)
+	{
+		llwarns << "Speaker manager is missing" << llendl;
+		return NULL;
+	}
+
+	const LLConversationItem * participant_itemp = getCurSelectedViewModelItem();
+	if (NULL == participant_itemp)
+	{
+		llwarns << "Cannot evaluate current selected view model item" << llendl;
+		return NULL;
+	}
+
+	return speaker_managerp->findSpeaker(participant_itemp->getUUID());
+}
+
+void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
+	if (NULL != speaker_managerp)
+	{
+		speaker_managerp->toggleAllowTextChat(participant_uuid);
+	}
+}
+
+void LLFloaterIMContainer::openNearbyChat()
+{
+	// If there's only one conversation in the container and that conversation is the nearby chat
+	//(which it should be...), open it so to make the list of participants visible. This happens to be the most common case when opening the Chat floater.
+	if(mConversationsItems.size() == 1)
+	{
+		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[LLUUID()]);
+		if (nearby_chat)
+		{
+			nearby_chat->setOpen(TRUE);
+		}
+	}
+}
+
+void LLFloaterIMContainer::onNearbyChatClosed()
+{
+	// If nearby chat is the only remaining conversation and it is closed, close whole conversation floater as well
+	if (mConversationsItems.size() == 1)
+		closeFloater();
+}
+
+// EOF
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
new file mode 100644
index 0000000000..f65e946dad
--- /dev/null
+++ b/indra/newview/llfloaterimcontainer.h
@@ -0,0 +1,178 @@
+/** 
+ * @file llfloaterimcontainer.h
+ * @brief Multifloater containing active IM sessions in separate tab container tabs
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERIMCONTAINER_H
+#define LL_LLFLOATERIMCONTAINER_H
+
+#include <map>
+#include <vector>
+
+#include "llimview.h"
+#include "llevents.h"
+#include "llfloater.h"
+#include "llmultifloater.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llgroupmgr.h"
+#include "lltrans.h"
+#include "llconversationmodel.h"
+#include "llconversationview.h"
+
+class LLButton;
+class LLLayoutPanel;
+class LLLayoutStack;
+class LLTabContainer;
+class LLFloaterIMContainer;
+class LLSpeaker;
+class LLSpeakerMgr;
+
+class LLFloaterIMContainer
+	: public LLMultiFloater
+	, public LLIMSessionObserver
+{
+public:
+	LLFloaterIMContainer(const LLSD& seed);
+	virtual ~LLFloaterIMContainer();
+	
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void draw();
+	/*virtual*/ void setVisible(BOOL visible);
+	void onCloseFloater(LLUUID& id);
+
+	/*virtual*/ void addFloater(LLFloater* floaterp, 
+								BOOL select_added_floater, 
+								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+    
+    void showConversation(const LLUUID& session_id);
+    void selectConversation(const LLUUID& session_id);
+    BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
+
+	/*virtual*/ void tabClose();
+
+	static LLFloater* getCurrentVoiceFloater();
+	static LLFloaterIMContainer* findInstance();
+	static LLFloaterIMContainer* getInstance();
+
+	static void onCurrentChannelChanged(const LLUUID& session_id);
+
+	void collapseMessagesPane(bool collapse);
+	
+	// Callbacks
+	static void idle(void* user_data);
+
+	// LLIMSessionObserver observe triggers
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
+	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
+	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
+	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
+    LLUUID getSelectedSession() { return mSelectedSession; }
+    void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
+	LLConversationItem* getSessionModel(const LLUUID& session_id) { return get_ptr_in_map(mConversationsItems,session_id); }
+	LLConversationSort& getSortOrder() { return mConversationViewModel.getSorter(); }
+
+	void onNearbyChatClosed();
+
+private:
+	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
+	avatarID_panel_map_t mSessions;
+	boost::signals2::connection mNewMessageConnection;
+
+	/*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height);
+
+	void onNewMessageReceived(const LLSD& data);
+
+	void onExpandCollapseButtonClicked();
+	void processParticipantsStyleUpdate();
+
+	void collapseConversationsPane(bool collapse);
+
+	void updateState(bool collapse, S32 delta_width);
+
+	void onAddButtonClicked();
+	void onAvatarPicked(const uuid_vec_t& ids);
+
+	BOOL isActionChecked(const LLSD& userdata);
+	void onCustomAction (const LLSD& userdata);
+	void setSortOrderSessions(const LLConversationFilter::ESortOrderType order);
+	void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order);
+	void setSortOrder(const LLConversationSort& order);
+
+    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
+    const LLConversationItem * getCurSelectedViewModelItem();
+    void getParticipantUUIDs(uuid_vec_t& selected_uuids);
+    void doToSelected(const LLSD& userdata);
+    void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS);
+    void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
+    void doToSelectedGroup(const LLSD& userdata);
+    bool checkContextMenuItem(const LLSD& userdata);
+    bool enableContextMenuItem(const LLSD& userdata);
+
+	static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
+	bool enableModerateContextMenuItem(const std::string& userdata);
+	LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp);
+	LLSpeakerMgr * getSpeakerMgrForSelectedParticipant();
+	bool isGroupModerator();
+	bool isMuted(const LLUUID& avatar_id);
+	void moderateVoice(const std::string& command, const LLUUID& userID);
+	void moderateVoiceAllParticipants(bool unmute);
+	void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
+	void toggleAllowTextChat(const LLUUID& participant_uuid);
+	void openNearbyChat();
+
+	LLButton* mExpandCollapseBtn;
+	LLLayoutPanel* mMessagesPane;
+	LLLayoutPanel* mConversationsPane;
+	LLLayoutStack* mConversationsStack;
+	
+	bool mInitialized;
+
+	LLUUID mSelectedSession;
+
+	// Conversation list implementation
+public:
+	bool removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
+	LLConversationItem* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
+	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
+	void setNearbyDistances();
+
+private:
+	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
+	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+	bool onConversationModelEvent(const LLSD& event);
+
+	// Conversation list data
+	LLPanel* mConversationsListPanel;	// This is the main widget we add conversation widget to
+	conversations_items_map mConversationsItems;
+	conversations_widgets_map mConversationsWidgets;
+	LLConversationViewModel mConversationViewModel;
+	LLFolderView* mConversationsRoot;
+	LLEventStream mConversationsEventStream; 
+};
+
+#endif // LL_LLFLOATERIMCONTAINER_H
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
new file mode 100644
index 0000000000..5867eb3e84
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -0,0 +1,867 @@
+/** 
+ * @file LLFloaterIMNearbyChat.cpp
+ * @brief LLFloaterIMNearbyChat class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "message.h"
+
+#include "lliconctrl.h"
+#include "llappviewer.h"
+#include "llchatentry.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+#include "llfloaterimcontainer.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfocusmgr.h"
+#include "lllogchat.h"
+#include "llresizebar.h"
+#include "llresizehandle.h"
+#include "lldraghandle.h"
+#include "llmenugl.h"
+#include "llviewermenu.h" // for gMenuHolder
+#include "llfloaterimnearbychathandler.h"
+#include "llchannelmanager.h"
+#include "llchathistory.h"
+#include "llstylemap.h"
+#include "llavatarnamecache.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+
+#include "llfirstuse.h"
+#include "llfloaterimnearbychat.h"
+#include "llagent.h" // gAgent
+#include "llgesturemgr.h"
+#include "llmultigesture.h"
+#include "llkeyboard.h"
+#include "llanimationstates.h"
+#include "llviewerstats.h"
+#include "llcommandhandler.h"
+#include "llviewercontrol.h"
+#include "llnavigationbar.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llrootview.h"
+#include "llviewerchat.h"
+#include "lltranslate.h"
+
+S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0;
+
+const S32 EXPANDED_HEIGHT = 266;
+const S32 COLLAPSED_HEIGHT = 60;
+const S32 EXPANDED_MIN_HEIGHT = 150;
+
+// legacy callback glue
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
+
+struct LLChatTypeTrigger {
+	std::string name;
+	EChatType type;
+};
+
+static LLChatTypeTrigger sChatTypeTriggers[] = {
+	{ "/whisper"	, CHAT_TYPE_WHISPER},
+	{ "/shout"	, CHAT_TYPE_SHOUT}
+};
+
+
+LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd)
+:	LLFloaterIMSessionTab(llsd),
+	//mOutputMonitor(NULL),
+	mSpeakerMgr(NULL),
+	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
+{
+    mIsP2PChat = false;
+	mIsNearbyChat = true;
+	setIsChrome(TRUE);
+	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
+	mSessionID = LLUUID();
+}
+
+//static
+LLFloaterIMNearbyChat* LLFloaterIMNearbyChat::buildFloater(const LLSD& key)
+{
+    LLFloaterReg::getInstance("im_container");
+    return new LLFloaterIMNearbyChat(key);
+}
+
+//virtual
+BOOL LLFloaterIMNearbyChat::postBuild()
+{
+    setIsSingleInstance(TRUE);
+    BOOL result = LLFloaterIMSessionTab::postBuild();
+	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
+	mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
+	mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
+	mInputEditor->setFocusReceivedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusReceived, this));
+	mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle"));
+
+//	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
+//	mOutputMonitor->setVisible(FALSE);
+
+	// Register for font change notifications
+	LLViewerChat::setFontChangedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatFontChange, this, _1));
+
+	// title must be defined BEFORE call addConversationListItem() because
+	// it is used for show the item's name in the conversations list
+	setTitle(LLTrans::getString("NearbyChatTitle"));
+
+	//for menu
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+	enable_registrar.add("NearbyChat.Check", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
+	registrar.add("NearbyChat.Action", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
+
+	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	if(menu)
+	{
+		mPopupMenuHandle = menu->getHandle();
+	}
+
+	// obsolete, but may be needed for backward compatibility?
+	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
+
+	if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
+	{
+		loadHistory();
+	}
+
+	return result;
+}
+
+// virtual
+void LLFloaterIMNearbyChat::refresh()
+{
+	displaySpeakingIndicator();
+	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
+
+	// *HACK: Update transparency type depending on whether our children have focus.
+	// This is needed because this floater is chrome and thus cannot accept focus, so
+	// the transparency type setting code from LLFloater::setFocus() isn't reached.
+	if (getTransparencyType() != TT_DEFAULT)
+	{
+		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
+	}
+}
+
+void LLFloaterIMNearbyChat::onNearbySpeakers()
+{
+	LLSD param;
+	param["people_panel_tab_name"] = "nearby_panel";
+	LLFloaterSidePanelContainer::showPanel("people", "panel_people", param);
+}
+
+void	LLFloaterIMNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
+{
+}
+
+bool	LLFloaterIMNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
+{
+	std::string str = userdata.asString();
+	if(str == "nearby_people")
+		onNearbySpeakers();
+	return false;
+}
+
+
+BOOL	LLFloaterIMNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	//fix for EXT-6625
+	//highlight NearbyChat history whenever mouseclick happen in NearbyChat
+	//setting focus to eidtor will force onFocusLost() call that in its turn will change
+	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
+
+	if(mChatHistory)
+	{
+		mChatHistory->setFocus(TRUE);
+	}
+
+	BOOL handled = LLPanel::handleMouseDown(x, y, mask);
+	setFocus(handled);
+	return handled;
+}
+
+void LLFloaterIMNearbyChat::reloadMessages()
+{
+	mChatHistory->clear();
+
+	LLSD do_not_log;
+	do_not_log["do_not_log"] = true;
+	for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)
+	{
+		// Update the messages without re-writing them to a log file.
+		addMessage(*it,false, do_not_log);
+	}
+}
+
+void LLFloaterIMNearbyChat::loadHistory()
+{
+	LLSD do_not_log;
+	do_not_log["do_not_log"] = true;
+
+	std::list<LLSD> history;
+	LLLogChat::loadChatHistory("chat", history);
+
+	std::list<LLSD>::const_iterator it = history.begin();
+	while (it != history.end())
+	{
+		const LLSD& msg = *it;
+
+		std::string from = msg[IM_FROM];
+		LLUUID from_id;
+		if (msg[IM_FROM_ID].isDefined())
+		{
+			from_id = msg[IM_FROM_ID].asUUID();
+		}
+		else
+ 		{
+			std::string legacy_name = gCacheName->buildLegacyName(from);
+ 			gCacheName->getUUID(legacy_name, from_id);
+ 		}
+
+		LLChat chat;
+		chat.mFromName = from;
+		chat.mFromID = from_id;
+		chat.mText = msg[IM_TEXT].asString();
+		chat.mTimeStr = msg[IM_TIME].asString();
+		chat.mChatStyle = CHAT_STYLE_HISTORY;
+
+		chat.mSourceType = CHAT_SOURCE_AGENT;
+		if (from_id.isNull() && SYSTEM_FROM == from)
+		{
+			chat.mSourceType = CHAT_SOURCE_SYSTEM;
+
+		}
+		else if (from_id.isNull())
+		{
+			chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
+		}
+
+		addMessage(chat, true, do_not_log);
+
+		it++;
+	}
+}
+
+void LLFloaterIMNearbyChat::removeScreenChat()
+{
+	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	if(chat_channel)
+	{
+		chat_channel->removeToastsFromChannel();
+	}
+}
+
+
+void LLFloaterIMNearbyChat::setVisible(BOOL visible)
+{
+	LLFloaterIMSessionTab::setVisible(visible);
+
+	if(visible)
+	{
+		removeScreenChat();
+	}
+    setFocus(visible);
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onTearOffClicked()
+{
+	LLFloaterIMSessionTab::onTearOffClicked();
+
+	// see CHUI-170: Save torn-off state of the nearby chat between sessions
+	BOOL in_the_multifloater = !isTornOff();
+	gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
+}
+
+
+// virtual
+void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
+{
+	LLFloaterIMSessionTab::onOpen(key);
+	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onClose(bool app_quitting)
+{
+	// Override LLFloaterIMSessionTab::onClose() so that Nearby Chat is not removed from the conversation floater
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onClickCloseBtn()
+{
+	if (!isTornOff())
+		return;
+	onTearOffClicked();
+	
+	LLFloaterIMContainer *im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->onNearbyChatClosed();
+	}
+}
+
+void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)
+{
+	// Update things with the new font whohoo
+	if (mInputEditor)
+	{
+		mInputEditor->setFont(fontp);
+	}
+}
+
+
+void LLFloaterIMNearbyChat::show()
+{
+	if (isChatMultiTab())
+	{
+		openFloater(getKey());
+	}
+}
+
+bool LLFloaterIMNearbyChat::isChatVisible() const
+{
+	bool isVisible = false;
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance();
+	// Is the IM floater container ever null?
+	llassert(im_box != NULL);
+	if (im_box != NULL)
+	{
+		isVisible =
+				isChatMultiTab() && gSavedSettings.getBOOL("NearbyChatIsNotTornOff")?
+						im_box->getVisible() && !im_box->isMinimized() :
+						getVisible() && !isMinimized();
+	}
+
+	return isVisible;
+}
+
+void LLFloaterIMNearbyChat::showHistory()
+{
+	openFloater();
+	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
+}
+
+std::string LLFloaterIMNearbyChat::getCurrentChat()
+{
+	return mInputEditor ? mInputEditor->getText() : LLStringUtil::null;
+}
+
+// virtual
+BOOL LLFloaterIMNearbyChat::handleKeyHere( KEY key, MASK mask )
+{
+	BOOL handled = FALSE;
+
+	if( KEY_RETURN == key && mask == MASK_CONTROL)
+	{
+		// shout
+		sendChat(CHAT_TYPE_SHOUT);
+		handled = TRUE;
+	}
+
+	return handled;
+}
+
+BOOL LLFloaterIMNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
+{
+	U32 in_len = in_str.length();
+	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+	
+	bool string_was_found = false;
+
+	for (S32 n = 0; n < cnt && !string_was_found; n++)
+	{
+		if (in_len <= sChatTypeTriggers[n].name.length())
+		{
+			std::string trigger_trunc = sChatTypeTriggers[n].name;
+			LLStringUtil::truncate(trigger_trunc, in_len);
+
+			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+			{
+				*out_str = sChatTypeTriggers[n].name;
+				string_was_found = true;
+			}
+		}
+	}
+
+	return string_was_found;
+}
+
+void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata)
+{
+	LLFirstUse::otherAvatarChatFirst(false);
+
+	LLFloaterIMNearbyChat* self = (LLFloaterIMNearbyChat *)userdata;
+
+	LLWString raw_text = self->mInputEditor->getWText();
+
+	// Can't trim the end, because that will cause autocompletion
+	// to eat trailing spaces that might be part of a gesture.
+	LLWStringUtil::trimHead(raw_text);
+
+	S32 length = raw_text.length();
+
+	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences
+	{
+		gAgent.startTyping();
+	}
+	else
+	{
+		gAgent.stopTyping();
+	}
+
+	/* Doesn't work -- can't tell the difference between a backspace
+	   that killed the selection vs. backspace at the end of line.
+	if (length > 1 
+		&& text[0] == '/'
+		&& key == KEY_BACKSPACE)
+	{
+		// the selection will already be deleted, but we need to trim
+		// off the character before
+		std::string new_text = raw_text.substr(0, length-1);
+		self->mInputEditor->setText( new_text );
+		self->mInputEditor->setCursorToEnd();
+		length = length - 1;
+	}
+	*/
+
+	KEY key = gKeyboard->currentKey();
+
+	// Ignore "special" keys, like backspace, arrows, etc.
+	if (length > 1 
+		&& raw_text[0] == '/'
+		&& key < KEY_SPECIAL)
+	{
+		// we're starting a gesture, attempt to autocomplete
+
+		std::string utf8_trigger = wstring_to_utf8str(raw_text);
+		std::string utf8_out_str(utf8_trigger);
+
+		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
+		{
+			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+			self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+
+			// Select to end of line, starting from the character
+			// after the last one the user typed.
+			self->mInputEditor->selectNext(rest_of_match, false);
+		}
+		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
+		{
+			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+			self->mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
+			self->mInputEditor->endOfDoc();
+		}
+
+		//llinfos << "GESTUREDEBUG " << trigger 
+		//	<< " len " << length
+		//	<< " outlen " << out_str.getLength()
+		//	<< llendl;
+	}
+}
+
+// static
+void LLFloaterIMNearbyChat::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
+{
+	// stop typing animation
+	gAgent.stopTyping();
+}
+
+void LLFloaterIMNearbyChat::onChatBoxFocusReceived()
+{
+	mInputEditor->setEnabled(!gDisconnected);
+}
+
+EChatType LLFloaterIMNearbyChat::processChatTypeTriggers(EChatType type, std::string &str)
+{
+	U32 length = str.length();
+	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+	
+	for (S32 n = 0; n < cnt; n++)
+	{
+		if (length >= sChatTypeTriggers[n].name.length())
+		{
+			std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
+
+			if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
+			{
+				U32 trigger_length = sChatTypeTriggers[n].name.length();
+
+				// It's to remove space after trigger name
+				if (length > trigger_length && str[trigger_length] == ' ')
+					trigger_length++;
+
+				str = str.substr(trigger_length, length);
+
+				if (CHAT_TYPE_NORMAL == type)
+					return sChatTypeTriggers[n].type;
+				else
+					break;
+			}
+		}
+	}
+
+	return type;
+}
+
+void LLFloaterIMNearbyChat::sendChat( EChatType type )
+{
+	if (mInputEditor)
+	{
+		LLWString text = mInputEditor->getWText();
+		LLWStringUtil::trim(text);
+		LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
+		if (!text.empty())
+		{
+			// Check if this is destined for another channel
+			S32 channel = 0;
+			stripChannelNumber(text, &channel);
+			
+			std::string utf8text = wstring_to_utf8str(text);
+			// Try to trigger a gesture, if not chat to a script.
+			std::string utf8_revised_text;
+			if (0 == channel)
+			{
+				// discard returned "found" boolean
+				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
+			}
+			else
+			{
+				utf8_revised_text = utf8text;
+			}
+
+			utf8_revised_text = utf8str_trim(utf8_revised_text);
+
+			type = processChatTypeTriggers(type, utf8_revised_text);
+
+			if (!utf8_revised_text.empty())
+			{
+				// Chat with animation
+				sendChatFromViewer(utf8_revised_text, type, TRUE);
+			}
+		}
+
+		mInputEditor->setText(LLStringExplicit(""));
+	}
+
+	gAgent.stopTyping();
+
+	// If the user wants to stop chatting on hitting return, lose focus
+	// and go out of chat mode.
+	if (gSavedSettings.getBOOL("CloseChatOnReturn"))
+	{
+		stopChat();
+	}
+}
+
+void	LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+{
+	appendMessage(chat, args);
+
+	if(archive)
+	{
+		mMessageArchive.push_back(chat);
+		if(mMessageArchive.size()>200)
+			mMessageArchive.erase(mMessageArchive.begin());
+	}
+
+	// logging
+	if (!args["do_not_log"].asBoolean()
+			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
+	{
+		std::string from_name = chat.mFromName;
+
+		if (chat.mSourceType == CHAT_SOURCE_AGENT)
+		{
+			// if the chat is coming from an agent, log the complete name
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(chat.mFromID, &av_name);
+
+			if (!av_name.mIsDisplayNameDefault)
+			{
+				from_name = av_name.getCompleteName();
+			}
+		}
+
+		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
+	}
+}
+
+
+void LLFloaterIMNearbyChat::onChatBoxCommit()
+{
+	if (mInputEditor->getText().length() > 0)
+	{
+		sendChat(CHAT_TYPE_NORMAL);
+	}
+
+	gAgent.stopTyping();
+}
+
+void LLFloaterIMNearbyChat::displaySpeakingIndicator()
+{
+	LLSpeakerMgr::speaker_list_t speaker_list;
+	LLUUID id;
+
+	id.setNull();
+	mSpeakerMgr->update(TRUE);
+	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
+
+	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
+	{
+		LLPointer<LLSpeaker> s = *i;
+		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
+		{
+			id = s->mID;
+			break;
+		}
+	}
+
+	if (!id.isNull())
+	{
+		//mOutputMonitor->setVisible(TRUE);
+		//mOutputMonitor->setSpeakerId(id);
+	}
+	else
+	{
+		//mOutputMonitor->setVisible(FALSE);
+	}
+}
+
+void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
+{
+	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
+}
+
+void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
+{
+	// Look for "/20 foo" channel chats.
+	S32 channel = 0;
+	LLWString out_text = stripChannelNumber(wtext, &channel);
+	std::string utf8_out_text = wstring_to_utf8str(out_text);
+	std::string utf8_text = wstring_to_utf8str(wtext);
+
+	utf8_text = utf8str_trim(utf8_text);
+	if (!utf8_text.empty())
+	{
+		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
+	}
+
+	// Don't animate for chats people can't hear (chat to scripts)
+	if (animate && (channel == 0))
+	{
+		if (type == CHAT_TYPE_WHISPER)
+		{
+			lldebugs << "You whisper " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
+		}
+		else if (type == CHAT_TYPE_NORMAL)
+		{
+			lldebugs << "You say " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
+		}
+		else if (type == CHAT_TYPE_SHOUT)
+		{
+			lldebugs << "You shout " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
+		}
+		else
+		{
+			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
+			return;
+		}
+	}
+	else
+	{
+		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
+		{
+			lldebugs << "Channel chat: " << utf8_text << llendl;
+		}
+	}
+
+	send_chat_from_viewer(utf8_out_text, type, channel);
+}
+
+// static 
+bool LLFloaterIMNearbyChat::isWordsName(const std::string& name)
+{
+	// checking to see if it's display name plus username in parentheses
+	S32 open_paren = name.find(" (", 0);
+	S32 close_paren = name.find(')', 0);
+
+	if (open_paren != std::string::npos &&
+		close_paren == name.length()-1)
+	{
+		return true;
+	}
+	else
+	{
+		//checking for a single space
+		S32 pos = name.find(' ', 0);
+		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
+	}
+}
+
+// static 
+void LLFloaterIMNearbyChat::startChat(const char* line)
+{
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
+	{
+		nearby_chat->show();
+		nearby_chat->setVisible(TRUE);
+		nearby_chat->setFocus(TRUE);
+		nearby_chat->mInputEditor->setFocus(TRUE);
+
+		if (line)
+		{
+			std::string line_string(line);
+			nearby_chat->mInputEditor->setText(line_string);
+		}
+
+		nearby_chat->mInputEditor->endOfDoc();
+	}
+}
+
+// Exit "chat mode" and do the appropriate focus changes
+// static
+void LLFloaterIMNearbyChat::stopChat()
+{
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
+	{
+		nearby_chat->mInputEditor->setFocus(FALSE);
+	    gAgent.stopTyping();
+	}
+}
+
+// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
+// Otherwise returns input and channel 0.
+LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel)
+{
+	if (mesg[0] == '/'
+		&& mesg[1] == '/')
+	{
+		// This is a "repeat channel send"
+		*channel = sLastSpecialChatChannel;
+		return mesg.substr(2, mesg.length() - 2);
+	}
+	else if (mesg[0] == '/'
+			 && mesg[1]
+			 && LLStringOps::isDigit(mesg[1]))
+	{
+		// This a special "/20" speak on a channel
+		S32 pos = 0;
+
+		// Copy the channel number into a string
+		LLWString channel_string;
+		llwchar c;
+		do
+		{
+			c = mesg[pos+1];
+			channel_string.push_back(c);
+			pos++;
+		}
+		while(c && pos < 64 && LLStringOps::isDigit(c));
+		
+		// Move the pointer forward to the first non-whitespace char
+		// Check isspace before looping, so we can handle "/33foo"
+		// as well as "/33 foo"
+		while(c && iswspace(c))
+		{
+			c = mesg[pos+1];
+			pos++;
+		}
+		
+		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
+		*channel = sLastSpecialChatChannel;
+		return mesg.substr(pos, mesg.length() - pos);
+	}
+	else
+	{
+		// This is normal chat.
+		*channel = 0;
+		return mesg;
+	}
+}
+
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
+{
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_ChatFromViewer);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_ChatData);
+	msg->addStringFast(_PREHASH_Message, utf8_out_text);
+	msg->addU8Fast(_PREHASH_Type, type);
+	msg->addS32("Channel", channel);
+
+	gAgent.sendReliableMessage();
+
+	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+}
+
+class LLChatCommandHandler : public LLCommandHandler
+{
+public:
+	// not allowed from outside the app
+	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
+
+    // Your code here
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLMediaCtrl* web)
+	{
+		bool retval = false;
+		// Need at least 2 tokens to have a valid message.
+		if (tokens.size() < 2)
+		{
+			retval = false;
+		}
+		else
+		{
+		S32 channel = tokens[0].asInteger();
+			// VWR-19499 Restrict function to chat channels greater than 0.
+			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
+			{
+				retval = true;
+		// Send unescaped message, see EXT-6353.
+		std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
+		send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
+			}
+			else
+			{
+				retval = false;
+				// Tell us this is an unsupported SLurl.
+			}
+		}
+		return retval;
+	}
+};
+
+// Creating the object registers with the dispatcher.
+LLChatCommandHandler gChatHandler;
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
new file mode 100644
index 0000000000..1479746fbd
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -0,0 +1,125 @@
+/** 
+ * @file llfloaterimnearbychat.h
+ * @brief LLFloaterIMNearbyChat class definition
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERIMNEARBYCHAT_H
+#define LL_LLFLOATERIMNEARBYCHAT_H
+
+#include "llfloaterimsessiontab.h"
+#include "llcombobox.h"
+#include "llgesturemgr.h"
+#include "llchat.h"
+#include "llvoiceclient.h"
+#include "lloutputmonitorctrl.h"
+#include "llspeakers.h"
+#include "llscrollbar.h"
+#include "llviewerchat.h"
+#include "llpanel.h"
+
+class LLResizeBar;
+
+class LLFloaterIMNearbyChat
+	:	public LLFloaterIMSessionTab
+{
+public:
+	// constructor for inline chat-bars (e.g. hosted in chat history window)
+	LLFloaterIMNearbyChat(const LLSD& key = LLSD(LLUUID()));
+	~LLFloaterIMNearbyChat() {}
+
+	static LLFloaterIMNearbyChat* buildFloater(const LLSD& key);
+
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onClose(bool app_quitting);
+	/*virtual*/ void setVisible(BOOL visible);
+
+	void loadHistory();
+    void reloadMessages();
+	void removeScreenChat();
+
+	void addToHost();
+	void show();
+	bool isChatVisible() const;
+
+	/** @param archive true - to save a message to the chat history log */
+	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());
+	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);
+	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
+
+	LLChatEntry* getChatBox() { return mInputEditor; }
+
+	std::string getCurrentChat();
+
+	virtual BOOL handleKeyHere( KEY key, MASK mask );
+	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
+
+	static void startChat(const char* line);
+	static void stopChat();
+
+	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
+	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
+
+	static bool isWordsName(const std::string& name);
+
+	void showHistory();
+
+protected:
+	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
+	static void onChatBoxKeystroke(LLTextEditor* caller, void* userdata);
+	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
+	void onChatBoxFocusReceived();
+
+	void sendChat( EChatType type );
+	void onChatBoxCommit();
+	void onChatFontChange(LLFontGL* fontp);
+
+	/*virtual*/ void onTearOffClicked();
+	/*virtual*/ void onClickCloseBtn();
+
+	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
+	EChatType processChatTypeTriggers(EChatType type, std::string &str);
+
+	void displaySpeakingIndicator();
+
+	// Which non-zero channel did we last chat on?
+	static S32 sLastSpecialChatChannel;
+
+	LLOutputMonitorCtrl*	mOutputMonitor;
+	LLLocalSpeakerMgr*		mSpeakerMgr;
+
+	S32 mExpandedHeight;
+
+private:
+
+	void	onNearbySpeakers	();
+
+	/*virtual*/ void refresh();
+
+	LLHandle<LLView>	mPopupMenuHandle;
+	std::vector<LLChat> mMessageArchive;
+
+};
+
+#endif // LL_LLFLOATERIMNEARBYCHAT_H
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
new file mode 100644
index 0000000000..0dfaa9174b
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -0,0 +1,630 @@
+/** 
+ * @file LLFloaterIMNearbyChatHandler.cpp
+ * @brief Nearby chat chat managment
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagentdata.h" // for gAgentID
+#include "llfloaterimnearbychathandler.h"
+
+#include "llchatitemscontainerctrl.h"
+#include "llfirstuse.h"
+#include "llfloaterscriptdebug.h"
+#include "llhints.h"
+#include "llfloaterimnearbychat.h"
+#include "llrecentpeople.h"
+
+#include "llviewercontrol.h"
+
+#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
+#include "llviewerwindow.h"//for screen channel position
+#include "llfloaterimnearbychat.h"
+#include "llrootview.h"
+#include "lllayoutstack.h"
+
+//add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace
+using namespace LLNotificationsUI;
+
+static LLFloaterIMNearbyChatToastPanel* createToastPanel()
+{
+	LLFloaterIMNearbyChatToastPanel* item = LLFloaterIMNearbyChatToastPanel::createInstance();
+	return item;
+}
+
+
+//-----------------------------------------------------------------------------------------------
+//LLFloaterIMNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------	
+
+class LLFloaterIMNearbyChatScreenChannel: public LLScreenChannelBase
+{
+	LOG_CLASS(LLFloaterIMNearbyChatScreenChannel);
+public:
+	typedef std::vector<LLHandle<LLToast> > toast_vec_t;
+	typedef std::list<LLHandle<LLToast> > toast_list_t;
+
+	LLFloaterIMNearbyChatScreenChannel(const Params& p)
+		: LLScreenChannelBase(p)
+	{
+		mStopProcessing = false;
+
+		LLControlVariable* ctrl = gSavedSettings.getControl("NearbyToastLifeTime").get();
+		if (ctrl)
+		{
+			ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime, this));
+		}
+
+		ctrl = gSavedSettings.getControl("NearbyToastFadingTime").get();
+		if (ctrl)
+		{
+			ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime, this));
+		}
+	}
+
+	void addChat	(LLSD& chat);
+	void arrangeToasts		();
+	
+	typedef boost::function<LLFloaterIMNearbyChatToastPanel* (void )> create_toast_panel_callback_t;
+	void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
+
+	void onToastDestroyed	(LLToast* toast, bool app_quitting);
+	void onToastFade		(LLToast* toast);
+
+	void redrawToasts()
+	{
+		arrangeToasts();
+	}
+
+	// hide all toasts from screen, but not remove them from a channel
+	// removes all toasts from a channel
+	virtual void		removeToastsFromChannel() 
+	{
+		for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+		{
+			addToToastPool(it->get());
+		}
+		m_active_toasts.clear();
+	};
+
+	virtual void deleteAllChildren()
+	{
+		LL_DEBUGS("NearbyChat") << "Clearing toast pool" << llendl;
+		m_toast_pool.clear();
+		m_active_toasts.clear();
+		LLScreenChannelBase::deleteAllChildren();
+	}
+
+protected:
+	void	deactivateToast(LLToast* toast);
+	void	addToToastPool(LLToast* toast)
+	{
+		if (!toast) return;
+		LL_DEBUGS("NearbyChat") << "Pooling toast" << llendl;
+		toast->setVisible(FALSE);
+		toast->stopTimer();
+		toast->setIsHidden(true);
+
+		// Nearby chat toasts that are hidden, not destroyed. They are collected to the toast pool, so that
+		// they can be used next time, this is done for performance. But if the toast lifetime was changed
+		// (from preferences floater (STORY-36)) while it was shown (at this moment toast isn't in the pool yet)
+		// changes don't take affect.
+		// So toast's lifetime should be updated each time it's added to the pool. Otherwise viewer would have
+		// to be restarted so that changes take effect.
+		toast->setLifetime(gSavedSettings.getS32("NearbyToastLifeTime"));
+		toast->setFadingTime(gSavedSettings.getS32("NearbyToastFadingTime"));
+		m_toast_pool.push_back(toast->getHandle());
+	}
+
+	void	createOverflowToast(S32 bottom, F32 timer);
+
+	void 	updateToastsLifetime();
+
+	void	updateToastFadingTime();
+
+	create_toast_panel_callback_t m_create_toast_panel_callback_t;
+
+	bool	createPoolToast();
+	
+	toast_vec_t m_active_toasts;
+	toast_list_t m_toast_pool;
+
+	bool	mStopProcessing;
+	bool	mChannelRect;
+};
+
+
+
+//-----------------------------------------------------------------------------------------------
+// LLFloaterIMNearbyChatToast
+//-----------------------------------------------------------------------------------------------
+
+// We're deriving from LLToast to be able to override onClose()
+// in order to handle closing nearby chat toasts properly.
+class LLFloaterIMNearbyChatToast : public LLToast
+{
+	LOG_CLASS(LLFloaterIMNearbyChatToast);
+public:
+	LLFloaterIMNearbyChatToast(const LLToast::Params& p, LLFloaterIMNearbyChatScreenChannel* nc_channelp)
+	:	LLToast(p),
+	 	mNearbyChatScreenChannelp(nc_channelp)
+	{
+	}
+
+	/*virtual*/ void onClose(bool app_quitting);
+
+private:
+	LLFloaterIMNearbyChatScreenChannel*	mNearbyChatScreenChannelp;
+};
+
+//-----------------------------------------------------------------------------------------------
+// LLFloaterIMNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------
+
+void LLFloaterIMNearbyChatScreenChannel::deactivateToast(LLToast* toast)
+{
+	toast_vec_t::iterator pos = std::find(m_active_toasts.begin(), m_active_toasts.end(), toast->getHandle());
+
+	if (pos == m_active_toasts.end())
+	{
+		llassert(pos == m_active_toasts.end());
+		return;
+	}
+
+	LL_DEBUGS("NearbyChat") << "Deactivating toast" << llendl;
+	m_active_toasts.erase(pos);
+}
+
+void	LLFloaterIMNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
+{
+	//we don't need overflow toast in nearby chat
+}
+
+void LLFloaterIMNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting)
+{	
+	LL_DEBUGS("NearbyChat") << "Toast destroyed (app_quitting=" << app_quitting << ")" << llendl;
+
+	if (app_quitting)
+	{
+		// Viewer is quitting.
+		// Immediately stop processing chat messages (EXT-1419).
+	mStopProcessing = true;
+}
+	else
+	{
+		// The toast is being closed by user (STORM-192).
+		// Remove it from the list of active toasts to prevent
+		// further references to the invalid pointer.
+		deactivateToast(toast);
+	}
+}
+
+void LLFloaterIMNearbyChatScreenChannel::onToastFade(LLToast* toast)
+{	
+	LL_DEBUGS("NearbyChat") << "Toast fading" << llendl;
+
+	//fade mean we put toast to toast pool
+	if(!toast)
+		return;
+
+	deactivateToast(toast);
+
+	addToToastPool(toast);
+	
+	arrangeToasts();
+}
+
+void LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime()
+{
+	S32 seconds = gSavedSettings.getS32("NearbyToastLifeTime");
+	toast_list_t::iterator it;
+
+	for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it)
+	{
+		(*it).get()->setLifetime(seconds);
+	}
+}
+
+void LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime()
+{
+	S32 seconds = gSavedSettings.getS32("NearbyToastFadingTime");
+	toast_list_t::iterator it;
+
+	for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it)
+	{
+		(*it).get()->setFadingTime(seconds);
+	}
+}
+
+bool	LLFloaterIMNearbyChatScreenChannel::createPoolToast()
+{
+	LLFloaterIMNearbyChatToastPanel* panel= m_create_toast_panel_callback_t();
+	if(!panel)
+		return false;
+	
+	LLToast::Params p;
+	p.panel = panel;
+	p.lifetime_secs = gSavedSettings.getS32("NearbyToastLifeTime");
+	p.fading_time_secs = gSavedSettings.getS32("NearbyToastFadingTime");
+
+	LLToast* toast = new LLFloaterIMNearbyChatToast(p, this);
+	
+	
+	toast->setOnFadeCallback(boost::bind(&LLFloaterIMNearbyChatScreenChannel::onToastFade, this, _1));
+
+	// If the toast gets somehow prematurely destroyed, deactivate it to prevent crash (STORM-1352).
+	toast->setOnToastDestroyedCallback(boost::bind(&LLFloaterIMNearbyChatScreenChannel::onToastDestroyed, this, _1, false));
+
+	LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl;	
+	m_toast_pool.push_back(toast->getHandle());
+	return true;
+}
+
+void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat)
+{
+	//look in pool. if there is any message
+	if(mStopProcessing)
+		return;
+
+	/*
+    find last toast and check ID
+	*/
+
+	if(m_active_toasts.size())
+	{
+		LLUUID fromID = chat["from_id"].asUUID();		// agent id or object id
+		std::string from = chat["from"].asString();
+		LLToast* toast = m_active_toasts[0].get();
+		if (toast)
+		{
+			LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel());
+  
+			if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText())
+			{
+				panel->addMessage(chat);
+				toast->reshapeToPanel();
+				toast->startTimer();
+	  
+				arrangeToasts();
+				return;
+			}
+		}
+	}
+	
+
+	
+	if(m_toast_pool.empty())
+	{
+		//"pool" is empty - create one more panel
+		LL_DEBUGS("NearbyChat") << "Empty pool" << llendl;
+		if(!createPoolToast())//created toast will go to pool. so next call will find it
+			return;
+		addChat(chat);
+		return;
+	}
+
+	int chat_type = chat["chat_type"].asInteger();
+	
+	if( ((EChatType)chat_type == CHAT_TYPE_DEBUG_MSG))
+	{
+		if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) 
+			return;
+		if(gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)
+			return;
+	}
+		
+
+	//take 1st element from pool, (re)initialize it, put it in active toasts
+
+	LL_DEBUGS("NearbyChat") << "Getting toast from pool" << llendl;
+	LLToast* toast = m_toast_pool.back().get();
+
+	m_toast_pool.pop_back();
+
+
+	LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel());
+	if(!panel)
+		return;
+	panel->init(chat);
+
+	toast->reshapeToPanel();
+	toast->startTimer();
+	
+	m_active_toasts.push_back(toast->getHandle());
+
+	arrangeToasts();
+}
+
+static bool sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> second)
+{
+	if (!first.get() || !second.get()) return false; // STORM-1352
+
+	F32 v1 = first.get()->getTimeLeftToLive();
+	F32 v2 = second.get()->getTimeLeftToLive();
+	return v1 > v2;
+}
+
+void LLFloaterIMNearbyChatScreenChannel::arrangeToasts()
+{
+	if(mStopProcessing || isHovering())
+		return;
+
+	if (mFloaterSnapRegion == NULL)
+	{
+		mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region");
+	}
+	
+	if (!getParent())
+	{
+		// connect to floater snap region just to get resize events, we don't care about being a proper widget 
+		mFloaterSnapRegion->addChild(this);
+		setFollows(FOLLOWS_ALL);
+	}
+
+	LLRect	toast_rect;	
+	updateRect();
+
+	LLRect channel_rect;
+	mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &channel_rect, gFloaterView);
+	channel_rect.mLeft += 10;
+	channel_rect.mRight = channel_rect.mLeft + 300;
+
+	S32 channel_bottom = channel_rect.mBottom;
+
+	S32		bottom = channel_bottom + 80;
+	S32		margin = gSavedSettings.getS32("ToastGap");
+
+	//sort active toasts
+	std::sort(m_active_toasts.begin(),m_active_toasts.end(),sort_toasts_predicate);
+
+	//calc max visible item and hide other toasts.
+
+	for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+	{
+		LLToast* toast = it->get();
+		if (!toast)
+		{
+			llwarns << "NULL found in the active chat toasts list!" << llendl;
+			continue;
+		}
+
+		S32 toast_top = bottom + toast->getRect().getHeight() + margin;
+
+		if(toast_top > channel_rect.getHeight())
+		{
+			while(it!=m_active_toasts.end())
+			{
+				addToToastPool(it->get());
+				it=m_active_toasts.erase(it);
+			}
+			break;
+		}
+
+		toast_rect = toast->getRect();
+		toast_rect.setLeftTopAndSize(channel_rect.mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());
+
+		toast->setRect(toast_rect);
+		bottom += toast_rect.getHeight() - toast->getTopPad() + margin;
+	}
+	
+	// use reverse order to provide correct z-order and avoid toast blinking
+	
+	for(toast_vec_t::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it)
+	{
+		LLToast* toast = it->get();
+		if (toast)
+	{
+		toast->setIsHidden(false);
+		toast->setVisible(TRUE);
+		}
+	}
+
+}
+
+
+
+//-----------------------------------------------------------------------------------------------
+//LLFloaterIMNearbyChatHandler
+//-----------------------------------------------------------------------------------------------
+boost::scoped_ptr<LLEventPump> LLFloaterIMNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat"));
+
+LLFloaterIMNearbyChatHandler::LLFloaterIMNearbyChatHandler()
+{
+	// Getting a Channel for our notifications
+	LLFloaterIMNearbyChatScreenChannel::Params p;
+	p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
+	LLFloaterIMNearbyChatScreenChannel* channel = new LLFloaterIMNearbyChatScreenChannel(p);
+	
+	LLFloaterIMNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
+
+	channel->setCreatePanelCallback(callback);
+
+	LLChannelManager::getInstance()->addChannel(channel);
+
+	mChannel = channel->getHandle();
+}
+
+LLFloaterIMNearbyChatHandler::~LLFloaterIMNearbyChatHandler()
+{
+}
+
+
+void LLFloaterIMNearbyChatHandler::initChannel()
+{
+	//LLRect snap_rect = gFloaterView->getSnapRect();
+	//mChannel->init(snap_rect.mLeft, snap_rect.mLeft + 200);
+}
+
+
+
+void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
+									  const LLSD &args)
+{
+	if(chat_msg.mMuted == TRUE)
+		return;
+
+	if(chat_msg.mText.empty())
+		return;//don't process empty messages
+
+    LLFloaterReg::getInstance("im_container");
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+
+	// Build notification data 
+	LLSD chat;
+	chat["message"] = chat_msg.mText;
+	chat["from"] = chat_msg.mFromName;
+	chat["from_id"] = chat_msg.mFromID;
+	chat["time"] = chat_msg.mTime;
+	chat["source"] = (S32)chat_msg.mSourceType;
+	chat["chat_type"] = (S32)chat_msg.mChatType;
+	chat["chat_style"] = (S32)chat_msg.mChatStyle;
+	// Pass sender info so that it can be rendered properly (STORM-1021).
+	chat["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
+
+	if (chat_msg.mChatType == CHAT_TYPE_DIRECT &&
+		chat_msg.mText.length() > 0 &&
+		chat_msg.mText[0] == '@')
+	{
+		// Send event on to LLEventStream and exit
+		sChatWatcher->post(chat);
+		return;
+	}
+
+	// don't show toast and add message to chat history on receive debug message
+	// with disabled setting showing script errors or enabled setting to show script
+	// errors in separate window.
+	if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
+	{
+		if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE)
+			return;
+
+		// don't process debug messages from not owned objects, see EXT-7762
+		if (gAgentID != chat_msg.mOwnerID)
+		{
+			return;
+		}
+
+		if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat"))
+		{
+
+			LLColor4 txt_color;
+
+			LLViewerChat::getChatColor(chat_msg,txt_color);
+
+			LLFloaterScriptDebug::addScriptLine(chat_msg.mText,
+												chat_msg.mFromName,
+												txt_color,
+												chat_msg.mFromID);
+			return;
+		}
+	}
+
+	nearby_chat->addMessage(chat_msg, true, args);
+
+	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT 
+		&& chat_msg.mFromID.notNull() 
+		&& chat_msg.mFromID != gAgentID)
+	{
+ 		LLFirstUse::otherAvatarChatFirst();
+
+ 		// Add sender to the recent people list.
+ 		LLRecentPeople::instance().add(chat_msg.mFromID);
+
+	}
+
+	// Send event on to LLEventStream
+	sChatWatcher->post(chat);
+
+	if( nearby_chat->isInVisibleChain()
+		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
+			&& gSavedSettings.getBOOL("UseChatBubbles") )
+		|| mChannel.isDead()
+		|| !mChannel.get()->getShowToasts() ) // to prevent toasts in Do Not Disturb mode
+		return;//no need in toast if chat is visible or if bubble chat is enabled
+
+	// arrange a channel on a screen
+	if(!mChannel.get()->getVisible())
+	{
+		initChannel();
+	}
+
+	/*
+	//comment all this due to EXT-4432
+	..may clean up after some time...
+
+	//only messages from AGENTS
+	if(CHAT_SOURCE_OBJECT == chat_msg.mSourceType)
+	{
+		if(chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
+			return;//ok for now we don't skip messeges from object, so skip only debug messages
+	}
+	*/
+
+	LLFloaterIMNearbyChatScreenChannel* channel = dynamic_cast<LLFloaterIMNearbyChatScreenChannel*>(mChannel.get());
+
+	if(channel)
+	{
+		// Handle IRC styled messages.
+		std::string toast_msg;
+		if (chat_msg.mChatStyle == CHAT_STYLE_IRC)
+		{
+			if (!chat_msg.mFromName.empty())
+			{
+				toast_msg += chat_msg.mFromName;
+			}
+			toast_msg += chat_msg.mText.substr(3);
+		}
+		else
+		{
+			toast_msg = chat_msg.mText;
+		}
+
+		// Add a nearby chat toast.
+		LLUUID id;
+		id.generate();
+		chat["id"] = id;
+		std::string r_color_name = "White";
+		F32 r_color_alpha = 1.0f; 
+		LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
+		
+		chat["text_color"] = r_color_name;
+		chat["color_alpha"] = r_color_alpha;
+		chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
+		chat["message"] = toast_msg;
+		channel->addChat(chat);	
+	}
+}
+
+
+//-----------------------------------------------------------------------------------------------
+// LLFloaterIMNearbyChatToast
+//-----------------------------------------------------------------------------------------------
+
+// virtual
+void LLFloaterIMNearbyChatToast::onClose(bool app_quitting)
+{
+	mNearbyChatScreenChannelp->onToastDestroyed(this, app_quitting);
+}
+
+// EOF
diff --git a/indra/newview/llfloaterimnearbychathandler.h b/indra/newview/llfloaterimnearbychathandler.h
new file mode 100644
index 0000000000..5e6f8cde30
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychathandler.h
@@ -0,0 +1,54 @@
+/** 
+ * @file llfloaterimnearbychathandler.h
+ * @brief nearby chat notify
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERIMNEARBYCHATHANDLER_H
+#define LL_LLFLOATERIMNEARBYCHATHANDLER_H
+
+#include "llnotificationhandler.h"
+
+class LLEventPump;
+
+//add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace
+namespace LLNotificationsUI{
+
+class LLFloaterIMNearbyChatHandler : public LLChatHandler
+{
+public:
+	LLFloaterIMNearbyChatHandler();
+	virtual ~LLFloaterIMNearbyChatHandler();
+
+
+	virtual void processChat(const LLChat& chat_msg, const LLSD &args);
+
+protected:
+	virtual void initChannel();
+
+	static boost::scoped_ptr<LLEventPump> sChatWatcher;
+};
+
+}
+
+#endif /* LL_LLFLOATERIMNEARBYCHATHANDLER_H */
diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp
new file mode 100644
index 0000000000..14a22bcd84
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychatlistener.cpp
@@ -0,0 +1,100 @@
+/**
+ * @file   llfloaterimnearbychatlistener.cpp
+ * @author Dave Simmons
+ * @date   2011-03-15
+ * @brief  Implementation for LLFloaterIMNearbyChatListener.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterimnearbychatlistener.h"
+#include "llfloaterimnearbychat.h"
+
+#include "llagent.h"
+#include "llchat.h"
+
+
+
+LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar)
+  : LLEventAPI("LLChatBar",
+               "LLChatBar listener to (e.g.) sendChat, etc."),
+	mChatbar(chatbar)
+{
+    add("sendChat",
+        "Send chat to the simulator:\n"
+        "[\"message\"] chat message text [required]\n"
+        "[\"channel\"] chat channel number [default = 0]\n"
+		"[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]",
+        &LLFloaterIMNearbyChatListener::sendChat);
+}
+
+
+// "sendChat" command
+void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const
+{
+	// Extract the data
+	std::string chat_text = chat_data["message"].asString();
+
+	S32 channel = 0;
+	if (chat_data.has("channel"))
+	{
+		channel = chat_data["channel"].asInteger();
+		if (channel < 0 || channel >= CHAT_CHANNEL_DEBUG)
+		{	// Use 0 up to (but not including) CHAT_CHANNEL_DEBUG
+			channel = 0;
+		}
+	}
+
+	EChatType type_o_chat = CHAT_TYPE_NORMAL;
+	if (chat_data.has("type"))
+	{
+		std::string type_string = chat_data["type"].asString();
+		if (type_string == "whisper")
+		{
+			type_o_chat = CHAT_TYPE_WHISPER;
+		}
+		else if (type_string == "shout")
+		{
+			type_o_chat = CHAT_TYPE_SHOUT;
+		}
+	}
+
+	// Have to prepend /42 style channel numbers
+	std::string chat_to_send;
+	if (channel == 0)
+	{
+		chat_to_send = chat_text;
+	}
+	else
+	{
+		chat_to_send += "/";
+		chat_to_send += chat_data["channel"].asString();
+		chat_to_send += " ";
+		chat_to_send += chat_text;
+	}
+
+	// Send it as if it was typed in
+	mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0));
+}
+
diff --git a/indra/newview/llfloaterimnearbychatlistener.h b/indra/newview/llfloaterimnearbychatlistener.h
new file mode 100644
index 0000000000..1470a6dc1e
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychatlistener.h
@@ -0,0 +1,50 @@
+/**
+ * @file   llfloaterimnearbychatlistener.h
+ * @author Dave Simmons
+ * @date   2011-03-15
+ * @brief  Class definition for LLFloaterIMNearbyChatListener.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLFLOATERIMNEARBYCHATLISTENER_H
+#define LL_LLFLOATERIMNEARBYCHATLISTENER_H
+
+#include "lleventapi.h"
+
+class LLSD;
+class LLFloaterIMNearbyChat;
+
+class LLFloaterIMNearbyChatListener : public LLEventAPI
+{
+public:
+	LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar);
+
+private:
+    void sendChat(LLSD const & chat_data) const;
+
+	LLFloaterIMNearbyChat & mChatbar;
+};
+
+#endif // LL_LLFLOATERIMNEARBYCHATLISTENER_H
+
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
new file mode 100644
index 0000000000..0c622e07c4
--- /dev/null
+++ b/indra/newview/llfloaterimsession.cpp
@@ -0,0 +1,1202 @@
+/** 
+ * @file llfloaterimsession.cpp
+ * @brief LLFloaterIMSession class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterimsession.h"
+
+#include "lldraghandle.h"
+#include "llnotificationsutil.h"
+
+#include "llagent.h"
+#include "llappviewer.h"
+#include "llavataractions.h"
+#include "llavatarnamecache.h"
+#include "llbutton.h"
+#include "llchannelmanager.h"
+#include "llchiclet.h"
+#include "llchicletbar.h"
+#include "llfloaterreg.h"
+#include "llfloateravatarpicker.h"
+#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
+#include "llinventoryfunctions.h"
+//#include "lllayoutstack.h"
+#include "llchatentry.h"
+#include "lllogchat.h"
+#include "llscreenchannel.h"
+#include "llsyswellwindow.h"
+#include "lltrans.h"
+#include "llchathistory.h"
+#include "llnotifications.h"
+#include "llviewerwindow.h"
+#include "lltransientfloatermgr.h"
+#include "llinventorymodel.h"
+#include "llrootview.h"
+#include "llspeakers.h"
+#include "llviewerchat.h"
+#include "llnotificationmanager.h"
+#include "llautoreplace.h"
+
+floater_showed_signal_t LLFloaterIMSession::sIMFloaterShowedSignal;
+
+LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
+  : LLFloaterIMSessionTab(session_id),
+	mLastMessageIndex(-1),
+	mDialog(IM_NOTHING_SPECIAL),
+	mSavedTitle(),
+	mTypingStart(),
+	mShouldSendTypingState(false),
+	mMeTyping(false),
+	mOtherTyping(false),
+	mTypingTimer(),
+	mTypingTimeoutTimer(),
+	mPositioned(false),
+	mSessionInitialized(false),
+	mStartConferenceInSameFloater(false)
+{
+	mIsNearbyChat = false;
+
+	initIMSession(session_id);
+		
+	setOverlapsScreenChannel(true);
+
+	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+
+	setDocked(true);
+}
+
+
+// virtual
+void LLFloaterIMSession::refresh()
+{
+	if (mMeTyping)
+{
+		// Time out if user hasn't typed for a while.
+		if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS)
+		{
+	setTyping(false);
+		}
+	}
+}
+
+// virtual
+void LLFloaterIMSession::onClickCloseBtn()
+{
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
+
+	if (session != NULL)
+	{
+		bool is_call_with_chat = session->isGroupSessionType()
+				|| session->isAdHocSessionType() || session->isP2PSessionType();
+
+		LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+		if (is_call_with_chat && voice_channel != NULL
+				&& voice_channel->isActive())
+		{
+			LLSD payload;
+			payload["session_id"] = mSessionID;
+			LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+			return;
+		}
+	}
+	else
+	{
+		llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl;
+		return;
+	}
+
+	LLFloaterIMSessionTab::onClickCloseBtn();
+}
+
+/* static */
+void LLFloaterIMSession::newIMCallback(const LLSD& data)
+{
+	if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull())
+	{
+		LLUUID session_id = data["session_id"].asUUID();
+
+		LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+        // update if visible, otherwise will be updated when opened
+		if (floater && floater->getVisible())
+		{
+			floater->updateMessages();
+		}
+	}
+}
+
+void LLFloaterIMSession::onVisibilityChange(const LLSD& new_visibility)
+{
+	bool visible = new_visibility.asBoolean();
+
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+	if (visible && voice_channel &&
+		voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
+	{
+		LLFloaterReg::showInstance("voice_call", mSessionID);
+	}
+	else
+	{
+		LLFloaterReg::hideInstance("voice_call", mSessionID);
+	}
+}
+
+void LLFloaterIMSession::onSendMsg( LLUICtrl* ctrl, void* userdata )
+{
+	LLFloaterIMSession* self = (LLFloaterIMSession*) userdata;
+	self->sendMsgFromInputEditor();
+	self->setTyping(false);
+}
+
+void LLFloaterIMSession::sendMsgFromInputEditor()
+{
+	if (gAgent.isGodlike()
+		|| (mDialog != IM_NOTHING_SPECIAL)
+		|| !mOtherParticipantUUID.isNull())
+	{
+		if (mInputEditor)
+		{
+			LLWString text = mInputEditor->getWText();
+			LLWStringUtil::trim(text);
+			LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
+			if(!text.empty())
+			{
+				// Truncate and convert to UTF8 for transport
+				std::string utf8_text = wstring_to_utf8str(text);
+
+				sendMsg(utf8_text);
+
+				mInputEditor->setText(LLStringUtil::null);
+			}
+		}
+	}
+	else
+	{
+		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
+	}
+}
+
+void LLFloaterIMSession::sendMsg(const std::string& msg)
+{
+	const std::string utf8_text = utf8str_truncate(msg, MAX_MSG_BUF_SIZE - 1);
+
+	if (mSessionInitialized)
+	{
+		LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
+	}
+	else
+	{
+		//queue up the message to send once the session is initialized
+		mQueuedMsgsForInit.append(utf8_text);
+	}
+
+	updateMessages();
+}
+
+LLFloaterIMSession::~LLFloaterIMSession()
+{
+	mVoiceChannelStateChangeConnection.disconnect();
+	if(LLVoiceClient::instanceExists())
+	{
+		LLVoiceClient::getInstance()->removeObserver(this);
+	}
+
+	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
+}
+
+
+void LLFloaterIMSession::initIMSession(const LLUUID& session_id)
+{
+	// Change the floater key to bind it to a new session.
+	setKey(session_id);
+
+	mSessionID = session_id;
+	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+	if (mSession)
+	{
+		mIsP2PChat = mSession->isP2PSessionType();
+		mSessionInitialized = mSession->mSessionInitialized;
+		mDialog = mSession->mType;
+	}
+}
+
+void LLFloaterIMSession::initIMFloater()
+{
+	const LLUUID& other_party_id =
+			LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+	if (other_party_id.notNull())
+	{
+		mOtherParticipantUUID = other_party_id;
+	}
+
+	boundVoiceChannel();
+
+	mTypingStart = LLTrans::getString("IM_typing_start_string");
+
+	// Show control panel in torn off floaters only.
+	mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel"));
+
+	// Disable input editor if session cannot accept text
+	if ( mSession && !mSession->mTextIMPossible )
+	{
+		mInputEditor->setEnabled(FALSE);
+		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
+	}
+
+	if (!mIsP2PChat)
+	{
+		std::string session_name(LLIMModel::instance().getName(mSessionID));
+		updateSessionName(session_name);
+	}
+}
+
+//virtual
+BOOL LLFloaterIMSession::postBuild()
+{
+	BOOL result = LLFloaterIMSessionTab::postBuild();
+
+	mInputEditor->setMaxTextLength(1023);
+	// enable line history support for instant message bar
+	// XXX stinson TODO : resolve merge by adding autoreplace to text editors
+#if 0
+	// *TODO Establish LineEditor with autoreplace callback
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
+#endif
+	
+	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
+	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
+	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
+	mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this));
+
+	setDocked(true);
+
+	LLButton* add_btn = getChild<LLButton>("add_btn");
+
+	// Allow to add chat participants depending on the session type
+	add_btn->setEnabled(isInviteAllowed());
+	add_btn->setClickedCallback(boost::bind(&LLFloaterIMSession::onAddButtonClicked, this));
+
+	childSetAction("voice_call_btn", boost::bind(&LLFloaterIMSession::onCallButtonClicked, this));
+
+	LLVoiceClient::getInstance()->addObserver(this);
+	
+	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
+	//see LLFloaterIMPanel for how it is done (IB)
+
+	initIMFloater();
+
+	return result;
+}
+
+void LLFloaterIMSession::onAddButtonClicked()
+{
+    LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn");
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMSession::addSessionParticipants, this, _1), TRUE, TRUE, FALSE, root_floater->getName(), button);
+	if (!picker)
+	{
+		return;
+	}
+
+	// Need to disable 'ok' button when selected users are already in conversation.
+	picker->setOkBtnEnableCb(boost::bind(&LLFloaterIMSession::canAddSelectedToChat, this, _1));
+	
+	if (root_floater)
+	{
+		root_floater->addDependentFloater(picker);
+	}
+}
+
+bool LLFloaterIMSession::canAddSelectedToChat(const uuid_vec_t& uuids)
+{
+	if (!mSession
+		|| mDialog == IM_SESSION_GROUP_START
+		|| mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID))
+	{
+		return false;
+	}
+
+	if (mIsP2PChat)
+	{
+		// For a P2P session just check if we are not adding the other participant.
+
+		for (uuid_vec_t::const_iterator id = uuids.begin();
+				id != uuids.end(); ++id)
+		{
+			if (*id == mOtherParticipantUUID)
+			{
+				return false;
+			}
+		}
+	}
+	else
+	{
+		// For a conference session we need to check against the list from LLSpeakerMgr,
+		// because this list may change when participants join or leave the session.
+
+		LLSpeakerMgr::speaker_list_t speaker_list;
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if (speaker_mgr)
+		{
+			speaker_mgr->getSpeakerList(&speaker_list, true);
+		}
+	
+		for (uuid_vec_t::const_iterator id = uuids.begin();
+				id != uuids.end(); ++id)
+		{
+			for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin();
+					it != speaker_list.end(); ++it)
+			{
+				const LLPointer<LLSpeaker>& speaker = *it;
+				if (*id == speaker->mID)
+				{
+					return false;
+				}
+			}
+		}
+	}
+
+	return true;
+}
+
+void LLFloaterIMSession::addSessionParticipants(const uuid_vec_t& uuids)
+{
+	if (mIsP2PChat)
+	{
+		LLSD payload;
+		LLSD args;
+
+		LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload,
+				boost::bind(&LLFloaterIMSession::addP2PSessionParticipants, this, _1, _2, uuids));
+	}
+	else
+	{
+		// remember whom we have invited, to notify others later, when the invited ones actually join
+		mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+		
+		inviteToSession(uuids);
+	}
+}
+
+void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (option != 0)
+	{
+		return;
+	}
+
+	mStartConferenceInSameFloater = true;
+
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+	// first check whether this is a voice session
+	bool is_voice_call = voice_channel != NULL && voice_channel->isActive();
+
+	uuid_vec_t temp_ids;
+
+	// Add the initial participant of a P2P session
+	temp_ids.push_back(mOtherParticipantUUID);
+	temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end());
+
+	// then we can close the current session
+	onClose(false);
+
+	// we start a new session so reset the initialization flag
+	mSessionInitialized = false;
+
+	// remember whom we have invited, to notify others later, when the invited ones actually join
+	mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
+
+	// Start a new ad hoc voice call if we invite new participants to a P2P call,
+	// or start a text chat otherwise.
+	if (is_voice_call)
+	{
+		LLAvatarActions::startAdhocCall(temp_ids, mSessionID);
+	}
+	else
+	{
+		LLAvatarActions::startConference(temp_ids, mSessionID);
+	}
+}
+
+void LLFloaterIMSession::sendParticipantsAddedNotification(const uuid_vec_t& uuids)
+{
+	std::string names_string;
+	LLAvatarActions::buildResidentsString(uuids, names_string);
+	LLStringUtil::format_map_t args;
+	args["[NAME]"] = names_string;
+
+	sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args));
+}
+
+void LLFloaterIMSession::boundVoiceChannel()
+{
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+	if(voice_channel)
+	{
+		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(
+				boost::bind(&LLFloaterIMSession::onVoiceChannelStateChanged, this, _1, _2));
+
+		//call (either p2p, group or ad-hoc) can be already in started state
+		bool callIsActive = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+		updateCallBtnState(callIsActive);
+	}
+}
+
+void LLFloaterIMSession::onCallButtonClicked()
+{
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+	if (voice_channel)
+	{
+		bool is_call_active = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+	    if (is_call_active)
+	    {
+		    gIMMgr->endCall(mSessionID);
+	    }
+	    else
+	    {
+		    gIMMgr->startCall(mSessionID);
+	    }
+	}
+}
+
+void LLFloaterIMSession::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL)
+	{
+		enableDisableCallBtn();
+	}
+}
+
+void LLFloaterIMSession::onVoiceChannelStateChanged(
+		const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
+{
+	bool callIsActive = new_state >= LLVoiceChannel::STATE_CALL_STARTED;
+	updateCallBtnState(callIsActive);
+}
+
+void LLFloaterIMSession::updateSessionName(const std::string& name)
+{
+	LLFloaterIMSessionTab::updateSessionName(name);
+	setTitle(name);	
+	mTypingStart.setArg("[NAME]", name);
+}
+
+//static
+LLFloaterIMSession* LLFloaterIMSession::show(const LLUUID& session_id)
+{
+	closeHiddenIMToasts();
+
+	if (!gIMMgr->hasSession(session_id))
+		return NULL;
+
+	// Test the existence of the floater before we try to create it
+	bool exist = findInstance(session_id);
+
+	// Get the floater: this will create the instance if it didn't exist
+	LLFloaterIMSession* floater = getInstance(session_id);
+	if (!floater)
+		return NULL;
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+
+	// Do not add again existing floaters
+	if (!exist)
+	{
+		//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
+		// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
+		LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
+		if (floater_container)
+		{
+			floater_container->addFloater(floater, TRUE, i_pt);
+		}
+	}
+
+	floater->openFloater(floater->getKey());
+
+	floater->setVisible(TRUE);
+
+	return floater;
+}
+//static
+LLFloaterIMSession* LLFloaterIMSession::findInstance(const LLUUID& session_id)
+{
+    LLFloaterIMSession* conversation =
+    		LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+	return conversation;
+}
+
+LLFloaterIMSession* LLFloaterIMSession::getInstance(const LLUUID& session_id)
+{
+	LLFloaterIMSession* conversation =
+				LLFloaterReg::getTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+	return conversation;
+}
+
+void LLFloaterIMSession::onClose(bool app_quitting)
+{
+	setTyping(false);
+
+	// The source of much argument and design thrashing
+	// Should the window hide or the session close when the X is clicked?
+	//
+	// Last change:
+	// EXT-3516 X Button should end IM session, _ button should hide
+	gIMMgr->leaveSession(mSessionID);
+
+	// Clean up the conversation *after* the session has been ended
+	LLFloaterIMSessionTab::onClose(app_quitting);
+}
+
+void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock)
+{
+	// update notification channel state
+	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+		(LLNotificationsUI::LLChannelManager::getInstance()->
+											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+	
+	if(!isChatMultiTab())
+	{
+		LLTransientDockableFloater::setDocked(docked, pop_on_undock);
+	}
+
+	// update notification channel state
+	if(channel)
+	{
+		channel->updateShowToastsState();
+		channel->redrawToasts();
+	}
+}
+
+void LLFloaterIMSession::setVisible(BOOL visible)
+{
+	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+		(LLNotificationsUI::LLChannelManager::getInstance()->
+											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+	LLFloaterIMSessionTab::setVisible(visible);
+
+	// update notification channel state
+	if(channel)
+	{
+		channel->updateShowToastsState();
+		channel->redrawToasts();
+	}
+
+	if(!visible)
+	{
+		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
+		if(chiclet)
+		{
+			chiclet->setToggleState(false);
+		}
+	}
+
+	if (visible && isInVisibleChain())
+	{
+		sIMFloaterShowedSignal(mSessionID);
+        
+	}
+
+    setFocus(visible);
+}
+
+BOOL LLFloaterIMSession::getVisible()
+{
+	bool visible;
+
+	if(isChatMultiTab())
+	{
+		LLFloaterIMContainer* im_container =
+				LLFloaterIMContainer::getInstance();
+		
+		// Treat inactive floater as invisible.
+		bool is_active = im_container->getActiveFloater() == this;
+	
+		//torn off floater is always inactive
+		if (!is_active && getHost() != im_container)
+		{
+			visible = LLTransientDockableFloater::getVisible();
+		}
+		else
+		{
+		// getVisible() returns TRUE when Tabbed IM window is minimized.
+			visible = is_active && !im_container->isMinimized()
+						&& im_container->getVisible();
+	}
+	}
+	else
+	{
+		visible = LLTransientDockableFloater::getVisible();
+	}
+
+	return visible;
+}
+
+//static
+bool LLFloaterIMSession::toggle(const LLUUID& session_id)
+{
+	if(!isChatMultiTab())
+	{
+		LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>(
+				"impanel", session_id);
+		if (floater && floater->getVisible() && floater->hasFocus())
+		{
+			// clicking on chiclet to close floater just hides it to maintain existing
+			// scroll/text entry state
+			floater->setVisible(false);
+			return false;
+		}
+		else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
+		{
+			floater->setVisible(TRUE);
+			floater->setFocus(TRUE);
+			return true;
+		}
+	}
+
+	// ensure the list of messages is updated when floater is made visible
+	show(session_id);
+	return true;
+}
+
+void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id)
+{
+	mSessionInitialized = true;
+
+	//will be different only for an ad-hoc im session
+	if (mSessionID != im_session_id)
+	{
+		initIMSession(im_session_id);
+		buildConversationViewParticipant();
+	}
+
+	initIMFloater();
+	
+	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
+
+	//need to send delayed messages collected while waiting for session initialization
+	if (mQueuedMsgsForInit.size())
+	{
+		LLSD::array_iterator iter;
+		for ( iter = mQueuedMsgsForInit.beginArray();
+					iter != mQueuedMsgsForInit.endArray(); ++iter)
+		{
+			LLIMModel::sendMessage(iter->asString(), mSessionID,
+				mOtherParticipantUUID, mDialog);
+		}
+
+		mQueuedMsgsForInit.clear();
+	}
+}
+
+void LLFloaterIMSession::updateMessages()
+{
+	std::list<LLSD> messages;
+
+	// we shouldn't reset unread message counters if IM floater doesn't have focus
+    LLIMModel::instance().getMessages(
+    		mSessionID, messages, mLastMessageIndex + 1, hasFocus());
+
+	if (messages.size())
+	{
+		std::ostringstream message;
+		std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
+		std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
+		for (; iter != iter_end; ++iter)
+		{
+			LLSD msg = *iter;
+
+			std::string time = msg["time"].asString();
+			LLUUID from_id = msg["from_id"].asUUID();
+			std::string from = msg["from"].asString();
+			std::string message = msg["message"].asString();
+			bool is_history = msg["is_history"].asBoolean();
+
+			LLChat chat;
+			chat.mFromID = from_id;
+			chat.mSessionID = mSessionID;
+			chat.mFromName = from;
+			chat.mTimeStr = time;
+			chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
+
+			// process offer notification
+			if (msg.has("notification_id"))
+			{
+				chat.mNotifId = msg["notification_id"].asUUID();
+				// if notification exists - embed it
+				if (LLNotificationsUtil::find(chat.mNotifId) != NULL)
+				{
+					// remove embedded notification from channel
+					LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+							(LLNotificationsUI::LLChannelManager::getInstance()->
+																findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+					if (getVisible())
+					{
+						// toast will be automatically closed since it is not storable toast
+						channel->hideToast(chat.mNotifId);
+					}
+				}
+				// if notification doesn't exist - try to use next message which should be log entry
+				else
+				{
+					continue;
+				}
+			}
+			//process text message
+			else
+			{
+				chat.mText = message;
+			}
+			
+			// Add the message to the chat log
+			appendMessage(chat);
+			mLastMessageIndex = msg["index"].asInteger();
+
+			// if it is a notification - next message is a notification history log, so skip it
+			if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
+			{
+				if (++iter == iter_end)
+				{
+					break;
+				}
+				else
+				{
+					mLastMessageIndex++;
+				}
+			}
+		}
+	}
+}
+
+void LLFloaterIMSession::reloadMessages()
+{
+	mChatHistory->clear();
+	mLastMessageIndex = -1;
+	updateMessages();
+	mInputEditor->setFont(LLViewerChat::getChatFont());
+}
+
+// static
+void LLFloaterIMSession::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
+{
+	LLFloaterIMSession* self= (LLFloaterIMSession*) userdata;
+
+	// Allow enabling the LLFloaterIMSession input editor only if session can accept text
+	LLIMModel::LLIMSession* im_session =
+		LLIMModel::instance().findIMSession(self->mSessionID);
+	//TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
+	if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
+	{
+		//in disconnected state IM input editor should be disabled
+		self->mInputEditor->setEnabled(!gDisconnected);
+	}
+}
+
+// static
+void LLFloaterIMSession::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
+{
+	LLFloaterIMSession* self = (LLFloaterIMSession*) userdata;
+	self->setTyping(false);
+}
+
+// static
+void LLFloaterIMSession::onInputEditorKeystroke(LLTextEditor* caller, void* userdata)
+{
+	LLFloaterIMSession* self = (LLFloaterIMSession*)userdata;
+	std::string text = self->mInputEditor->getText();
+
+		// Deleting all text counts as stopping typing.
+	self->setTyping(!text.empty());
+}
+
+void LLFloaterIMSession::setTyping(bool typing)
+{
+	if ( typing )
+	{
+		// Started or proceeded typing, reset the typing timeout timer
+		mTypingTimeoutTimer.reset();
+	}
+
+	if ( mMeTyping != typing )
+	{
+		// Typing state is changed
+		mMeTyping = typing;
+		// So, should send current state
+		mShouldSendTypingState = true;
+		// In case typing is started, send state after some delay
+		mTypingTimer.reset();
+	}
+
+	// Don't want to send typing indicators to multiple people, potentially too
+	// much network traffic. Only send in person-to-person IMs.
+	if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
+	{
+		// Still typing, send 'start typing' notification or
+		// send 'stop typing' notification immediately
+		if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f)
+		{
+			LLIMModel::instance().sendTypingState(mSessionID,
+					mOtherParticipantUUID, mMeTyping);
+					mShouldSendTypingState = false;
+		}
+	}
+
+	if (!mIsNearbyChat)
+	{
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if (speaker_mgr)
+		{
+			speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
+		}
+	}
+}
+
+void LLFloaterIMSession::processIMTyping(const LLIMInfo* im_info, BOOL typing)
+{
+	if ( typing )
+	{
+		// other user started typing
+		addTypingIndicator(im_info);
+	}
+	else
+	{
+		// other user stopped typing
+		removeTypingIndicator(im_info);
+	}
+}
+
+void LLFloaterIMSession::processAgentListUpdates(const LLSD& body)
+{
+	uuid_vec_t joined_uuids;
+
+	if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap())
+	{
+		LLSD::map_const_iterator update_it;
+		for(update_it = body["agent_updates"].beginMap();
+			update_it != body["agent_updates"].endMap();
+			++update_it)
+		{
+			LLUUID agent_id(update_it->first);
+			LLSD agent_data = update_it->second;
+
+			if (agent_data.isMap())
+			{
+				// store the new participants in joined_uuids
+				if (agent_data.has("transition") && agent_data["transition"].asString() == "ENTER")
+				{
+					joined_uuids.push_back(agent_id);
+				}
+
+				// process the moderator mutes
+				if (agent_id == gAgentID && agent_data.has("info") && agent_data["info"].has("mutes"))
+				{
+					BOOL moderator_muted_text = agent_data["info"]["mutes"]["text"].asBoolean();
+					mInputEditor->setEnabled(!moderator_muted_text);
+					std::string label;
+					if (moderator_muted_text)
+						label = LLTrans::getString("IM_muted_text_label");
+					else
+						label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
+					mInputEditor->setLabel(label);
+
+					if (moderator_muted_text)
+						LLNotificationsUtil::add("TextChatIsMutedByModerator");
+				}
+			}
+		}
+	}
+
+	// the vectors need to be sorted for computing the intersection and difference
+	std::sort(mInvitedParticipants.begin(), mInvitedParticipants.end());
+    std::sort(joined_uuids.begin(), joined_uuids.end());
+
+    uuid_vec_t intersection; // uuids of invited residents who have joined the conversation
+	std::set_intersection(mInvitedParticipants.begin(), mInvitedParticipants.end(),
+						  joined_uuids.begin(), joined_uuids.end(),
+						  std::back_inserter(intersection));
+
+	if (intersection.size() > 0)
+	{
+		sendParticipantsAddedNotification(intersection);
+	}
+
+	// Remove all joined participants from invited array.
+	// The difference between the two vectors (the elements in mInvitedParticipants which are not in joined_uuids)
+	// is placed at the beginning of mInvitedParticipants, then all other elements are erased.
+	mInvitedParticipants.erase(std::set_difference(mInvitedParticipants.begin(), mInvitedParticipants.end(),
+												   joined_uuids.begin(), joined_uuids.end(),
+												   mInvitedParticipants.begin()),
+							   mInvitedParticipants.end());
+}
+
+void LLFloaterIMSession::processSessionUpdate(const LLSD& session_update)
+{
+	// *TODO : verify following code when moderated mode will be implemented
+	if ( false && session_update.has("moderated_mode") &&
+		 session_update["moderated_mode"].has("voice") )
+	{
+		BOOL voice_moderated = session_update["moderated_mode"]["voice"];
+		const std::string session_label = LLIMModel::instance().getName(mSessionID);
+
+		if (voice_moderated)
+		{
+			setTitle(session_label + std::string(" ")
+							+ LLTrans::getString("IM_moderated_chat_label"));
+		}
+		else
+		{
+			setTitle(session_label);
+		}
+
+		// *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added
+		//update the speakers dropdown too
+		//mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
+	}
+}
+
+// virtual
+BOOL LLFloaterIMSession::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+						   std::string& tooltip_msg)
+{
+	if (cargo_type == DAD_PERSON)
+	{
+		if (dropPerson(static_cast<LLUUID*>(cargo_data), drop))
+		{
+			*accept = ACCEPT_YES_MULTI;
+		}
+		else
+		{
+			*accept = ACCEPT_NO;
+		}
+	}
+	else if (mDialog == IM_NOTHING_SPECIAL)
+	{
+		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
+				cargo_type, cargo_data, accept);
+	}
+
+	return TRUE;
+}
+
+bool LLFloaterIMSession::dropPerson(LLUUID* person_id, bool drop)
+{
+	bool res = person_id && person_id->notNull();
+	if(res)
+	{
+		uuid_vec_t ids;
+		ids.push_back(*person_id);
+
+		res = canAddSelectedToChat(ids);
+		if(res && drop)
+		{
+			addSessionParticipants(ids);
+		}
+	}
+
+	return res;
+}
+
+BOOL LLFloaterIMSession::isInviteAllowed() const
+{
+	return ( (IM_SESSION_CONFERENCE_START == mDialog)
+			 || (IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
+			 || mIsP2PChat);
+}
+
+class LLSessionInviteResponder : public LLHTTPClient::Responder
+{
+public:
+	LLSessionInviteResponder(const LLUUID& session_id)
+	{
+		mSessionID = session_id;
+	}
+
+	void error(U32 statusNum, const std::string& reason)
+	{
+		llinfos << "Error inviting all agents to session" << llendl;
+		//throw something back to the viewer here?
+	}
+
+private:
+	LLUUID mSessionID;
+};
+
+BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
+{
+	LLViewerRegion* region = gAgent.getRegion();
+	bool is_region_exist = region != NULL;
+
+	if (is_region_exist)
+	{
+		S32 count = ids.size();
+
+		if( isInviteAllowed() && (count > 0) )
+		{
+			llinfos << "LLFloaterIMSession::inviteToSession() - inviting participants" << llendl;
+
+			std::string url = region->getCapability("ChatSessionRequest");
+
+			LLSD data;
+			data["params"] = LLSD::emptyArray();
+			for (int i = 0; i < count; i++)
+			{
+				data["params"].append(ids[i]);
+			}
+			data["method"] = "invite";
+			data["session-id"] = mSessionID;
+			LLHTTPClient::post(url,	data,new LLSessionInviteResponder(mSessionID));
+		}
+		else
+		{
+			llinfos << "LLFloaterIMSession::inviteToSession -"
+					<< " no need to invite agents for "
+					<< mDialog << llendl;
+			// successful add, because everyone that needed to get added
+			// was added.
+		}
+	}
+
+	return is_region_exist;
+}
+
+void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info)
+{
+	// We may have lost a "stop-typing" packet, don't add it twice
+	if ( im_info && !mOtherTyping )
+	{
+		mOtherTyping = true;
+
+		// Save and set new title
+		mSavedTitle = getTitle();
+		setTitle (mTypingStart);
+
+		// Update speaker
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if ( speaker_mgr )
+		{
+			speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
+		}
+	}
+}
+
+void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info)
+{
+	if ( mOtherTyping )
+	{
+		mOtherTyping = false;
+
+		// Revert the title to saved one
+		setTitle(mSavedTitle);
+
+		if ( im_info )
+		{
+			// Update speaker
+			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+			if ( speaker_mgr )
+			{
+				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
+			}
+		}
+	}
+}
+
+// static
+void LLFloaterIMSession::closeHiddenIMToasts()
+{
+	class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher
+	{
+	public:
+		bool matches(const LLNotificationPtr notification) const
+		{
+			// "notifytoast" type of notifications is reserved for IM notifications
+			return "notifytoast" == notification->getType();
+		}
+	};
+
+	LLNotificationsUI::LLScreenChannel* channel =
+			LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
+	if (channel != NULL)
+	{
+		channel->closeHiddenToasts(IMToastMatcher());
+	}
+}
+// static
+void LLFloaterIMSession::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	const LLSD& payload = notification["payload"];
+	LLUUID session_id = payload["session_id"];
+
+	LLFloater* im_floater = findInstance(session_id);
+	if (option == 0 && im_floater != NULL)
+	{
+		im_floater->closeFloater();
+	}
+
+	return;
+}
+
+// static
+void LLFloaterIMSession::sRemoveTypingIndicator(const LLSD& data)
+{
+	LLUUID session_id = data["session_id"];
+	if (session_id.isNull())
+		return;
+
+	LLUUID from_id = data["from_id"];
+	if (gAgentID == from_id || LLUUID::null == from_id)
+		return;
+
+	LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(session_id);
+	if (!floater)
+		return;
+
+	if (IM_NOTHING_SPECIAL != floater->mDialog)
+		return;
+
+	floater->removeTypingIndicator();
+}
+
+// static
+void LLFloaterIMSession::onIMChicletCreated( const LLUUID& session_id )
+{
+	LLFloaterIMSession::addToHost(session_id);
+}
+
+boost::signals2::connection LLFloaterIMSession::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb)
+{
+	return LLFloaterIMSession::sIMFloaterShowedSignal.connect(cb);
+}
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
new file mode 100644
index 0000000000..f4ec2d457d
--- /dev/null
+++ b/indra/newview/llfloaterimsession.h
@@ -0,0 +1,196 @@
+/** 
+ * @file llfloaterimsession.h
+ * @brief LLFloaterIMSession class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLOATERIMSESSION_H
+#define LL_FLOATERIMSESSION_H
+
+#include "llimview.h"
+#include "llfloaterimsessiontab.h"
+#include "llinstantmessage.h"
+#include "lllogchat.h"
+#include "lltooldraganddrop.h"
+#include "llvoicechannel.h"
+#include "llvoiceclient.h"
+
+class LLAvatarName;
+class LLButton;
+class LLChatEntry;
+class LLTextEditor;
+class LLPanelChatControlPanel;
+class LLChatHistory;
+class LLInventoryItem;
+class LLInventoryCategory;
+
+typedef boost::signals2::signal<void(const LLUUID& session_id)> floater_showed_signal_t;
+
+/**
+ * Individual IM window that appears at the bottom of the screen,
+ * optionally "docked" to the bottom tray.
+ */
+class LLFloaterIMSession
+    : public LLVoiceClientStatusObserver
+    , public LLFloaterIMSessionTab
+{
+	LOG_CLASS(LLFloaterIMSession);
+public:
+	LLFloaterIMSession(const LLUUID& session_id);
+
+	virtual ~LLFloaterIMSession();
+
+	void initIMSession(const LLUUID& session_id);
+	void initIMFloater();
+
+	// LLView overrides
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ BOOL getVisible();
+	// Check typing timeout timer.
+
+	static LLFloaterIMSession* findInstance(const LLUUID& session_id);
+	static LLFloaterIMSession* getInstance(const LLUUID& session_id);
+
+	// LLFloater overrides
+	/*virtual*/ void onClose(bool app_quitting);
+	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+	// Make IM conversion visible and update the message history
+	static LLFloaterIMSession* show(const LLUUID& session_id);
+
+	// Toggle panel specified by session_id
+	// Returns true iff panel became visible
+	static bool toggle(const LLUUID& session_id);
+
+	void sessionInitReplyReceived(const LLUUID& im_session_id);
+
+	// get new messages from LLIMModel
+	/*virtual*/ void updateMessages();
+	void reloadMessages();
+	static void onSendMsg(LLUICtrl*, void*);
+	void sendMsgFromInputEditor();
+	void sendMsg(const std::string& msg);
+
+	// callback for LLIMModel on new messages
+	// route to specific floater if it is visible
+	static void newIMCallback(const LLSD& data);
+
+	// called when docked floater's position has been set by chiclet
+	void setPositioned(bool b) { mPositioned = b; };
+
+	void onVisibilityChange(const LLSD& new_visibility);
+
+	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
+	// button when voice is available
+	void onChange(EStatusType status, const std::string &channelURI,
+			bool proximal);
+
+	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
+	virtual void onVoiceChannelStateChanged(
+			const LLVoiceChannel::EState& old_state,
+			const LLVoiceChannel::EState& new_state);
+
+	void processIMTyping(const LLIMInfo* im_info, BOOL typing);
+	void processAgentListUpdates(const LLSD& body);
+	void processSessionUpdate(const LLSD& session_update);
+
+	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+									   EDragAndDropType cargo_type,
+									   void* cargo_data,
+									   EAcceptance* accept,
+									   std::string& tooltip_msg);
+
+
+	//used as a callback on receiving new IM message
+	static void sRemoveTypingIndicator(const LLSD& data);
+	static void onIMChicletCreated(const LLUUID& session_id);
+
+	bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
+    const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;}
+
+	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
+	static floater_showed_signal_t sIMFloaterShowedSignal;
+
+private:
+
+	/*virtual*/ void refresh();
+
+	/*virtual*/ void onClickCloseBtn();
+
+	// Update the window title and input field help text
+	/*virtual*/ void updateSessionName(const std::string& name);
+
+	bool dropPerson(LLUUID* person_id, bool drop);
+
+	BOOL isInviteAllowed() const;
+	BOOL inviteToSession(const uuid_vec_t& agent_ids);
+	static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
+	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
+	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
+	void setTyping(bool typing);
+	void onAddButtonClicked();
+	void addSessionParticipants(const uuid_vec_t& uuids);
+	void addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids);
+	void sendParticipantsAddedNotification(const uuid_vec_t& uuids);
+	bool canAddSelectedToChat(const uuid_vec_t& uuids);
+
+	void onCallButtonClicked();
+
+	void boundVoiceChannel();
+
+	// Add the "User is typing..." indicator.
+	void addTypingIndicator(const LLIMInfo* im_info);
+
+	// Remove the "User is typing..." indicator.
+	void removeTypingIndicator(const LLIMInfo* im_info = NULL);
+
+	static void closeHiddenIMToasts();
+
+	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
+
+	S32 mLastMessageIndex;
+
+	EInstantMessage mDialog;
+	LLUUID mOtherParticipantUUID;
+	bool mPositioned;
+
+	std::string mSavedTitle;
+	LLUIString mTypingStart;
+	bool mMeTyping;
+	bool mOtherTyping;
+	bool mShouldSendTypingState;
+	LLFrameTimer mTypingTimer;
+	LLFrameTimer mTypingTimeoutTimer;
+
+	bool mSessionInitialized;
+	LLSD mQueuedMsgsForInit;
+
+	bool mStartConferenceInSameFloater;
+
+	uuid_vec_t mInvitedParticipants;
+
+	// connection to voice channel state change signal
+	boost::signals2::connection mVoiceChannelStateChangeConnection;
+};
+
+#endif  // LL_FLOATERIMSESSION_H
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
new file mode 100644
index 0000000000..a47c9177a1
--- /dev/null
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -0,0 +1,743 @@
+/**
+ * @file llfloaterimsessiontab.cpp
+ * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar
+ * @brief and LLFloaterIMSession for hosting both in LLIMContainer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterimsessiontab.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llchatentry.h"
+#include "llchathistory.h"
+#include "llchiclet.h"
+#include "llchicletbar.h"
+#include "lldraghandle.h"
+#include "llfloaterreg.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
+#include "lllayoutstack.h"
+#include "llfloaterimnearbychat.h"
+
+const F32 REFRESH_INTERVAL = 0.2f;
+
+LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
+  : LLTransientDockableFloater(NULL, true, session_id)
+  ,  mIsP2PChat(false)
+  ,  mExpandCollapseBtn(NULL)
+  ,  mTearOffBtn(NULL)
+  ,  mCloseBtn(NULL)
+  ,  mSessionID(session_id.asUUID())
+  , mConversationsRoot(NULL)
+  , mChatHistory(NULL)
+  , mInputEditor(NULL)
+  , mInputEditorTopPad(0)
+  , mRefreshTimer(new LLTimer())
+  , mIsHostAttached(false)
+{
+	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
+			boost::bind(&LLFloaterIMSessionTab::onIMSessionMenuItemClicked,  this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
+			boost::bind(&LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck, this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
+			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck,   this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
+			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable,  this, _2));
+
+	// Zero expiry time is set only once to allow initial update.
+	mRefreshTimer->setTimerExpirySec(0);
+	mRefreshTimer->start();
+}
+
+LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
+{
+	delete mRefreshTimer;
+}
+
+//static
+LLFloaterIMSessionTab* LLFloaterIMSessionTab::findConversation(const LLUUID& uuid)
+{
+	LLFloaterIMSessionTab* conv;
+
+	if (uuid.isNull())
+	{
+		conv = LLFloaterReg::findTypedInstance<LLFloaterIMSessionTab>("nearby_chat");
+	}
+	else
+	{
+		conv = LLFloaterReg::findTypedInstance<LLFloaterIMSessionTab>("impanel", LLSD(uuid));
+	}
+
+	return conv;
+};
+
+//static
+LLFloaterIMSessionTab* LLFloaterIMSessionTab::getConversation(const LLUUID& uuid)
+{
+	LLFloaterIMSessionTab* conv;
+
+	if (uuid.isNull())
+	{
+		conv = LLFloaterReg::getTypedInstance<LLFloaterIMSessionTab>("nearby_chat");
+	}
+	else
+	{
+		conv = LLFloaterReg::getTypedInstance<LLFloaterIMSessionTab>("impanel", LLSD(uuid));
+	}
+
+	return conv;
+};
+
+void LLFloaterIMSessionTab::setVisible(BOOL visible)
+{
+	LLTransientDockableFloater::setVisible(visible);
+
+	if(visible)
+	{
+			LLFloaterIMSessionTab::addToHost(mSessionID);
+	}
+    setFocus(visible);
+}
+
+/*virtual*/
+void LLFloaterIMSessionTab::setFocus(BOOL focus)
+{
+	LLTransientDockableFloater::setFocus(focus);
+
+    //Redirect focus to input editor
+    if (focus)
+	{
+    	updateMessages();
+
+        if (mInputEditor)
+        {
+    	    mInputEditor->setFocus(TRUE);
+        }
+	}
+}
+
+
+void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
+{
+	if ((session_id.notNull() && !gIMMgr->hasSession(session_id))
+			|| !LLFloaterIMSessionTab::isChatMultiTab())
+	{
+		return;
+	}
+
+	// Get the floater: this will create the instance if it didn't exist
+	LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(session_id);
+	if (conversp)
+	{
+		LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+
+		// Do not add again existing floaters
+		if (floater_container && !conversp->isHostAttached())
+		{
+			conversp->setHostAttached(true);
+
+			if (!conversp->isNearbyChat()
+					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
+			{
+				floater_container->addFloater(conversp, TRUE, LLTabContainer::END);
+			}
+			else
+			{
+				// setting of the "potential" host for Nearby Chat: this sequence sets
+				// LLFloater::mHostHandle = NULL (a current host), but
+				// LLFloater::mLastHostHandle = floater_container (a "future" host)
+				conversp->setHost(floater_container);
+				conversp->setHost(NULL);
+			}
+			// Added floaters share some state (like sort order) with their host
+			conversp->setSortOrder(floater_container->getSortOrder());
+		}
+	}
+}
+
+BOOL LLFloaterIMSessionTab::postBuild()
+{
+	BOOL result;
+
+	mCloseBtn = getChild<LLButton>("close_btn");
+	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
+
+	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onSlide, this));
+
+	mTearOffBtn = getChild<LLButton>("tear_off_btn");
+	mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
+
+	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
+	
+	// Create a root view folder for all participants
+	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mParticipantListPanel;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
+    p.use_ellipses = true;
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+	
+	// Add a scroller for the folder (participant) view
+	LLRect scroller_view_rect = mParticipantListPanel->getRect();
+	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
+	scroller_params.rect(scroller_view_rect);
+	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+	scroller->setFollowsAll();
+	
+	// Insert that scroller into the panel widgets hierarchy and folder view
+	mParticipantListPanel->addChild(scroller);
+	scroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(scroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+	
+	
+	mChatHistory = getChild<LLChatHistory>("chat_history");
+
+	mInputEditor = getChild<LLChatEntry>("chat_editor");
+	mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatHistory, this));
+	mInputEditor->setCommitOnFocusLost( FALSE );
+	mInputEditor->setPassDelete(TRUE);
+	mInputEditor->setFont(LLViewerChat::getChatFont());
+
+	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
+
+	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
+
+	buildConversationViewParticipant();
+
+	mSaveRect = isTornOff();
+	initRectControl();
+
+	if (isChatMultiTab())
+	{
+		result = LLFloater::postBuild();
+	}
+	else
+	{
+		result = LLDockableFloater::postBuild();
+	}
+
+	refreshConversation();
+	
+	return result;
+}
+
+LLParticipantList* LLFloaterIMSessionTab::getParticipantList()
+{
+	return dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(mSessionID));
+}
+
+void LLFloaterIMSessionTab::draw()
+{
+	if (mRefreshTimer->hasExpired())
+	{
+		if (getParticipantList())
+		{
+			getParticipantList()->update();
+		}
+
+		refreshConversation();
+
+		// Restart the refresh timer
+		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
+	}
+	
+	LLTransientDockableFloater::draw();
+}
+
+void LLFloaterIMSessionTab::enableDisableCallBtn()
+{
+    getChildView("voice_call_btn")->setEnabled(
+    		mSessionID.notNull()
+    		&& mSession
+    		&& mSession->mSessionInitialized
+    		&& LLVoiceClient::getInstance()->voiceEnabled()
+    		&& LLVoiceClient::getInstance()->isVoiceWorking()
+    		&& mSession->mCallBackEnabled);
+}
+
+void LLFloaterIMSessionTab::onFocusReceived()
+{
+	setBackgroundOpaque(true);
+
+	if (mSessionID.notNull() && isInVisibleChain())
+	{
+		LLIMModel::instance().sendNoUnreadMessages(mSessionID);
+	}
+
+	LLTransientDockableFloater::onFocusReceived();
+
+	LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+	if (container)
+	{
+		container->selectConversationPair(mSessionID, true);
+	}
+}
+
+void LLFloaterIMSessionTab::onFocusLost()
+{
+	setBackgroundOpaque(false);
+	LLTransientDockableFloater::onFocusLost();
+}
+
+std::string LLFloaterIMSessionTab::appendTime()
+{
+	time_t utc_time;
+	utc_time = time_corrected();
+	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+		+LLTrans::getString("TimeMin")+"]";
+
+	LLSD substitution;
+
+	substitution["datetime"] = (S32) utc_time;
+	LLStringUtil::format (timeStr, substitution);
+
+	return timeStr;
+}
+
+void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)
+{
+	// Update the participant activity time
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->setTimeNow(mSessionID,chat.mFromID);
+	}
+	
+
+	LLChat& tmp_chat = const_cast<LLChat&>(chat);
+
+	if(tmp_chat.mTimeStr.empty())
+		tmp_chat.mTimeStr = appendTime();
+
+	if (!chat.mMuted)
+	{
+		tmp_chat.mFromName = chat.mFromName;
+		LLSD chat_args;
+		if (args) chat_args = args;
+		chat_args["use_plain_text_chat_history"] =
+				gSavedSettings.getBOOL("PlainTextChatHistory");
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] =
+				!mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+
+		if (mChatHistory)
+		{
+			mChatHistory->appendMessage(chat, chat_args);
+		}
+	}
+}
+
+
+void LLFloaterIMSessionTab::buildConversationViewParticipant()
+{
+	// Clear the widget list since we are rebuilding afresh from the model
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	while (widget_it != mConversationsWidgets.end())
+	{
+		removeConversationViewParticipant(widget_it->first);
+		// Iterators are invalidated by erase so we need to pick begin again
+		widget_it = mConversationsWidgets.begin();
+	}
+	
+	// Get the model list
+	LLParticipantList* item = getParticipantList();
+	if (!item)
+	{
+		// Nothing to do if the model list is empty
+		return;
+	}
+
+	// Create the participants widgets now
+	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+	while (current_participant_model != end_participant_model)
+	{
+		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+		addConversationViewParticipant(participant_model);
+		current_participant_model++;
+	}
+}
+
+void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model)
+{
+	// Check if the model already has an associated view
+	LLUUID uuid = participant_model->getUUID();
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+	
+	// If not already present, create the participant view and attach it to the root, otherwise, just refresh it
+	if (widget)
+	{
+		updateConversationViewParticipant(uuid); // overkill?
+	}
+	else
+	{
+		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+		mConversationsWidgets[uuid] = participant_view;
+		participant_view->addToFolder(mConversationsRoot);
+		participant_view->setVisible(TRUE);
+		refreshConversation();
+	}
+}
+
+void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& participant_id)
+{
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+	if (widget)
+	{
+		mConversationsRoot->extractItem(widget);
+		delete widget;
+		mConversationsWidgets.erase(participant_id);
+		refreshConversation();
+	}
+}
+
+void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id)
+{
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+	if (widget)
+	{
+		widget->refresh();
+	}
+	refreshConversation();
+}
+
+void LLFloaterIMSessionTab::refreshConversation()
+{
+	// Note: We collect participants names to change the session name only in the case of ad-hoc conversations
+	bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false);
+	uuid_vec_t participants_uuids; // uuids vector for building the added participants name string
+	// For P2P chat, we still need to update the session name who may have changed (switch display name for instance)
+	if (mIsP2PChat && mSession)
+	{
+		participants_uuids.push_back(mSession->mOtherParticipantID);
+	}
+
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	while (widget_it != mConversationsWidgets.end())
+	{
+		// Add the participant to the list except if it's the agent itself (redundant)
+		if (is_ad_hoc && (widget_it->first != gAgentID))
+		{
+			participants_uuids.push_back(widget_it->first);
+		}
+		widget_it->second->refresh();
+		widget_it->second->setVisible(TRUE);
+		++widget_it;
+	}
+	if (is_ad_hoc || mIsP2PChat)
+	{
+		// Build the session name and update it
+		std::string session_name;
+		if (participants_uuids.size() != 0)
+		{
+			LLAvatarActions::buildResidentsString(participants_uuids, session_name);
+		}
+		else
+		{
+			session_name = LLIMModel::instance().getName(mSessionID);
+		}
+		updateSessionName(session_name);
+	} 
+	mConversationViewModel.requestSortAll();
+	mConversationsRoot->arrangeAll();
+	mConversationsRoot->update();
+	updateHeaderAndToolbar();
+	refresh();
+}
+
+// Copied from LLFloaterIMContainer::createConversationViewParticipant(). Refactor opportunity!
+LLConversationViewParticipant* LLFloaterIMSessionTab::createConversationViewParticipant(LLConversationItem* item)
+{
+    LLRect panel_rect = mParticipantListPanel->getRect();
+	
+	LLConversationViewParticipant::Params params;
+	params.name = item->getDisplayName();
+	params.root = mConversationsRoot;
+	params.listener = item;
+	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); // *TODO: use conversation_view_participant.xml itemHeight value in lieu of 24
+	params.tool_tip = params.name;
+	params.participant_id = item->getUUID();
+	
+	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
+void LLFloaterIMSessionTab::setSortOrder(const LLConversationSort& order)
+{
+	mConversationViewModel.setSorter(order);
+	mConversationsRoot->arrangeAll();
+	refreshConversation();
+}
+
+void LLFloaterIMSessionTab::onIMSessionMenuItemClicked(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+
+	if (item == "compact_view" || item == "expanded_view")
+	{
+		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
+	}
+	else
+	{
+		bool prev_value = gSavedSettings.getBOOL(item);
+		gSavedSettings.setBOOL(item, !prev_value);
+	}
+
+	LLFloaterIMSessionTab::processChatHistoryStyleUpdate();
+}
+
+
+bool LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
+
+	return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
+}
+
+
+bool LLFloaterIMSessionTab::onIMShowModesMenuItemCheck(const LLSD& userdata)
+{
+	return gSavedSettings.getBOOL(userdata.asString());
+}
+
+// enable/disable states for the "show time" and "show names" items of the show-modes menu
+bool LLFloaterIMSessionTab::onIMShowModesMenuItemEnable(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
+	bool is_not_names = (item != "IMShowNamesForP2PConv");
+	return (plain_text && (is_not_names || mIsP2PChat));
+}
+
+void LLFloaterIMSessionTab::hideOrShowTitle()
+{
+	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
+	S32 floater_header_size = default_params.header_height;
+	LLView* floater_contents = getChild<LLView>("contents_view");
+
+	LLRect floater_rect = getLocalRect();
+	S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0);
+	LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents);
+	LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom);
+	mDragHandle->setShape(handle_rect);
+	mDragHandle->setVisible(isTornOff());
+	floater_contents->setShape(contents_rect);
+}
+
+void LLFloaterIMSessionTab::updateSessionName(const std::string& name)
+{
+	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
+}
+
+void LLFloaterIMSessionTab::hideAllStandardButtons()
+{
+	for (S32 i = 0; i < BUTTON_COUNT; i++)
+	{
+		if (mButtons[i])
+		{
+			// Hide the standard header buttons in a docked IM floater.
+			mButtons[i]->setVisible(false);
+		}
+	}
+}
+
+void LLFloaterIMSessionTab::updateHeaderAndToolbar()
+{
+	// prevent start conversation before its container
+    LLFloaterIMContainer::getInstance();
+
+	bool is_torn_off = checkIfTornOff();
+	if (!is_torn_off)
+	{
+		hideAllStandardButtons();
+	}
+
+	hideOrShowTitle();
+
+	// Participant list should be visible only in torn off floaters.
+	bool is_participant_list_visible =
+			is_torn_off
+			&& gSavedSettings.getBOOL("IMShowControlPanel")
+			&& !mIsP2PChat;
+
+	mParticipantListPanel->setVisible(is_participant_list_visible);
+
+	// Display collapse image (<<) if the floater is hosted
+	// or if it is torn off but has an open control panel.
+	bool is_expanded = !is_torn_off || is_participant_list_visible;
+	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+
+	// toggle floater's drag handle and title visibility
+	if (mDragHandle)
+	{
+		mDragHandle->setTitleVisible(is_torn_off);
+	}
+
+	// The button (>>) should be disabled for torn off P2P conversations.
+	mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat);
+
+	mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon"));
+	mTearOffBtn->setToolTip(getString(!is_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
+
+	mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat);
+
+	enableDisableCallBtn();
+
+	showTranslationCheckbox();
+}
+
+void LLFloaterIMSessionTab::reshapeChatHistory()
+{
+	LLRect chat_rect  = mChatHistory->getRect();
+	LLRect input_rect = mInputEditor->getRect();
+
+	int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad);
+
+	chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height);
+	mChatHistory->setShape(chat_rect);
+}
+
+void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
+{
+	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE);
+}
+
+// static
+void LLFloaterIMSessionTab::processChatHistoryStyleUpdate()
+{
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+			iter != inst_list.end(); ++iter)
+	{
+		LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
+		if (floater)
+		{
+			floater->reloadMessages();
+		}
+	}
+
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
+	{
+             nearby_chat->reloadMessages();
+	}
+}
+
+void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)
+{
+	getChild<LLButton>("voice_call_btn")->setImageOverlay(
+			callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
+    enableDisableCallBtn();
+
+}
+
+void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
+{
+	LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost());
+	if (host_floater)
+	{
+		// Hide the messages pane if a floater is hosted in the Conversations
+		host_floater->collapseMessagesPane(true);
+	}
+	else ///< floater is torn off
+	{
+		if (!self->mIsP2PChat)
+		{
+			bool expand = !self->mParticipantListPanel->getVisible();
+
+			// Expand/collapse the IM control panel
+			self->mParticipantListPanel->setVisible(expand);
+
+			gSavedSettings.setBOOL("IMShowControlPanel", expand);
+
+			self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon"));
+		}
+	}
+}
+
+/*virtual*/
+void LLFloaterIMSessionTab::onOpen(const LLSD& key)
+{
+	if (!checkIfTornOff())
+	{
+		LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(getHost());
+		// Show the messages pane when opening a floater hosted in the Conversations
+		host_floater->collapseMessagesPane(false);
+	}
+}
+
+// virtual
+void LLFloaterIMSessionTab::onClose(bool app_quitting)
+{
+	// Always suppress the IM from the conversations list on close if present for any reason
+	if (LLFloaterIMSessionTab::isChatMultiTab())
+	{
+		LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+		if (im_box)
+		{
+            im_box->removeConversationListItem(mKey);
+        }
+    }
+}
+
+void LLFloaterIMSessionTab::onTearOffClicked()
+{
+    setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
+    mSaveRect = isTornOff();
+    initRectControl();
+	LLFloater::onClickTearOff(this);
+	refreshConversation();
+}
+
+// static
+bool LLFloaterIMSessionTab::isChatMultiTab()
+{
+	// Restart is required in order to change chat window type.
+	return true;
+}
+
+bool LLFloaterIMSessionTab::checkIfTornOff()
+{
+	bool isTorn = !getHost();
+	
+	if (isTorn != isTornOff())
+	{
+		setTornOff(isTorn);
+		refreshConversation();
+	}
+
+	return isTorn;
+}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
new file mode 100644
index 0000000000..94854ee9ee
--- /dev/null
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -0,0 +1,176 @@
+/**
+ * @file llfloaterimsessiontab.h
+ * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar
+ * @brief and LLFloaterIMSession for hosting both in LLIMContainer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLOATERIMSESSIONTAB_H
+#define LL_FLOATERIMSESSIONTAB_H
+
+#include "lllayoutstack.h"
+#include "llparticipantlist.h"
+#include "lltransientdockablefloater.h"
+#include "llviewercontrol.h"
+#include "lleventtimer.h"
+#include "llimview.h"
+#include "llconversationmodel.h"
+#include "llconversationview.h"
+#include "lltexteditor.h"
+
+class LLPanelChatControlPanel;
+class LLChatEntry;
+class LLChatHistory;
+
+class LLFloaterIMSessionTab
+	: public LLTransientDockableFloater
+{
+
+public:
+	LOG_CLASS(LLFloaterIMSessionTab);
+
+	LLFloaterIMSessionTab(const LLSD& session_id);
+	~LLFloaterIMSessionTab();
+
+	// reload all message with new settings of visual modes
+	static void processChatHistoryStyleUpdate();
+
+	/**
+	 * Returns true if chat is displayed in multi tabbed floater
+	 *         false if chat is displayed in multiple windows
+	 */
+	static bool isChatMultiTab();
+
+	// add conversation to container
+	static void addToHost(const LLUUID& session_id);
+
+	bool isHostAttached() {return mIsHostAttached;}
+	void setHostAttached(bool is_attached) {mIsHostAttached = is_attached;}
+
+    static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid);
+    static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid);
+
+	// show/hide the translation check box
+	void showTranslationCheckbox(const BOOL visible = FALSE);
+
+	bool isNearbyChat() {return mIsNearbyChat;}
+
+	// LLFloater overrides
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onClose(bool app_quitting);
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void draw();
+	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void setFocus(BOOL focus);
+	
+	// Handle the left hand participant list widgets
+	void addConversationViewParticipant(LLConversationItem* item);
+	void removeConversationViewParticipant(const LLUUID& participant_id);
+	void updateConversationViewParticipant(const LLUUID& participant_id);
+	void refreshConversation();
+	void buildConversationViewParticipant();
+
+	void setSortOrder(const LLConversationSort& order);
+	
+	virtual void updateMessages() {}
+
+protected:
+
+	// callback for click on any items of the visual states menu
+	void onIMSessionMenuItemClicked(const LLSD& userdata);
+
+	// callback for check/uncheck of the expanded/collapse mode's switcher
+	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
+
+	//
+	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
+	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
+	static void onSlide(LLFloaterIMSessionTab *self);
+	virtual void onTearOffClicked();
+
+	// refresh a visual state of the Call button
+	void updateCallBtnState(bool callIsActive);
+
+	void hideOrShowTitle(); // toggle the floater's drag handle
+	void hideAllStandardButtons();
+
+	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
+	void updateHeaderAndToolbar();
+
+	// Update the input field help text and other places that need the session name
+	virtual void updateSessionName(const std::string& name);
+
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn();
+
+	// process focus events to set a currently active session
+	/* virtual */ void onFocusLost();
+	/* virtual */ void onFocusReceived();
+
+	// prepare chat's params and out one message to chatHistory
+	void appendMessage(const LLChat& chat, const LLSD &args = 0);
+
+	std::string appendTime();
+
+	bool mIsNearbyChat;
+	bool mIsP2PChat;
+
+	LLIMModel::LLIMSession* mSession;
+
+	// Participants list: model and view
+	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+	
+	LLUUID mSessionID; 
+	LLLayoutPanel* mParticipantListPanel;	// add the widgets to that see mConversationsListPanel
+	LLParticipantList* getParticipantList();
+	conversations_widgets_map mConversationsWidgets;
+	LLConversationViewModel mConversationViewModel;
+	LLFolderView* mConversationsRoot;
+
+	LLChatHistory* mChatHistory;
+	LLChatEntry* mInputEditor;
+	int mInputEditorTopPad; // padding between input field and chat history
+
+	LLButton* mExpandCollapseBtn;
+	LLButton* mTearOffBtn;
+	LLButton* mCloseBtn;
+
+private:
+	/// Refreshes the floater at a constant rate.
+	virtual void refresh() = 0;
+
+	/**
+	 * Adjusts chat history height to fit vertically with input chat field
+	 * and avoid overlapping, since input chat field can be vertically expanded.
+	 * Implementation: chat history bottom "follows" top+top_pad of input chat field
+	 */
+	void reshapeChatHistory();
+
+	bool checkIfTornOff();
+    bool mIsHostAttached;
+
+	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
+};
+
+
+#endif /* LL_FLOATERIMSESSIONTAB_H */
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index b60af1a635..7c5e0776a7 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -51,11 +51,11 @@
 #include "llfloaterabout.h"
 #include "llfloaterhardwaresettings.h"
 #include "llfloatersidepanelcontainer.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llkeyboard.h"
 #include "llmodaldialog.h"
 #include "llnavigationbar.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llnotificationtemplate.h"
@@ -425,7 +425,7 @@ void LLFloaterPreference::saveAvatarProperties( void )
 
 BOOL LLFloaterPreference::postBuild()
 {
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
+	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
 
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index 29d7732a68..6a9236ce0c 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -29,7 +29,7 @@
 #include "llfloatertranslationsettings.h"
 
 // Viewer includes
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "lltranslate.h"
 #include "llviewercontrol.h" // for gSavedSettings
 
@@ -293,7 +293,7 @@ void LLFloaterTranslationSettings::onBtnOK()
 	gSavedSettings.setString("TranslationService", getSelectedService());
 	gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
 	gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
-	(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
 			showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 	closeFloater(false);
 }
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 0996af6125..f307505ff8 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -52,7 +52,7 @@
 #include "llviewermessage.h"
 #include "llvoavatarself.h"
 #include "llviewerstats.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llappearancemgr.h"
 #include "llgesturelistener.h"
 
@@ -998,7 +998,7 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
 
 			const BOOL animate = FALSE;
 
-			(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+			(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
 					sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
 
 			gesture->mCurrentStep++;
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 15eca39bce..a0f2918bd7 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -36,7 +36,7 @@
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llgroupmgr.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h" // for gIMMgr
 #include "llnotificationsutil.h"
 #include "llstatusbar.h"	// can_afford_transaction()
@@ -335,7 +335,7 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id)
 			group_id);
 		if (session_id != LLUUID::null)
 		{
-			LLIMFloaterContainer::getInstance()->showConversation(session_id);
+			LLFloaterIMContainer::getInstance()->showConversation(session_id);
 		}
 		make_ui_sound("UISndStartIM");
 		return session_id;
diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp
index 2f9810775b..188c4bcf25 100644
--- a/indra/newview/llgroupiconctrl.cpp
+++ b/indra/newview/llgroupiconctrl.cpp
@@ -38,7 +38,7 @@
 
 #include "llcachename.h"
 #include "llagentdata.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 */
 
 static LLDefaultChildRegistry::Register<LLGroupIconCtrl> g_i("group_icon");
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
deleted file mode 100644
index a321b3545a..0000000000
--- a/indra/newview/llimconversation.cpp
+++ /dev/null
@@ -1,743 +0,0 @@
-/**
- * @file llimconversation.cpp
- * @brief LLIMConversation class implements the common behavior of LNearbyChatBar
- * @brief and LLIMFloater for hosting both in LLIMContainer
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llimconversation.h"
-
-#include "llagent.h"
-#include "llavataractions.h"
-#include "llchatentry.h"
-#include "llchathistory.h"
-#include "llchiclet.h"
-#include "llchicletbar.h"
-#include "lldraghandle.h"
-#include "llfloaterreg.h"
-#include "llimfloater.h"
-#include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
-#include "lllayoutstack.h"
-#include "llnearbychat.h"
-
-const F32 REFRESH_INTERVAL = 0.2f;
-
-LLIMConversation::LLIMConversation(const LLSD& session_id)
-  : LLTransientDockableFloater(NULL, true, session_id)
-  ,  mIsP2PChat(false)
-  ,  mExpandCollapseBtn(NULL)
-  ,  mTearOffBtn(NULL)
-  ,  mCloseBtn(NULL)
-  ,  mSessionID(session_id.asUUID())
-  , mConversationsRoot(NULL)
-  , mChatHistory(NULL)
-  , mInputEditor(NULL)
-  , mInputEditorTopPad(0)
-  , mRefreshTimer(new LLTimer())
-  , mIsHostAttached(false)
-{
-	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
-
-	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
-			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
-			boost::bind(&LLIMConversation::onIMCompactExpandedMenuItemCheck, this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
-			boost::bind(&LLIMConversation::onIMShowModesMenuItemCheck,   this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
-			boost::bind(&LLIMConversation::onIMShowModesMenuItemEnable,  this, _2));
-
-	// Zero expiry time is set only once to allow initial update.
-	mRefreshTimer->setTimerExpirySec(0);
-	mRefreshTimer->start();
-}
-
-LLIMConversation::~LLIMConversation()
-{
-	delete mRefreshTimer;
-}
-
-//static
-LLIMConversation* LLIMConversation::findConversation(const LLUUID& uuid)
-{
-	LLIMConversation* conv;
-
-	if (uuid.isNull())
-	{
-		conv = LLFloaterReg::findTypedInstance<LLIMConversation>("nearby_chat");
-	}
-	else
-	{
-		conv = LLFloaterReg::findTypedInstance<LLIMConversation>("impanel", LLSD(uuid));
-	}
-
-	return conv;
-};
-
-//static
-LLIMConversation* LLIMConversation::getConversation(const LLUUID& uuid)
-{
-	LLIMConversation* conv;
-
-	if (uuid.isNull())
-	{
-		conv = LLFloaterReg::getTypedInstance<LLIMConversation>("nearby_chat");
-	}
-	else
-	{
-		conv = LLFloaterReg::getTypedInstance<LLIMConversation>("impanel", LLSD(uuid));
-	}
-
-	return conv;
-};
-
-void LLIMConversation::setVisible(BOOL visible)
-{
-	LLTransientDockableFloater::setVisible(visible);
-
-	if(visible)
-	{
-			LLIMConversation::addToHost(mSessionID);
-	}
-    setFocus(visible);
-}
-
-/*virtual*/
-void LLIMConversation::setFocus(BOOL focus)
-{
-	LLTransientDockableFloater::setFocus(focus);
-
-    //Redirect focus to input editor
-    if (focus)
-	{
-    	updateMessages();
-
-        if (mInputEditor)
-        {
-    	    mInputEditor->setFocus(TRUE);
-        }
-	}
-}
-
-
-void LLIMConversation::addToHost(const LLUUID& session_id)
-{
-	if ((session_id.notNull() && !gIMMgr->hasSession(session_id))
-			|| !LLIMConversation::isChatMultiTab())
-	{
-		return;
-	}
-
-	// Get the floater: this will create the instance if it didn't exist
-	LLIMConversation* conversp = LLIMConversation::getConversation(session_id);
-	if (conversp)
-	{
-		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
-
-		// Do not add again existing floaters
-		if (floater_container && !conversp->isHostAttached())
-		{
-			conversp->setHostAttached(true);
-
-			if (!conversp->isNearbyChat()
-					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
-			{
-				floater_container->addFloater(conversp, TRUE, LLTabContainer::END);
-			}
-			else
-			{
-				// setting of the "potential" host for Nearby Chat: this sequence sets
-				// LLFloater::mHostHandle = NULL (a current host), but
-				// LLFloater::mLastHostHandle = floater_container (a "future" host)
-				conversp->setHost(floater_container);
-				conversp->setHost(NULL);
-			}
-			// Added floaters share some state (like sort order) with their host
-			conversp->setSortOrder(floater_container->getSortOrder());
-		}
-	}
-}
-
-BOOL LLIMConversation::postBuild()
-{
-	BOOL result;
-
-	mCloseBtn = getChild<LLButton>("close_btn");
-	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
-
-	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
-	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this));
-
-	mTearOffBtn = getChild<LLButton>("tear_off_btn");
-	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
-
-	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
-	
-	// Create a root view folder for all participants
-	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
-    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
-    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
-    p.parent_panel = mParticipantListPanel;
-    p.listener = base_item;
-    p.view_model = &mConversationViewModel;
-    p.root = NULL;
-    p.use_ellipses = true;
-	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
-    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
-	
-	// Add a scroller for the folder (participant) view
-	LLRect scroller_view_rect = mParticipantListPanel->getRect();
-	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
-	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
-	scroller_params.rect(scroller_view_rect);
-	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
-	scroller->setFollowsAll();
-	
-	// Insert that scroller into the panel widgets hierarchy and folder view
-	mParticipantListPanel->addChild(scroller);
-	scroller->addChild(mConversationsRoot);
-	mConversationsRoot->setScrollContainer(scroller);
-	mConversationsRoot->setFollowsAll();
-	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
-	
-	
-	mChatHistory = getChild<LLChatHistory>("chat_history");
-
-	mInputEditor = getChild<LLChatEntry>("chat_editor");
-	mInputEditor->setTextExpandedCallback(boost::bind(&LLIMConversation::reshapeChatHistory, this));
-	mInputEditor->setCommitOnFocusLost( FALSE );
-	mInputEditor->setPassDelete(TRUE);
-	mInputEditor->setFont(LLViewerChat::getChatFont());
-
-	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
-
-	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
-
-	buildConversationViewParticipant();
-
-	mSaveRect = isTornOff();
-	initRectControl();
-
-	if (isChatMultiTab())
-	{
-		result = LLFloater::postBuild();
-	}
-	else
-	{
-		result = LLDockableFloater::postBuild();
-	}
-
-	refreshConversation();
-	
-	return result;
-}
-
-LLParticipantList* LLIMConversation::getParticipantList()
-{
-	return dynamic_cast<LLParticipantList*>(LLIMFloaterContainer::getInstance()->getSessionModel(mSessionID));
-}
-
-void LLIMConversation::draw()
-{
-	if (mRefreshTimer->hasExpired())
-	{
-		if (getParticipantList())
-		{
-			getParticipantList()->update();
-		}
-
-		refreshConversation();
-
-		// Restart the refresh timer
-		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
-	}
-	
-	LLTransientDockableFloater::draw();
-}
-
-void LLIMConversation::enableDisableCallBtn()
-{
-    getChildView("voice_call_btn")->setEnabled(
-    		mSessionID.notNull()
-    		&& mSession
-    		&& mSession->mSessionInitialized
-    		&& LLVoiceClient::getInstance()->voiceEnabled()
-    		&& LLVoiceClient::getInstance()->isVoiceWorking()
-    		&& mSession->mCallBackEnabled);
-}
-
-void LLIMConversation::onFocusReceived()
-{
-	setBackgroundOpaque(true);
-
-	if (mSessionID.notNull() && isInVisibleChain())
-	{
-		LLIMModel::instance().sendNoUnreadMessages(mSessionID);
-	}
-
-	LLTransientDockableFloater::onFocusReceived();
-
-	LLIMFloaterContainer* container = LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
-	if (container)
-	{
-		container->selectConversationPair(mSessionID, true);
-	}
-}
-
-void LLIMConversation::onFocusLost()
-{
-	setBackgroundOpaque(false);
-	LLTransientDockableFloater::onFocusLost();
-}
-
-std::string LLIMConversation::appendTime()
-{
-	time_t utc_time;
-	utc_time = time_corrected();
-	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
-		+LLTrans::getString("TimeMin")+"]";
-
-	LLSD substitution;
-
-	substitution["datetime"] = (S32) utc_time;
-	LLStringUtil::format (timeStr, substitution);
-
-	return timeStr;
-}
-
-void LLIMConversation::appendMessage(const LLChat& chat, const LLSD &args)
-{
-	// Update the participant activity time
-	LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
-	if (im_box)
-	{
-		im_box->setTimeNow(mSessionID,chat.mFromID);
-	}
-	
-
-	LLChat& tmp_chat = const_cast<LLChat&>(chat);
-
-	if(tmp_chat.mTimeStr.empty())
-		tmp_chat.mTimeStr = appendTime();
-
-	if (!chat.mMuted)
-	{
-		tmp_chat.mFromName = chat.mFromName;
-		LLSD chat_args;
-		if (args) chat_args = args;
-		chat_args["use_plain_text_chat_history"] =
-				gSavedSettings.getBOOL("PlainTextChatHistory");
-		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
-		chat_args["show_names_for_p2p_conv"] =
-				!mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
-
-		if (mChatHistory)
-		{
-			mChatHistory->appendMessage(chat, chat_args);
-		}
-	}
-}
-
-
-void LLIMConversation::buildConversationViewParticipant()
-{
-	// Clear the widget list since we are rebuilding afresh from the model
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
-	while (widget_it != mConversationsWidgets.end())
-	{
-		removeConversationViewParticipant(widget_it->first);
-		// Iterators are invalidated by erase so we need to pick begin again
-		widget_it = mConversationsWidgets.begin();
-	}
-	
-	// Get the model list
-	LLParticipantList* item = getParticipantList();
-	if (!item)
-	{
-		// Nothing to do if the model list is empty
-		return;
-	}
-
-	// Create the participants widgets now
-	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
-	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
-	while (current_participant_model != end_participant_model)
-	{
-		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
-		addConversationViewParticipant(participant_model);
-		current_participant_model++;
-	}
-}
-
-void LLIMConversation::addConversationViewParticipant(LLConversationItem* participant_model)
-{
-	// Check if the model already has an associated view
-	LLUUID uuid = participant_model->getUUID();
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
-	
-	// If not already present, create the participant view and attach it to the root, otherwise, just refresh it
-	if (widget)
-	{
-		updateConversationViewParticipant(uuid); // overkill?
-	}
-	else
-	{
-		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
-		mConversationsWidgets[uuid] = participant_view;
-		participant_view->addToFolder(mConversationsRoot);
-		participant_view->setVisible(TRUE);
-		refreshConversation();
-	}
-}
-
-void LLIMConversation::removeConversationViewParticipant(const LLUUID& participant_id)
-{
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
-	if (widget)
-	{
-		mConversationsRoot->extractItem(widget);
-		delete widget;
-		mConversationsWidgets.erase(participant_id);
-		refreshConversation();
-	}
-}
-
-void LLIMConversation::updateConversationViewParticipant(const LLUUID& participant_id)
-{
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
-	if (widget)
-	{
-		widget->refresh();
-	}
-	refreshConversation();
-}
-
-void LLIMConversation::refreshConversation()
-{
-	// Note: We collect participants names to change the session name only in the case of ad-hoc conversations
-	bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false);
-	uuid_vec_t participants_uuids; // uuids vector for building the added participants name string
-	// For P2P chat, we still need to update the session name who may have changed (switch display name for instance)
-	if (mIsP2PChat && mSession)
-	{
-		participants_uuids.push_back(mSession->mOtherParticipantID);
-	}
-
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
-	while (widget_it != mConversationsWidgets.end())
-	{
-		// Add the participant to the list except if it's the agent itself (redundant)
-		if (is_ad_hoc && (widget_it->first != gAgentID))
-		{
-			participants_uuids.push_back(widget_it->first);
-		}
-		widget_it->second->refresh();
-		widget_it->second->setVisible(TRUE);
-		++widget_it;
-	}
-	if (is_ad_hoc || mIsP2PChat)
-	{
-		// Build the session name and update it
-		std::string session_name;
-		if (participants_uuids.size() != 0)
-		{
-			LLAvatarActions::buildResidentsString(participants_uuids, session_name);
-		}
-		else
-		{
-			session_name = LLIMModel::instance().getName(mSessionID);
-		}
-		updateSessionName(session_name);
-	} 
-	mConversationViewModel.requestSortAll();
-	mConversationsRoot->arrangeAll();
-	mConversationsRoot->update();
-	updateHeaderAndToolbar();
-	refresh();
-}
-
-// Copied from LLIMFloaterContainer::createConversationViewParticipant(). Refactor opportunity!
-LLConversationViewParticipant* LLIMConversation::createConversationViewParticipant(LLConversationItem* item)
-{
-    LLRect panel_rect = mParticipantListPanel->getRect();
-	
-	LLConversationViewParticipant::Params params;
-	params.name = item->getDisplayName();
-	params.root = mConversationsRoot;
-	params.listener = item;
-	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); // *TODO: use conversation_view_participant.xml itemHeight value in lieu of 24
-	params.tool_tip = params.name;
-	params.participant_id = item->getUUID();
-	
-	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
-}
-
-void LLIMConversation::setSortOrder(const LLConversationSort& order)
-{
-	mConversationViewModel.setSorter(order);
-	mConversationsRoot->arrangeAll();
-	refreshConversation();
-}
-
-void LLIMConversation::onIMSessionMenuItemClicked(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-
-	if (item == "compact_view" || item == "expanded_view")
-	{
-		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
-	}
-	else
-	{
-		bool prev_value = gSavedSettings.getBOOL(item);
-		gSavedSettings.setBOOL(item, !prev_value);
-	}
-
-	LLIMConversation::processChatHistoryStyleUpdate();
-}
-
-
-bool LLIMConversation::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-	bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
-
-	return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
-}
-
-
-bool LLIMConversation::onIMShowModesMenuItemCheck(const LLSD& userdata)
-{
-	return gSavedSettings.getBOOL(userdata.asString());
-}
-
-// enable/disable states for the "show time" and "show names" items of the show-modes menu
-bool LLIMConversation::onIMShowModesMenuItemEnable(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
-	bool is_not_names = (item != "IMShowNamesForP2PConv");
-	return (plain_text && (is_not_names || mIsP2PChat));
-}
-
-void LLIMConversation::hideOrShowTitle()
-{
-	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
-	S32 floater_header_size = default_params.header_height;
-	LLView* floater_contents = getChild<LLView>("contents_view");
-
-	LLRect floater_rect = getLocalRect();
-	S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0);
-	LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents);
-	LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom);
-	mDragHandle->setShape(handle_rect);
-	mDragHandle->setVisible(isTornOff());
-	floater_contents->setShape(contents_rect);
-}
-
-void LLIMConversation::updateSessionName(const std::string& name)
-{
-	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
-}
-
-void LLIMConversation::hideAllStandardButtons()
-{
-	for (S32 i = 0; i < BUTTON_COUNT; i++)
-	{
-		if (mButtons[i])
-		{
-			// Hide the standard header buttons in a docked IM floater.
-			mButtons[i]->setVisible(false);
-		}
-	}
-}
-
-void LLIMConversation::updateHeaderAndToolbar()
-{
-	// prevent start conversation before its container
-    LLIMFloaterContainer::getInstance();
-
-	bool is_torn_off = checkIfTornOff();
-	if (!is_torn_off)
-	{
-		hideAllStandardButtons();
-	}
-
-	hideOrShowTitle();
-
-	// Participant list should be visible only in torn off floaters.
-	bool is_participant_list_visible =
-			is_torn_off
-			&& gSavedSettings.getBOOL("IMShowControlPanel")
-			&& !mIsP2PChat;
-
-	mParticipantListPanel->setVisible(is_participant_list_visible);
-
-	// Display collapse image (<<) if the floater is hosted
-	// or if it is torn off but has an open control panel.
-	bool is_expanded = !is_torn_off || is_participant_list_visible;
-	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
-
-	// toggle floater's drag handle and title visibility
-	if (mDragHandle)
-	{
-		mDragHandle->setTitleVisible(is_torn_off);
-	}
-
-	// The button (>>) should be disabled for torn off P2P conversations.
-	mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat);
-
-	mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon"));
-	mTearOffBtn->setToolTip(getString(!is_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
-
-	mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat);
-
-	enableDisableCallBtn();
-
-	showTranslationCheckbox();
-}
-
-void LLIMConversation::reshapeChatHistory()
-{
-	LLRect chat_rect  = mChatHistory->getRect();
-	LLRect input_rect = mInputEditor->getRect();
-
-	int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad);
-
-	chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height);
-	mChatHistory->setShape(chat_rect);
-}
-
-void LLIMConversation::showTranslationCheckbox(BOOL show)
-{
-	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE);
-}
-
-// static
-void LLIMConversation::processChatHistoryStyleUpdate()
-{
-	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
-	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
-			iter != inst_list.end(); ++iter)
-	{
-		LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
-		if (floater)
-		{
-			floater->reloadMessages();
-		}
-	}
-
-	LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
-	if (nearby_chat)
-	{
-             nearby_chat->reloadMessages();
-	}
-}
-
-void LLIMConversation::updateCallBtnState(bool callIsActive)
-{
-	getChild<LLButton>("voice_call_btn")->setImageOverlay(
-			callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
-    enableDisableCallBtn();
-
-}
-
-void LLIMConversation::onSlide(LLIMConversation* self)
-{
-	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(self->getHost());
-	if (host_floater)
-	{
-		// Hide the messages pane if a floater is hosted in the Conversations
-		host_floater->collapseMessagesPane(true);
-	}
-	else ///< floater is torn off
-	{
-		if (!self->mIsP2PChat)
-		{
-			bool expand = !self->mParticipantListPanel->getVisible();
-
-			// Expand/collapse the IM control panel
-			self->mParticipantListPanel->setVisible(expand);
-
-			gSavedSettings.setBOOL("IMShowControlPanel", expand);
-
-			self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon"));
-		}
-	}
-}
-
-/*virtual*/
-void LLIMConversation::onOpen(const LLSD& key)
-{
-	if (!checkIfTornOff())
-	{
-		LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
-		// Show the messages pane when opening a floater hosted in the Conversations
-		host_floater->collapseMessagesPane(false);
-	}
-}
-
-// virtual
-void LLIMConversation::onClose(bool app_quitting)
-{
-	// Always suppress the IM from the conversations list on close if present for any reason
-	if (LLIMConversation::isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
-		if (im_box)
-		{
-            im_box->removeConversationListItem(mKey);
-        }
-    }
-}
-
-void LLIMConversation::onTearOffClicked()
-{
-    setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
-    mSaveRect = isTornOff();
-    initRectControl();
-	LLFloater::onClickTearOff(this);
-	refreshConversation();
-}
-
-// static
-bool LLIMConversation::isChatMultiTab()
-{
-	// Restart is required in order to change chat window type.
-	return true;
-}
-
-bool LLIMConversation::checkIfTornOff()
-{
-	bool isTorn = !getHost();
-	
-	if (isTorn != isTornOff())
-	{
-		setTornOff(isTorn);
-		refreshConversation();
-	}
-
-	return isTorn;
-}
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
deleted file mode 100644
index 93a1ab847e..0000000000
--- a/indra/newview/llimconversation.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * @file llimconversation.h
- * @brief LLIMConversation class implements the common behavior of LNearbyChatBar
- * @brief and LLIMFloater for hosting both in LLIMContainer
- *
- * $LicenseInfo:firstyear=2012&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_IMCONVERSATION_H
-#define LL_IMCONVERSATION_H
-
-#include "lllayoutstack.h"
-#include "llparticipantlist.h"
-#include "lltransientdockablefloater.h"
-#include "llviewercontrol.h"
-#include "lleventtimer.h"
-#include "llimview.h"
-#include "llconversationmodel.h"
-#include "llconversationview.h"
-#include "lltexteditor.h"
-
-class LLPanelChatControlPanel;
-class LLChatEntry;
-class LLChatHistory;
-
-class LLIMConversation
-	: public LLTransientDockableFloater
-{
-
-public:
-	LOG_CLASS(LLIMConversation);
-
-	LLIMConversation(const LLSD& session_id);
-	~LLIMConversation();
-
-	// reload all message with new settings of visual modes
-	static void processChatHistoryStyleUpdate();
-
-	/**
-	 * Returns true if chat is displayed in multi tabbed floater
-	 *         false if chat is displayed in multiple windows
-	 */
-	static bool isChatMultiTab();
-
-	// add conversation to container
-	static void addToHost(const LLUUID& session_id);
-
-	bool isHostAttached() {return mIsHostAttached;}
-	void setHostAttached(bool is_attached) {mIsHostAttached = is_attached;}
-
-    static LLIMConversation* findConversation(const LLUUID& uuid);
-    static LLIMConversation* getConversation(const LLUUID& uuid);
-
-	// show/hide the translation check box
-	void showTranslationCheckbox(const BOOL visible = FALSE);
-
-	bool isNearbyChat() {return mIsNearbyChat;}
-
-	// LLFloater overrides
-	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void onClose(bool app_quitting);
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void draw();
-	/*virtual*/ void setVisible(BOOL visible);
-	/*virtual*/ void setFocus(BOOL focus);
-	
-	// Handle the left hand participant list widgets
-	void addConversationViewParticipant(LLConversationItem* item);
-	void removeConversationViewParticipant(const LLUUID& participant_id);
-	void updateConversationViewParticipant(const LLUUID& participant_id);
-	void refreshConversation();
-	void buildConversationViewParticipant();
-
-	void setSortOrder(const LLConversationSort& order);
-	
-	virtual void updateMessages() {}
-
-protected:
-
-	// callback for click on any items of the visual states menu
-	void onIMSessionMenuItemClicked(const LLSD& userdata);
-
-	// callback for check/uncheck of the expanded/collapse mode's switcher
-	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
-
-	//
-	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
-	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
-	static void onSlide(LLIMConversation *self);
-	virtual void onTearOffClicked();
-
-	// refresh a visual state of the Call button
-	void updateCallBtnState(bool callIsActive);
-
-	void hideOrShowTitle(); // toggle the floater's drag handle
-	void hideAllStandardButtons();
-
-	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
-	void updateHeaderAndToolbar();
-
-	// Update the input field help text and other places that need the session name
-	virtual void updateSessionName(const std::string& name);
-
-	// set the enable/disable state for the Call button
-	virtual void enableDisableCallBtn();
-
-	// process focus events to set a currently active session
-	/* virtual */ void onFocusLost();
-	/* virtual */ void onFocusReceived();
-
-	// prepare chat's params and out one message to chatHistory
-	void appendMessage(const LLChat& chat, const LLSD &args = 0);
-
-	std::string appendTime();
-
-	bool mIsNearbyChat;
-	bool mIsP2PChat;
-
-	LLIMModel::LLIMSession* mSession;
-
-	// Participants list: model and view
-	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
-	
-	LLUUID mSessionID; 
-	LLLayoutPanel* mParticipantListPanel;	// add the widgets to that see mConversationsListPanel
-	LLParticipantList* getParticipantList();
-	conversations_widgets_map mConversationsWidgets;
-	LLConversationViewModel mConversationViewModel;
-	LLFolderView* mConversationsRoot;
-
-	LLChatHistory* mChatHistory;
-	LLChatEntry* mInputEditor;
-	int mInputEditorTopPad; // padding between input field and chat history
-
-	LLButton* mExpandCollapseBtn;
-	LLButton* mTearOffBtn;
-	LLButton* mCloseBtn;
-
-private:
-	/// Refreshes the floater at a constant rate.
-	virtual void refresh() = 0;
-
-	/**
-	 * Adjusts chat history height to fit vertically with input chat field
-	 * and avoid overlapping, since input chat field can be vertically expanded.
-	 * Implementation: chat history bottom "follows" top+top_pad of input chat field
-	 */
-	void reshapeChatHistory();
-
-	bool checkIfTornOff();
-    bool mIsHostAttached;
-
-	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
-};
-
-
-#endif // LL_IMCONVERSATION_H
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
deleted file mode 100644
index 73c7be37eb..0000000000
--- a/indra/newview/llimfloater.cpp
+++ /dev/null
@@ -1,1202 +0,0 @@
-/** 
- * @file llimfloater.cpp
- * @brief LLIMFloater class definition
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llimfloater.h"
-
-#include "lldraghandle.h"
-#include "llnotificationsutil.h"
-
-#include "llagent.h"
-#include "llappviewer.h"
-#include "llavataractions.h"
-#include "llavatarnamecache.h"
-#include "llbutton.h"
-#include "llchannelmanager.h"
-#include "llchiclet.h"
-#include "llchicletbar.h"
-#include "llfloaterreg.h"
-#include "llfloateravatarpicker.h"
-#include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
-#include "llinventoryfunctions.h"
-//#include "lllayoutstack.h"
-#include "llchatentry.h"
-#include "lllogchat.h"
-#include "llscreenchannel.h"
-#include "llsyswellwindow.h"
-#include "lltrans.h"
-#include "llchathistory.h"
-#include "llnotifications.h"
-#include "llviewerwindow.h"
-#include "lltransientfloatermgr.h"
-#include "llinventorymodel.h"
-#include "llrootview.h"
-#include "llspeakers.h"
-#include "llviewerchat.h"
-#include "llnotificationmanager.h"
-#include "llautoreplace.h"
-
-floater_showed_signal_t LLIMFloater::sIMFloaterShowedSignal;
-
-LLIMFloater::LLIMFloater(const LLUUID& session_id)
-  : LLIMConversation(session_id),
-	mLastMessageIndex(-1),
-	mDialog(IM_NOTHING_SPECIAL),
-	mSavedTitle(),
-	mTypingStart(),
-	mShouldSendTypingState(false),
-	mMeTyping(false),
-	mOtherTyping(false),
-	mTypingTimer(),
-	mTypingTimeoutTimer(),
-	mPositioned(false),
-	mSessionInitialized(false),
-	mStartConferenceInSameFloater(false)
-{
-	mIsNearbyChat = false;
-
-	initIMSession(session_id);
-		
-	setOverlapsScreenChannel(true);
-
-	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
-
-	setDocked(true);
-}
-
-
-// virtual
-void LLIMFloater::refresh()
-{
-	if (mMeTyping)
-{
-		// Time out if user hasn't typed for a while.
-		if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS)
-		{
-	setTyping(false);
-		}
-	}
-}
-
-// virtual
-void LLIMFloater::onClickCloseBtn()
-{
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
-
-	if (session != NULL)
-	{
-		bool is_call_with_chat = session->isGroupSessionType()
-				|| session->isAdHocSessionType() || session->isP2PSessionType();
-
-		LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-		if (is_call_with_chat && voice_channel != NULL
-				&& voice_channel->isActive())
-		{
-			LLSD payload;
-			payload["session_id"] = mSessionID;
-			LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
-			return;
-		}
-	}
-	else
-	{
-		llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl;
-		return;
-	}
-
-	LLIMConversation::onClickCloseBtn();
-}
-
-/* static */
-void LLIMFloater::newIMCallback(const LLSD& data)
-{
-	if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull())
-	{
-		LLUUID session_id = data["session_id"].asUUID();
-
-		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-
-        // update if visible, otherwise will be updated when opened
-		if (floater && floater->getVisible())
-		{
-			floater->updateMessages();
-		}
-	}
-}
-
-void LLIMFloater::onVisibilityChange(const LLSD& new_visibility)
-{
-	bool visible = new_visibility.asBoolean();
-
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-	if (visible && voice_channel &&
-		voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
-	{
-		LLFloaterReg::showInstance("voice_call", mSessionID);
-	}
-	else
-	{
-		LLFloaterReg::hideInstance("voice_call", mSessionID);
-	}
-}
-
-void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
-{
-	LLIMFloater* self = (LLIMFloater*) userdata;
-	self->sendMsgFromInputEditor();
-	self->setTyping(false);
-}
-
-void LLIMFloater::sendMsgFromInputEditor()
-{
-	if (gAgent.isGodlike()
-		|| (mDialog != IM_NOTHING_SPECIAL)
-		|| !mOtherParticipantUUID.isNull())
-	{
-		if (mInputEditor)
-		{
-			LLWString text = mInputEditor->getWText();
-			LLWStringUtil::trim(text);
-			LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
-			if(!text.empty())
-			{
-				// Truncate and convert to UTF8 for transport
-				std::string utf8_text = wstring_to_utf8str(text);
-
-				sendMsg(utf8_text);
-
-				mInputEditor->setText(LLStringUtil::null);
-			}
-		}
-	}
-	else
-	{
-		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
-	}
-}
-
-void LLIMFloater::sendMsg(const std::string& msg)
-{
-	const std::string utf8_text = utf8str_truncate(msg, MAX_MSG_BUF_SIZE - 1);
-
-	if (mSessionInitialized)
-	{
-		LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
-	}
-	else
-	{
-		//queue up the message to send once the session is initialized
-		mQueuedMsgsForInit.append(utf8_text);
-	}
-
-	updateMessages();
-}
-
-LLIMFloater::~LLIMFloater()
-{
-	mVoiceChannelStateChangeConnection.disconnect();
-	if(LLVoiceClient::instanceExists())
-	{
-		LLVoiceClient::getInstance()->removeObserver(this);
-	}
-
-	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
-}
-
-
-void LLIMFloater::initIMSession(const LLUUID& session_id)
-{
-	// Change the floater key to bind it to a new session.
-	setKey(session_id);
-
-	mSessionID = session_id;
-	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
-
-	if (mSession)
-	{
-		mIsP2PChat = mSession->isP2PSessionType();
-		mSessionInitialized = mSession->mSessionInitialized;
-		mDialog = mSession->mType;
-	}
-}
-
-void LLIMFloater::initIMFloater()
-{
-	const LLUUID& other_party_id =
-			LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
-	if (other_party_id.notNull())
-	{
-		mOtherParticipantUUID = other_party_id;
-	}
-
-	boundVoiceChannel();
-
-	mTypingStart = LLTrans::getString("IM_typing_start_string");
-
-	// Show control panel in torn off floaters only.
-	mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel"));
-
-	// Disable input editor if session cannot accept text
-	if ( mSession && !mSession->mTextIMPossible )
-	{
-		mInputEditor->setEnabled(FALSE);
-		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
-	}
-
-	if (!mIsP2PChat)
-	{
-		std::string session_name(LLIMModel::instance().getName(mSessionID));
-		updateSessionName(session_name);
-	}
-}
-
-//virtual
-BOOL LLIMFloater::postBuild()
-{
-	BOOL result = LLIMConversation::postBuild();
-
-	mInputEditor->setMaxTextLength(1023);
-	// enable line history support for instant message bar
-	// XXX stinson TODO : resolve merge by adding autoreplace to text editors
-#if 0
-	// *TODO Establish LineEditor with autoreplace callback
-	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
-#endif
-	
-	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
-	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
-	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
-	mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this));
-
-	setDocked(true);
-
-	LLButton* add_btn = getChild<LLButton>("add_btn");
-
-	// Allow to add chat participants depending on the session type
-	add_btn->setEnabled(isInviteAllowed());
-	add_btn->setClickedCallback(boost::bind(&LLIMFloater::onAddButtonClicked, this));
-
-	childSetAction("voice_call_btn", boost::bind(&LLIMFloater::onCallButtonClicked, this));
-
-	LLVoiceClient::getInstance()->addObserver(this);
-	
-	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
-	//see LLFloaterIMPanel for how it is done (IB)
-
-	initIMFloater();
-
-	return result;
-}
-
-void LLIMFloater::onAddButtonClicked()
-{
-    LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn");
-    LLFloater* root_floater = gFloaterView->getParentFloater(this);
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloater::addSessionParticipants, this, _1), TRUE, TRUE, FALSE, root_floater->getName(), button);
-	if (!picker)
-	{
-		return;
-	}
-
-	// Need to disable 'ok' button when selected users are already in conversation.
-	picker->setOkBtnEnableCb(boost::bind(&LLIMFloater::canAddSelectedToChat, this, _1));
-	
-	if (root_floater)
-	{
-		root_floater->addDependentFloater(picker);
-	}
-}
-
-bool LLIMFloater::canAddSelectedToChat(const uuid_vec_t& uuids)
-{
-	if (!mSession
-		|| mDialog == IM_SESSION_GROUP_START
-		|| mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID))
-	{
-		return false;
-	}
-
-	if (mIsP2PChat)
-	{
-		// For a P2P session just check if we are not adding the other participant.
-
-		for (uuid_vec_t::const_iterator id = uuids.begin();
-				id != uuids.end(); ++id)
-		{
-			if (*id == mOtherParticipantUUID)
-			{
-				return false;
-			}
-		}
-	}
-	else
-	{
-		// For a conference session we need to check against the list from LLSpeakerMgr,
-		// because this list may change when participants join or leave the session.
-
-		LLSpeakerMgr::speaker_list_t speaker_list;
-		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		if (speaker_mgr)
-		{
-			speaker_mgr->getSpeakerList(&speaker_list, true);
-		}
-	
-		for (uuid_vec_t::const_iterator id = uuids.begin();
-				id != uuids.end(); ++id)
-		{
-			for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin();
-					it != speaker_list.end(); ++it)
-			{
-				const LLPointer<LLSpeaker>& speaker = *it;
-				if (*id == speaker->mID)
-				{
-					return false;
-				}
-			}
-		}
-	}
-
-	return true;
-}
-
-void LLIMFloater::addSessionParticipants(const uuid_vec_t& uuids)
-{
-	if (mIsP2PChat)
-	{
-		LLSD payload;
-		LLSD args;
-
-		LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload,
-				boost::bind(&LLIMFloater::addP2PSessionParticipants, this, _1, _2, uuids));
-	}
-	else
-	{
-		// remember whom we have invited, to notify others later, when the invited ones actually join
-		mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
-		
-		inviteToSession(uuids);
-	}
-}
-
-void LLIMFloater::addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if (option != 0)
-	{
-		return;
-	}
-
-	mStartConferenceInSameFloater = true;
-
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-	// first check whether this is a voice session
-	bool is_voice_call = voice_channel != NULL && voice_channel->isActive();
-
-	uuid_vec_t temp_ids;
-
-	// Add the initial participant of a P2P session
-	temp_ids.push_back(mOtherParticipantUUID);
-	temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end());
-
-	// then we can close the current session
-	onClose(false);
-
-	// we start a new session so reset the initialization flag
-	mSessionInitialized = false;
-
-	// remember whom we have invited, to notify others later, when the invited ones actually join
-	mInvitedParticipants.insert(mInvitedParticipants.end(), uuids.begin(), uuids.end());
-
-	// Start a new ad hoc voice call if we invite new participants to a P2P call,
-	// or start a text chat otherwise.
-	if (is_voice_call)
-	{
-		LLAvatarActions::startAdhocCall(temp_ids, mSessionID);
-	}
-	else
-	{
-		LLAvatarActions::startConference(temp_ids, mSessionID);
-	}
-}
-
-void LLIMFloater::sendParticipantsAddedNotification(const uuid_vec_t& uuids)
-{
-	std::string names_string;
-	LLAvatarActions::buildResidentsString(uuids, names_string);
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = names_string;
-
-	sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args));
-}
-
-void LLIMFloater::boundVoiceChannel()
-{
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-	if(voice_channel)
-	{
-		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(
-				boost::bind(&LLIMFloater::onVoiceChannelStateChanged, this, _1, _2));
-
-		//call (either p2p, group or ad-hoc) can be already in started state
-		bool callIsActive = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
-		updateCallBtnState(callIsActive);
-	}
-}
-
-void LLIMFloater::onCallButtonClicked()
-{
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-	if (voice_channel)
-	{
-		bool is_call_active = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
-	    if (is_call_active)
-	    {
-		    gIMMgr->endCall(mSessionID);
-	    }
-	    else
-	    {
-		    gIMMgr->startCall(mSessionID);
-	    }
-	}
-}
-
-void LLIMFloater::onChange(EStatusType status, const std::string &channelURI, bool proximal)
-{
-	if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL)
-	{
-		enableDisableCallBtn();
-	}
-}
-
-void LLIMFloater::onVoiceChannelStateChanged(
-		const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
-	bool callIsActive = new_state >= LLVoiceChannel::STATE_CALL_STARTED;
-	updateCallBtnState(callIsActive);
-}
-
-void LLIMFloater::updateSessionName(const std::string& name)
-{
-	LLIMConversation::updateSessionName(name);
-	setTitle(name);	
-	mTypingStart.setArg("[NAME]", name);
-}
-
-//static
-LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
-{
-	closeHiddenIMToasts();
-
-	if (!gIMMgr->hasSession(session_id))
-		return NULL;
-
-	// Test the existence of the floater before we try to create it
-	bool exist = findInstance(session_id);
-
-	// Get the floater: this will create the instance if it didn't exist
-	LLIMFloater* floater = getInstance(session_id);
-	if (!floater)
-		return NULL;
-
-	LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
-
-	// Do not add again existing floaters
-	if (!exist)
-	{
-		//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
-		// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
-		LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
-		if (floater_container)
-		{
-			floater_container->addFloater(floater, TRUE, i_pt);
-		}
-	}
-
-	floater->openFloater(floater->getKey());
-
-	floater->setVisible(TRUE);
-
-	return floater;
-}
-//static
-LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
-{
-    LLIMFloater* conversation =
-    		LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-
-	return conversation;
-}
-
-LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
-{
-	LLIMFloater* conversation =
-				LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
-
-	return conversation;
-}
-
-void LLIMFloater::onClose(bool app_quitting)
-{
-	setTyping(false);
-
-	// The source of much argument and design thrashing
-	// Should the window hide or the session close when the X is clicked?
-	//
-	// Last change:
-	// EXT-3516 X Button should end IM session, _ button should hide
-	gIMMgr->leaveSession(mSessionID);
-
-	// Clean up the conversation *after* the session has been ended
-	LLIMConversation::onClose(app_quitting);
-}
-
-void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
-{
-	// update notification channel state
-	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-		(LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-	
-	if(!isChatMultiTab())
-	{
-		LLTransientDockableFloater::setDocked(docked, pop_on_undock);
-	}
-
-	// update notification channel state
-	if(channel)
-	{
-		channel->updateShowToastsState();
-		channel->redrawToasts();
-	}
-}
-
-void LLIMFloater::setVisible(BOOL visible)
-{
-	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-		(LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-
-	LLIMConversation::setVisible(visible);
-
-	// update notification channel state
-	if(channel)
-	{
-		channel->updateShowToastsState();
-		channel->redrawToasts();
-	}
-
-	if(!visible)
-	{
-		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
-		if(chiclet)
-		{
-			chiclet->setToggleState(false);
-		}
-	}
-
-	if (visible && isInVisibleChain())
-	{
-		sIMFloaterShowedSignal(mSessionID);
-        
-	}
-
-    setFocus(visible);
-}
-
-BOOL LLIMFloater::getVisible()
-{
-	bool visible;
-
-	if(isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_container =
-				LLIMFloaterContainer::getInstance();
-		
-		// Treat inactive floater as invisible.
-		bool is_active = im_container->getActiveFloater() == this;
-	
-		//torn off floater is always inactive
-		if (!is_active && getHost() != im_container)
-		{
-			visible = LLTransientDockableFloater::getVisible();
-		}
-		else
-		{
-		// getVisible() returns TRUE when Tabbed IM window is minimized.
-			visible = is_active && !im_container->isMinimized()
-						&& im_container->getVisible();
-	}
-	}
-	else
-	{
-		visible = LLTransientDockableFloater::getVisible();
-	}
-
-	return visible;
-}
-
-//static
-bool LLIMFloater::toggle(const LLUUID& session_id)
-{
-	if(!isChatMultiTab())
-	{
-		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>(
-				"impanel", session_id);
-		if (floater && floater->getVisible() && floater->hasFocus())
-		{
-			// clicking on chiclet to close floater just hides it to maintain existing
-			// scroll/text entry state
-			floater->setVisible(false);
-			return false;
-		}
-		else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
-		{
-			floater->setVisible(TRUE);
-			floater->setFocus(TRUE);
-			return true;
-		}
-	}
-
-	// ensure the list of messages is updated when floater is made visible
-	show(session_id);
-	return true;
-}
-
-void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
-{
-	mSessionInitialized = true;
-
-	//will be different only for an ad-hoc im session
-	if (mSessionID != im_session_id)
-	{
-		initIMSession(im_session_id);
-		buildConversationViewParticipant();
-	}
-
-	initIMFloater();
-	
-	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
-
-	//need to send delayed messages collected while waiting for session initialization
-	if (mQueuedMsgsForInit.size())
-	{
-		LLSD::array_iterator iter;
-		for ( iter = mQueuedMsgsForInit.beginArray();
-					iter != mQueuedMsgsForInit.endArray(); ++iter)
-		{
-			LLIMModel::sendMessage(iter->asString(), mSessionID,
-				mOtherParticipantUUID, mDialog);
-		}
-
-		mQueuedMsgsForInit.clear();
-	}
-}
-
-void LLIMFloater::updateMessages()
-{
-	std::list<LLSD> messages;
-
-	// we shouldn't reset unread message counters if IM floater doesn't have focus
-    LLIMModel::instance().getMessages(
-    		mSessionID, messages, mLastMessageIndex + 1, hasFocus());
-
-	if (messages.size())
-	{
-		std::ostringstream message;
-		std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
-		std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
-		for (; iter != iter_end; ++iter)
-		{
-			LLSD msg = *iter;
-
-			std::string time = msg["time"].asString();
-			LLUUID from_id = msg["from_id"].asUUID();
-			std::string from = msg["from"].asString();
-			std::string message = msg["message"].asString();
-			bool is_history = msg["is_history"].asBoolean();
-
-			LLChat chat;
-			chat.mFromID = from_id;
-			chat.mSessionID = mSessionID;
-			chat.mFromName = from;
-			chat.mTimeStr = time;
-			chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
-
-			// process offer notification
-			if (msg.has("notification_id"))
-			{
-				chat.mNotifId = msg["notification_id"].asUUID();
-				// if notification exists - embed it
-				if (LLNotificationsUtil::find(chat.mNotifId) != NULL)
-				{
-					// remove embedded notification from channel
-					LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-							(LLNotificationsUI::LLChannelManager::getInstance()->
-																findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-					if (getVisible())
-					{
-						// toast will be automatically closed since it is not storable toast
-						channel->hideToast(chat.mNotifId);
-					}
-				}
-				// if notification doesn't exist - try to use next message which should be log entry
-				else
-				{
-					continue;
-				}
-			}
-			//process text message
-			else
-			{
-				chat.mText = message;
-			}
-			
-			// Add the message to the chat log
-			appendMessage(chat);
-			mLastMessageIndex = msg["index"].asInteger();
-
-			// if it is a notification - next message is a notification history log, so skip it
-			if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
-			{
-				if (++iter == iter_end)
-				{
-					break;
-				}
-				else
-				{
-					mLastMessageIndex++;
-				}
-			}
-		}
-	}
-}
-
-void LLIMFloater::reloadMessages()
-{
-	mChatHistory->clear();
-	mLastMessageIndex = -1;
-	updateMessages();
-	mInputEditor->setFont(LLViewerChat::getChatFont());
-}
-
-// static
-void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
-{
-	LLIMFloater* self= (LLIMFloater*) userdata;
-
-	// Allow enabling the LLIMFloater input editor only if session can accept text
-	LLIMModel::LLIMSession* im_session =
-		LLIMModel::instance().findIMSession(self->mSessionID);
-	//TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
-	if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
-	{
-		//in disconnected state IM input editor should be disabled
-		self->mInputEditor->setEnabled(!gDisconnected);
-	}
-}
-
-// static
-void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
-{
-	LLIMFloater* self = (LLIMFloater*) userdata;
-	self->setTyping(false);
-}
-
-// static
-void LLIMFloater::onInputEditorKeystroke(LLTextEditor* caller, void* userdata)
-{
-	LLIMFloater* self = (LLIMFloater*)userdata;
-	std::string text = self->mInputEditor->getText();
-
-		// Deleting all text counts as stopping typing.
-	self->setTyping(!text.empty());
-}
-
-void LLIMFloater::setTyping(bool typing)
-{
-	if ( typing )
-	{
-		// Started or proceeded typing, reset the typing timeout timer
-		mTypingTimeoutTimer.reset();
-	}
-
-	if ( mMeTyping != typing )
-	{
-		// Typing state is changed
-		mMeTyping = typing;
-		// So, should send current state
-		mShouldSendTypingState = true;
-		// In case typing is started, send state after some delay
-		mTypingTimer.reset();
-	}
-
-	// Don't want to send typing indicators to multiple people, potentially too
-	// much network traffic. Only send in person-to-person IMs.
-	if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
-	{
-		// Still typing, send 'start typing' notification or
-		// send 'stop typing' notification immediately
-		if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f)
-		{
-			LLIMModel::instance().sendTypingState(mSessionID,
-					mOtherParticipantUUID, mMeTyping);
-					mShouldSendTypingState = false;
-		}
-	}
-
-	if (!mIsNearbyChat)
-	{
-		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		if (speaker_mgr)
-		{
-			speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
-		}
-	}
-}
-
-void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
-{
-	if ( typing )
-	{
-		// other user started typing
-		addTypingIndicator(im_info);
-	}
-	else
-	{
-		// other user stopped typing
-		removeTypingIndicator(im_info);
-	}
-}
-
-void LLIMFloater::processAgentListUpdates(const LLSD& body)
-{
-	uuid_vec_t joined_uuids;
-
-	if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap())
-	{
-		LLSD::map_const_iterator update_it;
-		for(update_it = body["agent_updates"].beginMap();
-			update_it != body["agent_updates"].endMap();
-			++update_it)
-		{
-			LLUUID agent_id(update_it->first);
-			LLSD agent_data = update_it->second;
-
-			if (agent_data.isMap())
-			{
-				// store the new participants in joined_uuids
-				if (agent_data.has("transition") && agent_data["transition"].asString() == "ENTER")
-				{
-					joined_uuids.push_back(agent_id);
-				}
-
-				// process the moderator mutes
-				if (agent_id == gAgentID && agent_data.has("info") && agent_data["info"].has("mutes"))
-				{
-					BOOL moderator_muted_text = agent_data["info"]["mutes"]["text"].asBoolean();
-					mInputEditor->setEnabled(!moderator_muted_text);
-					std::string label;
-					if (moderator_muted_text)
-						label = LLTrans::getString("IM_muted_text_label");
-					else
-						label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
-					mInputEditor->setLabel(label);
-
-					if (moderator_muted_text)
-						LLNotificationsUtil::add("TextChatIsMutedByModerator");
-				}
-			}
-		}
-	}
-
-	// the vectors need to be sorted for computing the intersection and difference
-	std::sort(mInvitedParticipants.begin(), mInvitedParticipants.end());
-    std::sort(joined_uuids.begin(), joined_uuids.end());
-
-    uuid_vec_t intersection; // uuids of invited residents who have joined the conversation
-	std::set_intersection(mInvitedParticipants.begin(), mInvitedParticipants.end(),
-						  joined_uuids.begin(), joined_uuids.end(),
-						  std::back_inserter(intersection));
-
-	if (intersection.size() > 0)
-	{
-		sendParticipantsAddedNotification(intersection);
-	}
-
-	// Remove all joined participants from invited array.
-	// The difference between the two vectors (the elements in mInvitedParticipants which are not in joined_uuids)
-	// is placed at the beginning of mInvitedParticipants, then all other elements are erased.
-	mInvitedParticipants.erase(std::set_difference(mInvitedParticipants.begin(), mInvitedParticipants.end(),
-												   joined_uuids.begin(), joined_uuids.end(),
-												   mInvitedParticipants.begin()),
-							   mInvitedParticipants.end());
-}
-
-void LLIMFloater::processSessionUpdate(const LLSD& session_update)
-{
-	// *TODO : verify following code when moderated mode will be implemented
-	if ( false && session_update.has("moderated_mode") &&
-		 session_update["moderated_mode"].has("voice") )
-	{
-		BOOL voice_moderated = session_update["moderated_mode"]["voice"];
-		const std::string session_label = LLIMModel::instance().getName(mSessionID);
-
-		if (voice_moderated)
-		{
-			setTitle(session_label + std::string(" ")
-							+ LLTrans::getString("IM_moderated_chat_label"));
-		}
-		else
-		{
-			setTitle(session_label);
-		}
-
-		// *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added
-		//update the speakers dropdown too
-		//mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
-	}
-}
-
-// virtual
-BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-									EDragAndDropType cargo_type,
-									void* cargo_data,
-									EAcceptance* accept,
-						   std::string& tooltip_msg)
-{
-	if (cargo_type == DAD_PERSON)
-	{
-		if (dropPerson(static_cast<LLUUID*>(cargo_data), drop))
-		{
-			*accept = ACCEPT_YES_MULTI;
-		}
-		else
-		{
-			*accept = ACCEPT_NO;
-		}
-	}
-	else if (mDialog == IM_NOTHING_SPECIAL)
-	{
-		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
-				cargo_type, cargo_data, accept);
-	}
-
-	return TRUE;
-}
-
-bool LLIMFloater::dropPerson(LLUUID* person_id, bool drop)
-{
-	bool res = person_id && person_id->notNull();
-	if(res)
-	{
-		uuid_vec_t ids;
-		ids.push_back(*person_id);
-
-		res = canAddSelectedToChat(ids);
-		if(res && drop)
-		{
-			addSessionParticipants(ids);
-		}
-	}
-
-	return res;
-}
-
-BOOL LLIMFloater::isInviteAllowed() const
-{
-	return ( (IM_SESSION_CONFERENCE_START == mDialog)
-			 || (IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
-			 || mIsP2PChat);
-}
-
-class LLSessionInviteResponder : public LLHTTPClient::Responder
-{
-public:
-	LLSessionInviteResponder(const LLUUID& session_id)
-	{
-		mSessionID = session_id;
-	}
-
-	void error(U32 statusNum, const std::string& reason)
-	{
-		llinfos << "Error inviting all agents to session" << llendl;
-		//throw something back to the viewer here?
-	}
-
-private:
-	LLUUID mSessionID;
-};
-
-BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
-{
-	LLViewerRegion* region = gAgent.getRegion();
-	bool is_region_exist = region != NULL;
-
-	if (is_region_exist)
-	{
-		S32 count = ids.size();
-
-		if( isInviteAllowed() && (count > 0) )
-		{
-			llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
-
-			std::string url = region->getCapability("ChatSessionRequest");
-
-			LLSD data;
-			data["params"] = LLSD::emptyArray();
-			for (int i = 0; i < count; i++)
-			{
-				data["params"].append(ids[i]);
-			}
-			data["method"] = "invite";
-			data["session-id"] = mSessionID;
-			LLHTTPClient::post(url,	data,new LLSessionInviteResponder(mSessionID));
-		}
-		else
-		{
-			llinfos << "LLIMFloater::inviteToSession -"
-					<< " no need to invite agents for "
-					<< mDialog << llendl;
-			// successful add, because everyone that needed to get added
-			// was added.
-		}
-	}
-
-	return is_region_exist;
-}
-
-void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
-{
-	// We may have lost a "stop-typing" packet, don't add it twice
-	if ( im_info && !mOtherTyping )
-	{
-		mOtherTyping = true;
-
-		// Save and set new title
-		mSavedTitle = getTitle();
-		setTitle (mTypingStart);
-
-		// Update speaker
-		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		if ( speaker_mgr )
-		{
-			speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
-		}
-	}
-}
-
-void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
-{
-	if ( mOtherTyping )
-	{
-		mOtherTyping = false;
-
-		// Revert the title to saved one
-		setTitle(mSavedTitle);
-
-		if ( im_info )
-		{
-			// Update speaker
-			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-			if ( speaker_mgr )
-			{
-				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
-			}
-		}
-	}
-}
-
-// static
-void LLIMFloater::closeHiddenIMToasts()
-{
-	class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher
-	{
-	public:
-		bool matches(const LLNotificationPtr notification) const
-		{
-			// "notifytoast" type of notifications is reserved for IM notifications
-			return "notifytoast" == notification->getType();
-		}
-	};
-
-	LLNotificationsUI::LLScreenChannel* channel =
-			LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
-	if (channel != NULL)
-	{
-		channel->closeHiddenToasts(IMToastMatcher());
-	}
-}
-// static
-void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	const LLSD& payload = notification["payload"];
-	LLUUID session_id = payload["session_id"];
-
-	LLFloater* im_floater = findInstance(session_id);
-	if (option == 0 && im_floater != NULL)
-	{
-		im_floater->closeFloater();
-	}
-
-	return;
-}
-
-// static
-void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
-{
-	LLUUID session_id = data["session_id"];
-	if (session_id.isNull())
-		return;
-
-	LLUUID from_id = data["from_id"];
-	if (gAgentID == from_id || LLUUID::null == from_id)
-		return;
-
-	LLIMFloater* floater = LLIMFloater::findInstance(session_id);
-	if (!floater)
-		return;
-
-	if (IM_NOTHING_SPECIAL != floater->mDialog)
-		return;
-
-	floater->removeTypingIndicator();
-}
-
-// static
-void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
-{
-	LLIMFloater::addToHost(session_id);
-}
-
-boost::signals2::connection LLIMFloater::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb)
-{
-	return LLIMFloater::sIMFloaterShowedSignal.connect(cb);
-}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
deleted file mode 100644
index 6ba31657dc..0000000000
--- a/indra/newview/llimfloater.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/** 
- * @file llimfloater.h
- * @brief LLIMFloater class definition
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_IMFLOATER_H
-#define LL_IMFLOATER_H
-
-#include "llimview.h"
-#include "llimconversation.h"
-#include "llinstantmessage.h"
-#include "lllogchat.h"
-#include "lltooldraganddrop.h"
-#include "llvoicechannel.h"
-#include "llvoiceclient.h"
-
-class LLAvatarName;
-class LLButton;
-class LLChatEntry;
-class LLTextEditor;
-class LLPanelChatControlPanel;
-class LLChatHistory;
-class LLInventoryItem;
-class LLInventoryCategory;
-
-typedef boost::signals2::signal<void(const LLUUID& session_id)> floater_showed_signal_t;
-
-/**
- * Individual IM window that appears at the bottom of the screen,
- * optionally "docked" to the bottom tray.
- */
-class LLIMFloater
-    : public LLVoiceClientStatusObserver
-    , public LLIMConversation
-{
-	LOG_CLASS(LLIMFloater);
-public:
-	LLIMFloater(const LLUUID& session_id);
-
-	virtual ~LLIMFloater();
-
-	void initIMSession(const LLUUID& session_id);
-	void initIMFloater();
-
-	// LLView overrides
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void setVisible(BOOL visible);
-	/*virtual*/ BOOL getVisible();
-	// Check typing timeout timer.
-
-	static LLIMFloater* findInstance(const LLUUID& session_id);
-	static LLIMFloater* getInstance(const LLUUID& session_id);
-
-	// LLFloater overrides
-	/*virtual*/ void onClose(bool app_quitting);
-	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
-	// Make IM conversion visible and update the message history
-	static LLIMFloater* show(const LLUUID& session_id);
-
-	// Toggle panel specified by session_id
-	// Returns true iff panel became visible
-	static bool toggle(const LLUUID& session_id);
-
-	void sessionInitReplyReceived(const LLUUID& im_session_id);
-
-	// get new messages from LLIMModel
-	/*virtual*/ void updateMessages();
-	void reloadMessages();
-	static void onSendMsg(LLUICtrl*, void*);
-	void sendMsgFromInputEditor();
-	void sendMsg(const std::string& msg);
-
-	// callback for LLIMModel on new messages
-	// route to specific floater if it is visible
-	static void newIMCallback(const LLSD& data);
-
-	// called when docked floater's position has been set by chiclet
-	void setPositioned(bool b) { mPositioned = b; };
-
-	void onVisibilityChange(const LLSD& new_visibility);
-
-	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
-	// button when voice is available
-	void onChange(EStatusType status, const std::string &channelURI,
-			bool proximal);
-
-	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
-	virtual void onVoiceChannelStateChanged(
-			const LLVoiceChannel::EState& old_state,
-			const LLVoiceChannel::EState& new_state);
-
-	void processIMTyping(const LLIMInfo* im_info, BOOL typing);
-	void processAgentListUpdates(const LLSD& body);
-	void processSessionUpdate(const LLSD& session_update);
-
-	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-									   EDragAndDropType cargo_type,
-									   void* cargo_data,
-									   EAcceptance* accept,
-									   std::string& tooltip_msg);
-
-
-	//used as a callback on receiving new IM message
-	static void sRemoveTypingIndicator(const LLSD& data);
-	static void onIMChicletCreated(const LLUUID& session_id);
-
-	bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
-    const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;}
-
-	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
-	static floater_showed_signal_t sIMFloaterShowedSignal;
-
-private:
-
-	/*virtual*/ void refresh();
-
-	/*virtual*/ void onClickCloseBtn();
-
-	// Update the window title and input field help text
-	/*virtual*/ void updateSessionName(const std::string& name);
-
-	bool dropPerson(LLUUID* person_id, bool drop);
-
-	BOOL isInviteAllowed() const;
-	BOOL inviteToSession(const uuid_vec_t& agent_ids);
-	static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
-	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
-	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
-	void setTyping(bool typing);
-	void onAddButtonClicked();
-	void addSessionParticipants(const uuid_vec_t& uuids);
-	void addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids);
-	void sendParticipantsAddedNotification(const uuid_vec_t& uuids);
-	bool canAddSelectedToChat(const uuid_vec_t& uuids);
-
-	void onCallButtonClicked();
-
-	void boundVoiceChannel();
-
-	// Add the "User is typing..." indicator.
-	void addTypingIndicator(const LLIMInfo* im_info);
-
-	// Remove the "User is typing..." indicator.
-	void removeTypingIndicator(const LLIMInfo* im_info = NULL);
-
-	static void closeHiddenIMToasts();
-
-	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
-
-	S32 mLastMessageIndex;
-
-	EInstantMessage mDialog;
-	LLUUID mOtherParticipantUUID;
-	bool mPositioned;
-
-	std::string mSavedTitle;
-	LLUIString mTypingStart;
-	bool mMeTyping;
-	bool mOtherTyping;
-	bool mShouldSendTypingState;
-	LLFrameTimer mTypingTimer;
-	LLFrameTimer mTypingTimeoutTimer;
-
-	bool mSessionInitialized;
-	LLSD mQueuedMsgsForInit;
-
-	bool mStartConferenceInSameFloater;
-
-	uuid_vec_t mInvitedParticipants;
-
-	// connection to voice channel state change signal
-	boost::signals2::connection mVoiceChannelStateChangeConnection;
-};
-
-#endif  // LL_IMFLOATER_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
deleted file mode 100644
index 9c1f5d7593..0000000000
--- a/indra/newview/llimfloatercontainer.cpp
+++ /dev/null
@@ -1,1557 +0,0 @@
-/** 
- * @file llimfloatercontainer.cpp
- * @brief Multifloater containing active IM sessions in separate tab container tabs
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llimfloater.h"
-#include "llimfloatercontainer.h"
-
-#include "llfloaterreg.h"
-#include "lllayoutstack.h"
-#include "llnearbychat.h"
-
-#include "llagent.h"
-#include "llavataractions.h"
-#include "llavatariconctrl.h"
-#include "llavatarnamecache.h"
-#include "llcallbacklist.h"
-#include "llgroupactions.h"
-#include "llgroupiconctrl.h"
-#include "llfloateravatarpicker.h"
-#include "llfloaterpreference.h"
-#include "llimview.h"
-#include "llnotificationsutil.h"
-#include "lltransientfloatermgr.h"
-#include "llviewercontrol.h"
-#include "llconversationview.h"
-#include "llcallbacklist.h"
-#include "llworld.h"
-
-#include "llsdserialize.h"
-//
-// LLIMFloaterContainer
-//
-LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
-:	LLMultiFloater(seed),
-	mExpandCollapseBtn(NULL),
-	mConversationsRoot(NULL),
-	mConversationsEventStream("ConversationsEvents"),
-	mInitialized(false)
-{
-    mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLIMFloaterContainer::isActionChecked, this, _2));
-	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLIMFloaterContainer::onCustomAction,  this, _2));
-	
-    mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLIMFloaterContainer::checkContextMenuItem,	this, _2));
-    mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLIMFloaterContainer::enableContextMenuItem,	this, _2));
-    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelected, this, _2));
-    
-    mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&LLIMFloaterContainer::doToSelectedGroup, this, _2));
-
-	// Firstly add our self to IMSession observers, so we catch session events
-    LLIMMgr::getInstance()->addSessionObserver(this);
-
-	mAutoResize = FALSE;
-	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
-}
-
-LLIMFloaterContainer::~LLIMFloaterContainer()
-{
-	mConversationsEventStream.stopListening("ConversationsRefresh");
-
-	gIdleCallbacks.deleteFunction(idle, this);
-
-	mNewMessageConnection.disconnect();
-	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
-
-	gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed());
-	gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
-
-	if (!LLSingleton<LLIMMgr>::destroyed())
-	{
-		LLIMMgr::getInstance()->removeSessionObserver(this);
-	}
-}
-
-void LLIMFloaterContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
-{
-	addConversationListItem(session_id);
-	LLIMConversation::addToHost(session_id);
-}
-
-void LLIMFloaterContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
-{
-    selectConversation(session_id);
-}
-
-void LLIMFloaterContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
-{
-	addConversationListItem(session_id);
-	LLIMConversation::addToHost(session_id);
-}
-
-void LLIMFloaterContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
-	// *TODO: We should do this *without* delete and recreate
-	addConversationListItem(new_session_id, removeConversationListItem(old_session_id));
-}
-
-void LLIMFloaterContainer::sessionRemoved(const LLUUID& session_id)
-{
-	removeConversationListItem(session_id);
-}
-
-// static
-void LLIMFloaterContainer::onCurrentChannelChanged(const LLUUID& session_id)
-{
-    if (session_id != LLUUID::null)
-    {
-    	LLIMFloaterContainer::getInstance()->showConversation(session_id);
-    }
-}
-
-
-BOOL LLIMFloaterContainer::postBuild()
-{
-	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));
-	// Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
-	// mTabContainer will be initialized in LLMultiFloater::addChild()
-	
-	setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
-
-	mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
-	mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel");
-	mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel");
-	
-	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
-
-	// Open IM session with selected participant on double click event
-	mConversationsListPanel->setDoubleClickCallback(boost::bind(&LLIMFloaterContainer::doToSelected, this, LLSD("im")));
-
-	// Create the root model and view for all conversation sessions
-	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
-
-    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
-    p.name = getName();
-    p.title = getLabel();
-    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
-    p.parent_panel = mConversationsListPanel;
-    p.tool_tip = p.name;
-    p.listener = base_item;
-    p.view_model = &mConversationViewModel;
-    p.root = NULL;
-    p.use_ellipses = true;
-    p.options_menu = "menu_conversation.xml";
-	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
-    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
-
-	// Add listener to conversation model events
-	mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLIMFloaterContainer::onConversationModelEvent, this, _1));
-
-	// a scroller for folder view
-	LLRect scroller_view_rect = mConversationsListPanel->getRect();
-	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
-	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
-	scroller_params.rect(scroller_view_rect);
-
-	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
-	scroller->setFollowsAll();
-	mConversationsListPanel->addChild(scroller);
-	scroller->addChild(mConversationsRoot);
-	mConversationsRoot->setScrollContainer(scroller);
-	mConversationsRoot->setFollowsAll();
-	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
-
-	addConversationListItem(LLUUID()); // manually add nearby chat
-
-	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
-	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloaterContainer::onExpandCollapseButtonClicked, this));
-
-	childSetAction("add_btn", boost::bind(&LLIMFloaterContainer::onAddButtonClicked, this));
-
-	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
-	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
-	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
-
-	if (! mMessagesPane->isCollapsed())
-	{
-		S32 list_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
-		LLRect list_size = mConversationsPane->getRect();
-        S32 left_pad = mConversationsListPanel->getRect().mLeft;
-		list_size.mRight = list_size.mLeft + list_width - left_pad;
-
-        mConversationsPane->handleReshape(list_size, TRUE);
-	}
-
-	// Init the sort order now that the root had been created
-	setSortOrder(LLConversationSort(gSavedSettings.getU32("ConversationSortOrder")));
-	
-	mInitialized = true;
-
-	// Add callbacks:
-	// We'll take care of view updates on idle
-	gIdleCallbacks.addFunction(idle, this);
-	// When display name option change, we need to reload all participant names
-	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLIMFloaterContainer::processParticipantsStyleUpdate, this));
-
-	return TRUE;
-}
-
-void LLIMFloaterContainer::onOpen(const LLSD& key)
-{
-	LLMultiFloater::onOpen(key);
-	openNearbyChat();
-}
-
-// virtual
-void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
-									  BOOL select_added_floater,
-									  LLTabContainer::eInsertionPoint insertion_point)
-{
-	if(!floaterp) return;
-
-	// already here
-	if (floaterp->getHost() == this)
-	{
-		openFloater(floaterp->getKey());
-		return;
-	}
-	
-	// Make sure the message panel is open when adding a floater or it stays mysteriously hidden
-	collapseMessagesPane(false);
-
-	// Add the floater
-	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
-
-	LLUUID session_id = floaterp->getKey();
-	
-	LLIconCtrl* icon = 0;
-
-	if(gAgent.isInGroup(session_id, TRUE))
-	{
-		LLGroupIconCtrl::Params icon_params;
-		icon_params.group_id = session_id;
-		icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
-
-		mSessions[session_id] = floaterp;
-		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
-	}
-	else
-	{   LLUUID avatar_id = session_id.notNull()?
-		    LLIMModel::getInstance()->getOtherParticipantID(session_id) : LLUUID();
-
-		LLAvatarIconCtrl::Params icon_params;
-		icon_params.avatar_id = avatar_id;
-		icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
-
-		mSessions[session_id] = floaterp;
-		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
-	}
-
-	// forced resize of the floater
-	LLRect wrapper_rect = this->mTabContainer->getLocalRect();
-	floaterp->setRect(wrapper_rect);
-
-	mTabContainer->setTabImage(floaterp, icon);
-}
-
-
-void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
-{
-	mSessions.erase(id);
-	setFocus(TRUE);
-}
-
-// virtual
-void LLIMFloaterContainer::computeResizeLimits(S32& new_min_width, S32& new_min_height)
-{
-	// possibly increase floater's minimum height according to children's minimums
-	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
-	{
-		LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getPanelByIndex(tab_idx));
-		if (floaterp)
-		{
-			new_min_height = llmax(new_min_height, floaterp->getMinHeight());
-		}
-	}
-
-	S32 conversations_pane_min_dim = mConversationsPane->getRelevantMinDim();
-	S32 messages_pane_min_dim = mMessagesPane->getRelevantMinDim();
-
-	// set floater's minimum width according to relevant minimal children's dimensionals
-	new_min_width = conversations_pane_min_dim + messages_pane_min_dim + LLPANEL_BORDER_WIDTH*2;
-}
-
-void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data)
-{
-	LLUUID session_id = data["session_id"].asUUID();
-	LLFloater* floaterp = get_ptr_in_map(mSessions, session_id);
-	LLFloater* current_floater = LLMultiFloater::getActiveFloater();
-
-	if(floaterp && current_floater && floaterp != current_floater)
-	{
-		if(LLMultiFloater::isFloaterFlashing(floaterp))
-			LLMultiFloater::setFloaterFlashing(floaterp, FALSE);
-		LLMultiFloater::setFloaterFlashing(floaterp, TRUE);
-	}
-}
-
-void LLIMFloaterContainer::onExpandCollapseButtonClicked()
-{
-	if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()
-			&& gSavedPerAccountSettings.getBOOL("ConversationsExpandMessagePaneFirst"))
-	{
-		// Expand the messages pane from ultra minimized state
-		// if it was collapsed last in order.
-		collapseMessagesPane(false);
-	}
-	else
-	{
-		collapseConversationsPane(!mConversationsPane->isCollapsed());
-	}
-	selectConversation(mSelectedSession);
-}
-
-LLIMFloaterContainer* LLIMFloaterContainer::findInstance()
-{
-	return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container");
-}
-
-LLIMFloaterContainer* LLIMFloaterContainer::getInstance()
-{
-	return LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
-}
-
-// Update all participants in the conversation lists
-void LLIMFloaterContainer::processParticipantsStyleUpdate()
-{
-	// On each session in mConversationsItems
-	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
-	{
-		// Get the current session descriptors
-		LLConversationItem* session_model = it_session->second;
-		// Iterate through each model participant child
-		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
-		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
-		while (current_participant_model != end_participant_model)
-		{
-			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
-			// Get the avatar name for this participant id from the cache and update the model
-			participant_model->fetchAvatarName();
-			// Next participant
-			current_participant_model++;
-		}
-	}
-}
-
-// static
-void LLIMFloaterContainer::idle(void* user_data)
-{
-	LLIMFloaterContainer* self = static_cast<LLIMFloaterContainer*>(user_data);
-	
-	// Update the distance to agent in the nearby chat session if required
-	// Note: it makes no sense of course to update the distance in other session
-	if (self->mConversationViewModel.getSorter().getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE)
-	{
-		self->setNearbyDistances();
-	}
-	self->mConversationsRoot->update();
-}
-
-bool LLIMFloaterContainer::onConversationModelEvent(const LLSD& event)
-{
-	// For debug only
-	//std::ostringstream llsd_value;
-	//llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
-	//llinfos << "LLIMFloaterContainer::onConversationModelEvent, event = " << llsd_value.str() << llendl;
-	// end debug
-	
-	// Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
-	// the model could change substantially and the view could echo only a portion of this model (though currently the 
-	// conversation view does echo the conversation model 1 to 1).
-	// Consequently, the participant views need to be created either by the session view or by the container panel.
-	// For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp 
-	// (see LLInventoryPanel::buildNewViews()).
-
-	std::string type = event.get("type").asString();
-	LLUUID session_id = event.get("session_uuid").asUUID();
-	LLUUID participant_id = event.get("participant_uuid").asUUID();
-
-	LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,session_id));
-	if (!session_view)
-	{
-		// We skip events that are not associated with a session
-		return false;
-	}
-	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
-    LLIMConversation *conversation_floater = (session_id.isNull() ? (LLIMConversation*)(LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")) : (LLIMConversation*)(LLIMFloater::findInstance(session_id)));
-
-	if (type == "remove_participant")
-	{
-		// Remove a participant view from the hierarchical conversation list
-		if (participant_view)
-		{
-			session_view->extractItem(participant_view);
-			delete participant_view;
-			session_view->refresh();
-			mConversationsRoot->arrangeAll();
-		}
-		// Remove a participant view from the conversation floater 
-		if (conversation_floater)
-		{
-			conversation_floater->removeConversationViewParticipant(participant_id);
-		}
-	}
-	else if (type == "add_participant")
-	{
-		LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
-		LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL);
-		if (!participant_view && session_model && participant_model)
-		{
-			LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);
-			if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType()))
-			{
-				participant_view = createConversationViewParticipant(participant_model);
-				participant_view->addToFolder(session_view);
-				participant_view->setVisible(TRUE);
-			}
-		}
-		// Add a participant view to the conversation floater 
-		if (conversation_floater && participant_model)
-		{
-			conversation_floater->addConversationViewParticipant(participant_model);
-		}
-	}
-	else if (type == "update_participant")
-	{
-		// Update the participant view in the hierarchical conversation list
-		if (participant_view)
-		{
-			participant_view->refresh();
-		}
-		// Update the participant view in the conversation floater 
-		if (conversation_floater)
-		{
-			conversation_floater->updateConversationViewParticipant(participant_id);
-		}
-	}
-	else if (type == "update_session")
-	{
-		session_view->refresh();
-		if (conversation_floater)
-		{
-			conversation_floater->refreshConversation();
-		}
-	}
-	
-	mConversationViewModel.requestSortAll();
-	mConversationsRoot->arrangeAll();
-	
-	return false;
-}
-
-void LLIMFloaterContainer::draw()
-{
-	if (mTabContainer->getTabCount() == 0)
-	{
-		// Do not close the container when every conversation is torn off because the user
-		// still needs the conversation list. Simply collapse the message pane in that case.
-		collapseMessagesPane(true);
-	}
-	LLFloater::draw();
-}
-
-void LLIMFloaterContainer::tabClose()
-{
-	if (mTabContainer->getTabCount() == 0)
-	{
-		// Do not close the container when every conversation is torn off because the user
-		// still needs the conversation list. Simply collapse the message pane in that case.
-		collapseMessagesPane(true);
-	}
-}
-
-void LLIMFloaterContainer::setVisible(BOOL visible)
-{	LLNearbyChat* nearby_chat;
-	if (visible)
-	{
-		// Make sure we have the Nearby Chat present when showing the conversation container
-		nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
-		if (nearby_chat == NULL)
-		{
-			// If not found, force the creation of the nearby chat conversation panel
-			// *TODO: find a way to move this to XML as a default panel or something like that
-			LLSD name("nearby_chat");
-			LLFloaterReg::toggleInstanceOrBringToFront(name);
-		}
-		openNearbyChat();
-	}
-
-	nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
-	if (nearby_chat)
-	{
-		LLIMConversation::addToHost(LLUUID());
-	}
-
-	// We need to show/hide all the associated conversations that have been torn off
-	// (and therefore, are not longer managed by the multifloater),
-	// so that they show/hide with the conversations manager.
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
-	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
-	{
-		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
-		if (widget)
-		{
-		    widget->setVisibleIfDetached(visible);
-		}
-	}
-	
-	// Now, do the normal multifloater show/hide
-	LLMultiFloater::setVisible(visible);
-	
-}
-
-void LLIMFloaterContainer::collapseMessagesPane(bool collapse)
-{
-	if (mMessagesPane->isCollapsed() == collapse)
-	{
-		return;
-	}
-
-	if (collapse)
-	{
-		// Save the messages pane width before collapsing it.
-		gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", mMessagesPane->getRect().getWidth());
-
-		// Save the order in which the panels are closed to reverse user's last action.
-		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
-	}
-
-	// Save left pane rectangle before collapsing/expanding right pane.
-	LLRect prevRect = mConversationsPane->getRect();
-
-	// Show/hide the messages pane.
-	mConversationsStack->collapsePanel(mMessagesPane, collapse);
-
-	if (!collapse)
-	{
-		// Make sure layout is updated before resizing conversation pane.
-		mConversationsStack->updateLayout();
-	}
-
-	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
-	if (!collapse)
-	{
-		// Restore conversation's pane previous width after expanding messages pane.
-		mConversationsPane->setTargetDim(prevRect.getWidth());
-	}
-}
-void LLIMFloaterContainer::collapseConversationsPane(bool collapse)
-{
-	if (mConversationsPane->isCollapsed() == collapse)
-	{
-		return;
-	}
-
-	LLView* button_panel = getChild<LLView>("conversations_pane_buttons_expanded");
-	button_panel->setVisible(!collapse);
-	mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon"));
-
-	if (collapse)
-	{
-		// Save the conversations pane width before collapsing it.
-		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", mConversationsPane->getRect().getWidth());
-
-		// Save the order in which the panels are closed to reverse user's last action.
-		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", !mMessagesPane->isCollapsed());
-	}
-
-	mConversationsStack->collapsePanel(mConversationsPane, collapse);
-
-	S32 collapsed_width = mConversationsPane->getMinDim();
-	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - collapsed_width);
-
-	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
-			widget_it != mConversationsWidgets.end(); ++widget_it)
-	{
-		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
-		if (widget)
-		{
-		    widget->toggleMinimizedMode(collapse);
-
-		    // force closing all open conversations when collapsing to minimized state
-		    if (collapse)
-		    {
-		    	widget->setOpen(false);
-		    }
-}
-	}
-}
-
-void LLIMFloaterContainer::updateState(bool collapse, S32 delta_width)
-{
-	LLRect floater_rect = getRect();
-	floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
-
-	// Set by_user = true so that reshaped rect is saved in user_settings.
-	setShape(floater_rect, true);
-
-	updateResizeLimits();
-
-	bool is_left_pane_expanded = !mConversationsPane->isCollapsed();
-	bool is_right_pane_expanded = !mMessagesPane->isCollapsed();
-
-	setCanResize(is_left_pane_expanded || is_right_pane_expanded);
-	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
-
-    // force set correct size for the title after show/hide minimize button
-	LLRect cur_rect = getRect();
-	LLRect force_rect = cur_rect;
-	force_rect.mRight = cur_rect.mRight + 1;
-    setRect(force_rect);
-    setRect(cur_rect);
-
-    // restore floater's resize limits (prevent collapse when left panel is expanded)
-	if (is_left_pane_expanded && !is_right_pane_expanded)
-	{
-		S32 expanded_min_size = mConversationsPane->getExpandedMinDim();
-        setResizeLimits(expanded_min_size, expanded_min_size);
-	}
-
-}
-
-void LLIMFloaterContainer::onAddButtonClicked()
-{
-    LLView * button = findChild<LLView>("conversations_pane_buttons_expanded")->findChild<LLButton>("add_btn");
-    LLFloater* root_floater = gFloaterView->getParentFloater(this);
-    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLIMFloaterContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE, root_floater->getName(), button);
-    
-    if (picker && root_floater)
-    {
-        root_floater->addDependentFloater(picker);
-    }
-}
-
-void LLIMFloaterContainer::onAvatarPicked(const uuid_vec_t& ids)
-{
-    if (ids.size() == 1)
-    {
-        LLAvatarActions::startIM(ids.back());
-    }
-    else
-    {
-        LLAvatarActions::startConference(ids);
-    }
-}
-
-void LLIMFloaterContainer::onCustomAction(const LLSD& userdata)
-{
-	std::string command = userdata.asString();
-
-	if ("sort_sessions_by_type" == command)
-	{
-		setSortOrderSessions(LLConversationFilter::SO_SESSION_TYPE);
-	}
-	if ("sort_sessions_by_name" == command)
-	{
-		setSortOrderSessions(LLConversationFilter::SO_NAME);
-	}
-	if ("sort_sessions_by_recent" == command)
-	{
-		setSortOrderSessions(LLConversationFilter::SO_DATE);
-	}
-	if ("sort_participants_by_name" == command)
-	{
-		setSortOrderParticipants(LLConversationFilter::SO_NAME);
-	}
-	if ("sort_participants_by_recent" == command)
-	{
-		setSortOrderParticipants(LLConversationFilter::SO_DATE);
-	}
-	if ("sort_participants_by_distance" == command)
-	{
-		setSortOrderParticipants(LLConversationFilter::SO_DISTANCE);
-	}
-	if ("chat_preferences" == command)
-	{
-		LLFloaterPreference* floater_prefs = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
-		if (floater_prefs)
-		{
-			LLTabContainer* tab_container = floater_prefs->getChild<LLTabContainer>("pref core");
-			LLPanel* chat_panel = tab_container->getPanelByName("chat");
-			if (tab_container && chat_panel)
-			{
-				tab_container->selectTabPanel(chat_panel);
-			}
-		}
-	}
-}
-
-BOOL LLIMFloaterContainer::isActionChecked(const LLSD& userdata)
-{
-	LLConversationSort order = mConversationViewModel.getSorter();
-	std::string command = userdata.asString();
-	if ("sort_sessions_by_type" == command)
-	{
-		return (order.getSortOrderSessions() == LLConversationFilter::SO_SESSION_TYPE);
-	}
-	if ("sort_sessions_by_name" == command)
-	{
-		return (order.getSortOrderSessions() == LLConversationFilter::SO_NAME);
-	}
-	if ("sort_sessions_by_recent" == command)
-	{
-		return (order.getSortOrderSessions() == LLConversationFilter::SO_DATE);
-	}
-	if ("sort_participants_by_name" == command)
-	{
-		return (order.getSortOrderParticipants() == LLConversationFilter::SO_NAME);
-	}
-	if ("sort_participants_by_recent" == command)
-	{
-		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DATE);
-	}
-	if ("sort_participants_by_distance" == command)
-	{
-		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE);
-	}
-	
-	return FALSE;
-}
-
-void LLIMFloaterContainer::setSortOrderSessions(const LLConversationFilter::ESortOrderType order)
-{
-	LLConversationSort old_order = mConversationViewModel.getSorter();
-	if (order != old_order.getSortOrderSessions())
-	{
-		old_order.setSortOrderSessions(order);
-		setSortOrder(old_order);
-	}
-}
-
-void LLIMFloaterContainer::setSortOrderParticipants(const LLConversationFilter::ESortOrderType order)
-{
-	LLConversationSort old_order = mConversationViewModel.getSorter();
-	if (order != old_order.getSortOrderParticipants())
-	{
-		old_order.setSortOrderParticipants(order);
-		setSortOrder(old_order);
-	}
-}
-
-void LLIMFloaterContainer::setSortOrder(const LLConversationSort& order)
-{
-	mConversationViewModel.setSorter(order);
-	mConversationsRoot->arrangeAll();
-	// try to keep selection onscreen, even if it wasn't to start with
-	mConversationsRoot->scrollToShowSelection();
-	
-	// Notify all conversation (torn off or not) of the change to the sort order
-	// Note: For the moment, the sort order is *unique* across all conversations. That might change in the future.
-	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
-	{
-		LLUUID session_id = it_session->first;
-		LLIMConversation *conversation_floater = (session_id.isNull() ? (LLIMConversation*)(LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")) : (LLIMConversation*)(LLIMFloater::findInstance(session_id)));
-		if (conversation_floater)
-		{
-			conversation_floater->setSortOrder(order);
-		}
-	}
-	
-	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
-}
-
-void LLIMFloaterContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
-{
-    const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList();
-
-    std::set<LLFolderViewItem*>::const_iterator it = selectedItems.begin();
-    const std::set<LLFolderViewItem*>::const_iterator it_end = selectedItems.end();
-    LLConversationItem * conversationItem;
-
-    for (; it != it_end; ++it)
-    {
-        conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem());
-        selected_uuids.push_back(conversationItem->getUUID());
-    }
-}
-
-const LLConversationItem * LLIMFloaterContainer::getCurSelectedViewModelItem()
-{
-    LLConversationItem * conversationItem = NULL;
-
-    if(mConversationsRoot && 
-        mConversationsRoot->getCurSelectedItem() && 
-        mConversationsRoot->getCurSelectedItem()->getViewModelItem())
-    {
-        conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
-    }
-
-    return conversationItem;
-}
-
-void LLIMFloaterContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
-{
-    //Find the conversation floater associated with the selected id
-    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
-
-    if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
-    {
-        getSelectedUUIDs(selected_uuids);
-    }
-    //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
-    else if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
-    {
-        LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
-        LLUUID participantID = conversationFloater->getOtherParticipantUUID();
-        selected_uuids.push_back(participantID);
-    }    
-}
-
-void LLIMFloaterContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
-{
-	if(selectedIDS.size() > 0)
-	{
-		const LLUUID& userID = selectedIDS.front();
-		if(gAgent.getID() != userID)
-		{
-			if ("view_profile" == command)
-			{
-				LLAvatarActions::showProfile(userID);
-			}
-			else if("im" == command)
-			{
-				LLAvatarActions::startIM(userID);
-			}
-			else if("offer_teleport" == command)
-			{
-				LLAvatarActions::offerTeleport(selectedIDS);
-			}
-			else if("voice_call" == command)
-			{
-				LLAvatarActions::startCall(userID);
-			}
-			else if("chat_history" == command)
-			{
-				LLAvatarActions::viewChatHistory(userID);
-			}
-			else if("add_friend" == command)
-			{
-				LLAvatarActions::requestFriendshipDialog(userID);
-			}
-			else if("remove_friend" == command)
-			{
-				LLAvatarActions::removeFriendDialog(userID);
-			}
-			else if("invite_to_group" == command)
-			{
-				LLAvatarActions::inviteToGroup(userID);
-			}
-			else if("map" == command)
-			{
-				LLAvatarActions::showOnMap(userID);
-			}
-			else if("share" == command)
-			{
-				LLAvatarActions::share(userID);
-			}
-			else if("pay" == command)
-			{
-				LLAvatarActions::pay(userID);
-			}
-			else if("block_unblock" == command)
-			{
-				LLAvatarActions::toggleBlock(userID);
-			}
-			else if("selected" == command || "mute_all" == command || "unmute_all" == command)
-			{
-				moderateVoice(command, userID);
-			}
-			else if ("toggle_allow_text_chat" == command)
-			{
-				toggleAllowTextChat(userID);
-			}
-		}
-	}
-}
-
-void LLIMFloaterContainer::doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS)
-{
-    //Find the conversation floater associated with the selected id
-    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
-    LLIMFloater *conversationFloater = LLIMFloater::findInstance(conversationItem->getUUID());
-
-    if(conversationFloater)
-    {
-        //Close the selected conversation
-        if("close_conversation" == command)
-        {
-            LLFloater::onClickClose(conversationFloater);
-        }
-        else if("open_voice_conversation" == command)
-        {
-            gIMMgr->startCall(conversationItem->getUUID());
-        }
-        else if("disconnect_from_voice" == command)
-        {
-            gIMMgr->endCall(conversationItem->getUUID());
-        }
-        else if("chat_history" == command)
-        {
-			const LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(conversationItem->getUUID());
-
-			if (NULL != session)
-			{
-				const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
-				LLFloaterReg::showInstance("preview_conversation", session_id, true);
-			}
-        }
-        else
-        {
-            doToParticipants(command, selectedIDS);
-        }
-    }
-}
-
-void LLIMFloaterContainer::doToSelected(const LLSD& userdata)
-{
-    std::string command = userdata.asString();
-    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
-    uuid_vec_t selected_uuids;
-
-    if(conversationItem != NULL)
-    {
-    	getParticipantUUIDs(selected_uuids);
-
-    	if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
-    	{
-    		doToParticipants(command, selected_uuids);
-    	}
-    	else
-    	{
-    		doToSelectedConversation(command, selected_uuids);
-    	}
-    }
-}
-
-void LLIMFloaterContainer::doToSelectedGroup(const LLSD& userdata)
-{
-    std::string action = userdata.asString();
-    LLUUID selected_group = getCurSelectedViewModelItem()->getUUID();
-
-    if (action == "group_profile")
-    {
-        LLGroupActions::show(selected_group);
-    }
-    else if (action == "activate_group")
-    {
-        LLGroupActions::activate(selected_group);
-    }
-    else if (action == "leave_group")
-    {
-        LLGroupActions::leave(selected_group);
-    }
-}
-
-bool LLIMFloaterContainer::enableContextMenuItem(const LLSD& userdata)
-{
-    std::string item = userdata.asString();
-	uuid_vec_t uuids;
-	getParticipantUUIDs(uuids);
-
-    if(item == std::string("can_activate_group"))
-    {
-    	LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
-    	return gAgent.getGroupID() != selected_group_id;
-    }
-
-	if(uuids.size() <= 0)
-    {
-        return false;
-    }
-
-    // Note: can_block and can_delete is used only for one person selected menu
-    // so we don't need to go over all uuids.
-
-    if (item == std::string("can_block"))
-    {
-		const LLUUID& id = uuids.front();
-        return LLAvatarActions::canBlock(id);
-    }
-    else if (item == std::string("can_add"))
-    {
-        // We can add friends if:
-        // - there are selected people
-        // - and there are no friends among selection yet.
-
-        //EXT-7389 - disable for more than 1
-		if(uuids.size() > 1)
-        {
-            return false;
-        }
-
-        bool result = true;
-
-        uuid_vec_t::const_iterator
-			id = uuids.begin(),
-			uuids_end = uuids.end();
-
-        for (;id != uuids_end; ++id)
-        {
-            if ( LLAvatarActions::isFriend(*id) )
-            {
-                result = false;
-                break;
-            }
-        }
-
-        return result;
-    }
-    else if (item == std::string("can_delete"))
-    {
-        // We can remove friends if:
-        // - there are selected people
-        // - and there are only friends among selection.
-
-        bool result = (uuids.size() > 0);
-
-        uuid_vec_t::const_iterator
-			id = uuids.begin(),
-			uuids_end = uuids.end();
-
-        for (;id != uuids_end; ++id)
-        {
-            if ( !LLAvatarActions::isFriend(*id) )
-            {
-                result = false;
-                break;
-            }
-        }
-
-        return result;
-    }
-    else if (item == std::string("can_call"))
-    {
-        return LLAvatarActions::canCall();
-    }
-    else if (item == std::string("can_show_on_map"))
-    {
-		const LLUUID& id = uuids.front();
-
-        return (LLAvatarTracker::instance().isBuddyOnline(id) && is_agent_mappable(id))
-            || gAgent.isGodlike();
-    }
-    else if(item == std::string("can_offer_teleport"))
-    {
-		return LLAvatarActions::canOfferTeleport(uuids);
-    }
-	else if("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item)
-	{
-		return enableModerateContextMenuItem(item);
-	}
-
-    return false;
-}
-
-bool LLIMFloaterContainer::checkContextMenuItem(const LLSD& userdata)
-{
-    std::string item = userdata.asString();
-    uuid_vec_t mUUIDs;
-    getParticipantUUIDs(mUUIDs);
-
-    if(mUUIDs.size() > 0 )
-    {
-		if ("is_blocked" == item)
-		{
-			return LLAvatarActions::isBlocked(mUUIDs.front());
-		}
-		else if ("is_allowed_text_chat" == item)
-		{
-			const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
-
-			if (NULL != speakerp)
-			{
-				return !speakerp->mModeratorMutedText;
-			}
-		}
-    }
-
-    return false;
-}
-
-void LLIMFloaterContainer::showConversation(const LLUUID& session_id)
-{
-    setVisibleAndFrontmost(false);
-    selectConversation(session_id);    
-}
-
-// Will select only the conversation item
-void LLIMFloaterContainer::selectConversation(const LLUUID& session_id)
-{
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
-	if (widget)
-	{
-		(widget->getRoot())->setSelection(widget, FALSE, FALSE);
-	}
-}
-
-// Synchronous select the conversation item and the conversation floater
-BOOL LLIMFloaterContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
-{
-    BOOL handled = TRUE;
-
-    /* widget processing */
-    if (select_widget)
-    {
-    	LLFolderViewItem* widget = mConversationsWidgets[session_id];
-    	if (widget && widget->getParentFolder())
-    	{
-    		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
-    	}
-    }
-
-    /* floater processing */
-
-    if (session_id != getSelectedSession())
-    {
-        // Store the active session
-        setSelectedSession(session_id);
-
-		LLIMConversation* session_floater = LLIMConversation::getConversation(session_id);
-
-		if (session_floater->getHost())
-		{
-			// Always expand the message pane if the panel is hosted by the container
-			collapseMessagesPane(false);
-			// Switch to the conversation floater that is being selected
-			selectFloater(session_floater);
-		}
-
-		// Set the focus on the selected floater
-		if (!session_floater->hasFocus())
-		{
-			session_floater->setFocus(TRUE);
-		}
-    }
-
-    return handled;
-}
-
-void LLIMFloaterContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
-{
-	LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
-	if (item)
-	{
-		item->setTimeNow(participant_id);
-		mConversationViewModel.requestSortAll();
-		mConversationsRoot->arrangeAll();
-	}
-}
-
-void LLIMFloaterContainer::setNearbyDistances()
-{
-	// Get the nearby chat session: that's the one with uuid nul
-	LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,LLUUID()));
-	if (item)
-	{
-		// Get the positions of the nearby avatars and their ids
-		std::vector<LLVector3d> positions;
-		uuid_vec_t avatar_ids;
-		LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
-		// Get the position of the agent
-		const LLVector3d& me_pos = gAgent.getPositionGlobal();
-		// For each nearby avatar, compute and update the distance
-		int avatar_count = positions.size();
-		for (int i = 0; i < avatar_count; i++)
-		{
-			F64 dist = dist_vec_squared(positions[i], me_pos);
-			item->setDistance(avatar_ids[i],dist);
-		}
-		// Also does it for the agent itself
-		item->setDistance(gAgent.getID(),0.0f);
-		// Request resort
-		mConversationViewModel.requestSortAll();
-		mConversationsRoot->arrangeAll();
-	}
-}
-
-LLConversationItem* LLIMFloaterContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
-{
-	bool is_nearby_chat = uuid.isNull();
-
-    // Stores the display name for the conversation line item
-	std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatLabel") : LLIMModel::instance().getName(uuid);
-
-	// Check if the item is not already in the list, exit (nothing to do)
-	// Note: this happens often, when reattaching a torn off conversation for instance
-	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
-	if (item_it != mConversationsItems.end())
-	{
-		return item_it->second;
-	}
-
-	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
-	// and nothing wrong will happen removing it if it doesn't exist
-	removeConversationListItem(uuid,false);
-
-	// Create a conversation session model
-	LLConversationItemSession* item = NULL;
-	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
-	if (speaker_manager)
-	{
-		item = new LLParticipantList(speaker_manager, getRootViewModel());
-	}
-	if (!item)
-	{
-		llwarns << "Couldn't create conversation session item : " << display_name << llendl;
-		return NULL;
-	}
-	item->renameItem(display_name);
-	item->updateParticipantName(NULL);
-	
-	mConversationsItems[uuid] = item;
-
-	// Create a widget from it
-	LLConversationViewSession* widget = createConversationItemWidget(item);
-	mConversationsWidgets[uuid] = widget;
-
-	// Add a new conversation widget to the root folder of the folder view
-	widget->addToFolder(mConversationsRoot);
-	widget->requestArrange();
-
-	LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(uuid);
-
-	// Create the participants widgets now
-	// Note: usually, we do not get an updated avatar list at that point
-	if (uuid.isNull() || im_sessionp && !im_sessionp->isP2PSessionType())
-	{
-		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
-		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
-		while (current_participant_model != end_participant_model)
-		{
-			LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
-			LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
-			participant_view->addToFolder(widget);
-			current_participant_model++;
-		}
-	}
-	// Do that too for the conversation dialog
-    LLIMConversation *conversation_floater = (uuid.isNull() ? (LLIMConversation*)(LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")) : (LLIMConversation*)(LLIMFloater::findInstance(uuid)));
-	if (conversation_floater)
-	{
-		conversation_floater->buildConversationViewParticipant();
-	}
-
-	// set the widget to minimized mode if conversations pane is collapsed
-	widget->toggleMinimizedMode(mConversationsPane->isCollapsed());
-
-    if (isWidgetSelected)
-    {
-        selectConversation(uuid);
-        // scroll to newly added item
-        mConversationsRoot->scrollToShowSelection();
-    }
-
-	return item;
-}
-
-bool LLIMFloaterContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
-{
-	// Delete the widget and the associated conversation item
-	// Note : since the mConversationsItems is also the listener to the widget, deleting 
-	// the widget will also delete its listener
-	bool isWidgetSelected = false;
-	LLFolderViewItem* new_selection = NULL;
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
-	if (widget)
-	{
-		isWidgetSelected = widget->isSelected();
-		new_selection = mConversationsRoot->getNextFromChild(widget);
-		if(new_selection == NULL)
-		{
-			new_selection = mConversationsRoot->getPreviousFromChild(widget);
-		}
-		widget->destroyView();
-	}
-	
-	// Suppress the conversation items and widgets from their respective maps
-	mConversationsItems.erase(uuid);
-	mConversationsWidgets.erase(uuid);
-	
-	// Don't let the focus fall IW, select and refocus on the first conversation in the list
-	if (change_focus)
-	{
-		setFocus(TRUE);
-		if(new_selection != NULL)
-		{
-			LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
-			if(vmi != NULL)
-			{
-				selectConversation(vmi->getUUID());
-			}
-		}
-	}
-	return isWidgetSelected;
-}
-
-LLConversationViewSession* LLIMFloaterContainer::createConversationItemWidget(LLConversationItem* item)
-{
-	LLConversationViewSession::Params params;
-	
-	params.name = item->getDisplayName();
-	params.root = mConversationsRoot;
-	params.listener = item;
-	params.tool_tip = params.name;
-	params.container = this;
-	
-	return LLUICtrlFactory::create<LLConversationViewSession>(params);
-}
-
-LLConversationViewParticipant* LLIMFloaterContainer::createConversationViewParticipant(LLConversationItem* item)
-{
-	LLConversationViewParticipant::Params params;
-    LLRect panel_rect = mConversationsListPanel->getRect();
-	
-	params.name = item->getDisplayName();
-	params.root = mConversationsRoot;
-	params.listener = item;
-
-    //24 is the the current hight of an item (itemHeight) loaded from conversation_view_participant.xml.
-	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
-	params.tool_tip = params.name;
-	params.participant_id = item->getUUID();
-    params.folder_indentation = 42;
-
-	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
-}
-
-bool LLIMFloaterContainer::enableModerateContextMenuItem(const std::string& userdata)
-{
-	// only group moderators can perform actions related to this "enable callback"
-	if (!isGroupModerator())
-	{
-		return false;
-	}
-
-	LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
-	if (NULL == speakerp)
-	{
-		return false;
-	}
-
-	bool voice_channel = speakerp->isInVoiceChannel();
-
-	if ("can_moderate_voice" == userdata)
-	{
-		return voice_channel;
-	}
-	else if ("can_mute" == userdata)
-	{
-		return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
-	}
-	else if ("can_unmute" == userdata)
-	{
-		return voice_channel && isMuted(getCurSelectedViewModelItem()->getUUID());
-	}
-
-	// The last invoke is used to check whether the "can_allow_text_chat" will enabled
-	return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
-}
-
-bool LLIMFloaterContainer::isGroupModerator()
-{
-	LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant();
-	if (NULL == speaker_manager)
-	{
-		llwarns << "Speaker manager is missing" << llendl;
-		return false;
-	}
-
-	// Is session a group call/chat?
-	if(gAgent.isInGroup(speaker_manager->getSessionID()))
-	{
-		LLSpeaker * speaker = speaker_manager->findSpeaker(gAgentID).get();
-
-		// Is agent a moderator?
-		return speaker && speaker->mIsModerator;
-	}
-
-	return false;
-}
-
-void LLIMFloaterContainer::moderateVoice(const std::string& command, const LLUUID& userID)
-{
-	if (!gAgent.getRegion()) return;
-
-	if (command.compare("selected"))
-	{
-		moderateVoiceAllParticipants(command.compare("mute_all"));
-	}
-	else
-	{
-		moderateVoiceParticipant(userID, isMuted(userID));
-	}
-}
-
-bool LLIMFloaterContainer::isMuted(const LLUUID& avatar_id)
-{
-	const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
-	return NULL == speakerp ? true : speakerp->mStatus == LLSpeaker::STATUS_MUTED;
-}
-
-void LLIMFloaterContainer::moderateVoiceAllParticipants(bool unmute)
-{
-	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
-
-	if (NULL != speaker_managerp)
-	{
-		if (!unmute)
-		{
-			LLSD payload;
-			payload["session_id"] = speaker_managerp->getSessionID();
-			LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
-			return;
-		}
-
-		speaker_managerp->moderateVoiceAllParticipants(unmute);
-	}
-}
-
-// static
-void LLIMFloaterContainer::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	// if Cancel pressed
-	if (option == 1)
-	{
-		return;
-	}
-
-	const LLSD& payload = notification["payload"];
-	const LLUUID& session_id = payload["session_id"];
-
-	LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
-		LLIMModel::getInstance()->getSpeakerManager(session_id));
-	if (speaker_manager)
-	{
-		speaker_manager->moderateVoiceAllParticipants(false);
-	}
-
-	return;
-}
-
-void LLIMFloaterContainer::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
-{
-	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr *>(getSpeakerMgrForSelectedParticipant());
-
-	if (NULL != speaker_managerp)
-	{
-		speaker_managerp->moderateVoiceParticipant(avatar_id, unmute);
-	}
-}
-
-LLSpeakerMgr * LLIMFloaterContainer::getSpeakerMgrForSelectedParticipant()
-{
-	LLFolderViewItem * selected_folder_itemp = mConversationsRoot->getCurSelectedItem();
-	if (NULL == selected_folder_itemp)
-	{
-		llwarns << "Current selected item is null" << llendl;
-		return NULL;
-	}
-
-	LLFolderViewFolder * conversation_itemp = selected_folder_itemp->getParentFolder();
-
-	conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin();
-	conversations_widgets_map::const_iterator end = mConversationsWidgets.end();
-	const LLUUID * conversation_uuidp = NULL;
-	while(iter != end)
-	{
-		if (iter->second == conversation_itemp)
-		{
-			conversation_uuidp = &iter->first;
-			break;
-		}
-		++iter;
-	}
-	if (NULL == conversation_uuidp)
-	{
-		llwarns << "Cannot find conversation item widget" << llendl;
-		return NULL;
-	}
-
-	return conversation_uuidp->isNull() ? (LLSpeakerMgr *)LLLocalSpeakerMgr::getInstance()
-		: LLIMModel::getInstance()->getSpeakerManager(*conversation_uuidp);
-}
-
-LLSpeaker * LLIMFloaterContainer::getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp)
-{
-	if (NULL == speaker_managerp)
-	{
-		llwarns << "Speaker manager is missing" << llendl;
-		return NULL;
-	}
-
-	const LLConversationItem * participant_itemp = getCurSelectedViewModelItem();
-	if (NULL == participant_itemp)
-	{
-		llwarns << "Cannot evaluate current selected view model item" << llendl;
-		return NULL;
-	}
-
-	return speaker_managerp->findSpeaker(participant_itemp->getUUID());
-}
-
-void LLIMFloaterContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
-{
-	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
-	if (NULL != speaker_managerp)
-	{
-		speaker_managerp->toggleAllowTextChat(participant_uuid);
-	}
-}
-
-void LLIMFloaterContainer::openNearbyChat()
-{
-	// If there's only one conversation in the container and that conversation is the nearby chat
-	//(which it should be...), open it so to make the list of participants visible. This happens to be the most common case when opening the Chat floater.
-	if(mConversationsItems.size() == 1)
-	{
-		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[LLUUID()]);
-		if (nearby_chat)
-		{
-			nearby_chat->setOpen(TRUE);
-		}
-	}
-}
-
-void LLIMFloaterContainer::onNearbyChatClosed()
-{
-	// If nearby chat is the only remaining conversation and it is closed, close whole conversation floater as well
-	if (mConversationsItems.size() == 1)
-		closeFloater();
-}
-
-// EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
deleted file mode 100644
index e42ed053cb..0000000000
--- a/indra/newview/llimfloatercontainer.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/** 
- * @file llimfloatercontainer.h
- * @brief Multifloater containing active IM sessions in separate tab container tabs
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLIMFLOATERCONTAINER_H
-#define LL_LLIMFLOATERCONTAINER_H
-
-#include <map>
-#include <vector>
-
-#include "llimview.h"
-#include "llevents.h"
-#include "llfloater.h"
-#include "llmultifloater.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llgroupmgr.h"
-#include "lltrans.h"
-#include "llconversationmodel.h"
-#include "llconversationview.h"
-
-class LLButton;
-class LLLayoutPanel;
-class LLLayoutStack;
-class LLTabContainer;
-class LLIMFloaterContainer;
-class LLSpeaker;
-class LLSpeakerMgr;
-
-class LLIMFloaterContainer
-	: public LLMultiFloater
-	, public LLIMSessionObserver
-{
-public:
-	LLIMFloaterContainer(const LLSD& seed);
-	virtual ~LLIMFloaterContainer();
-	
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void draw();
-	/*virtual*/ void setVisible(BOOL visible);
-	void onCloseFloater(LLUUID& id);
-
-	/*virtual*/ void addFloater(LLFloater* floaterp, 
-								BOOL select_added_floater, 
-								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
-    
-    void showConversation(const LLUUID& session_id);
-    void selectConversation(const LLUUID& session_id);
-    BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
-
-	/*virtual*/ void tabClose();
-
-	static LLFloater* getCurrentVoiceFloater();
-	static LLIMFloaterContainer* findInstance();
-	static LLIMFloaterContainer* getInstance();
-
-	static void onCurrentChannelChanged(const LLUUID& session_id);
-
-	void collapseMessagesPane(bool collapse);
-	
-	// Callbacks
-	static void idle(void* user_data);
-
-	// LLIMSessionObserver observe triggers
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
-	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
-	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-
-	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
-    LLUUID getSelectedSession() { return mSelectedSession; }
-    void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
-	LLConversationItem* getSessionModel(const LLUUID& session_id) { return get_ptr_in_map(mConversationsItems,session_id); }
-	LLConversationSort& getSortOrder() { return mConversationViewModel.getSorter(); }
-
-	void onNearbyChatClosed();
-
-private:
-	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
-	avatarID_panel_map_t mSessions;
-	boost::signals2::connection mNewMessageConnection;
-
-	/*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height);
-
-	void onNewMessageReceived(const LLSD& data);
-
-	void onExpandCollapseButtonClicked();
-	void processParticipantsStyleUpdate();
-
-	void collapseConversationsPane(bool collapse);
-
-	void updateState(bool collapse, S32 delta_width);
-
-	void onAddButtonClicked();
-	void onAvatarPicked(const uuid_vec_t& ids);
-
-	BOOL isActionChecked(const LLSD& userdata);
-	void onCustomAction (const LLSD& userdata);
-	void setSortOrderSessions(const LLConversationFilter::ESortOrderType order);
-	void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order);
-	void setSortOrder(const LLConversationSort& order);
-
-    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
-    const LLConversationItem * getCurSelectedViewModelItem();
-    void getParticipantUUIDs(uuid_vec_t& selected_uuids);
-    void doToSelected(const LLSD& userdata);
-    void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS);
-    void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
-    void doToSelectedGroup(const LLSD& userdata);
-    bool checkContextMenuItem(const LLSD& userdata);
-    bool enableContextMenuItem(const LLSD& userdata);
-
-	static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
-	bool enableModerateContextMenuItem(const std::string& userdata);
-	LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp);
-	LLSpeakerMgr * getSpeakerMgrForSelectedParticipant();
-	bool isGroupModerator();
-	bool isMuted(const LLUUID& avatar_id);
-	void moderateVoice(const std::string& command, const LLUUID& userID);
-	void moderateVoiceAllParticipants(bool unmute);
-	void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
-	void toggleAllowTextChat(const LLUUID& participant_uuid);
-	void openNearbyChat();
-
-	LLButton* mExpandCollapseBtn;
-	LLLayoutPanel* mMessagesPane;
-	LLLayoutPanel* mConversationsPane;
-	LLLayoutStack* mConversationsStack;
-	
-	bool mInitialized;
-
-	LLUUID mSelectedSession;
-
-	// Conversation list implementation
-public:
-	bool removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
-	LLConversationItem* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
-	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
-	void setNearbyDistances();
-
-private:
-	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
-	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
-	bool onConversationModelEvent(const LLSD& event);
-
-	// Conversation list data
-	LLPanel* mConversationsListPanel;	// This is the main widget we add conversation widget to
-	conversations_items_map mConversationsItems;
-	conversations_widgets_map mConversationsWidgets;
-	LLConversationViewModel mConversationViewModel;
-	LLFolderView* mConversationsRoot;
-	LLEventStream mConversationsEventStream; 
-};
-
-#endif // LL_LLIMFLOATERCONTAINER_H
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 0250af6a0e..c64ecdc47a 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -171,7 +171,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	// enable line history support for instant message bar
 	mInputEditor->setEnableLineHistory(TRUE);
 
-	//*TODO we probably need the same "awaiting message" thing in LLIMFloater
+	//*TODO we probably need the same "awaiting message" thing in LLFloaterIMSession
 	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionUUID);
 	if (!im_session)
 	{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 9f24a5372f..6712127750 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -41,15 +41,15 @@
 #include "lltextutil.h"
 #include "lltrans.h"
 #include "lluictrlfactory.h"
-#include "llimconversation.h"
+#include "llfloaterimsessiontab.h"
 #include "llagent.h"
 #include "llagentui.h"
 #include "llappviewer.h"
 #include "llavatariconctrl.h"
 #include "llcallingcard.h"
 #include "llchat.h"
-#include "llimfloater.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
 #include "llgroupiconctrl.h"
 #include "llmd5.h"
 #include "llmutelist.h"
@@ -58,7 +58,7 @@
 #include "llviewerwindow.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llspeakers.h" //for LLIMSpeakerMgr
 #include "lltextbox.h"
 #include "lltoolbarview.h"
@@ -109,7 +109,7 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	args["FROM"] = av_name.getCompleteName();
 	args["FROM_ID"] = msg["from_id"];
 	args["SESSION_ID"] = msg["session_id"];
-	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLIMFloaterContainer::showConversation, LLIMFloaterContainer::getInstance(), msg["session_id"].asUUID()));
+	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
 void toast_callback(const LLSD& msg){
@@ -120,7 +120,7 @@ void toast_callback(const LLSD& msg){
 	}
 
     // Skip toasting if we have open window of IM with this session id
-    LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]);
+    LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(msg["session_id"]);
     if (
            open_im_floater
            && open_im_floater->isInVisibleChain()
@@ -160,7 +160,7 @@ void toast_callback(const LLSD& msg){
 
 LLIMModel::LLIMModel() 
 {
-	addNewMsgCallback(boost::bind(&LLIMFloater::newIMCallback, _1));
+	addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
 	addNewMsgCallback(boost::bind(&toast_callback, _1));
 }
 
@@ -638,7 +638,7 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
 			mId2SessionMap[new_session_id] = session;
 		}
 
-		LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
+		LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(old_session_id);
 		if (im_floater)
 		{
 			im_floater->sessionInitReplyReceived(new_session_id);
@@ -1387,7 +1387,7 @@ public:
 				&& LLIMModel::getInstance()->findIMSession(mSessionID))
 			{
 				// TODO remove in 2010, for voice calls we do not open an IM window
-				//LLIMFloater::show(mSessionID);
+				//LLFloaterIMSession::show(mSessionID);
 			}
 
 			gIMMgr->clearPendingAgentListUpdates(mSessionID);
@@ -1531,7 +1531,7 @@ LLIMMgr::onConfirmForceCloseError(
 	//only 1 option really
 	LLUUID session_id = notification["payload"]["session_id"];
 
-	LLFloater* floater = LLIMFloater::findInstance(session_id);
+	LLFloater* floater = LLFloaterIMSession::findInstance(session_id);
 	if ( floater )
 	{
 		floater->closeFloater(FALSE);
@@ -2397,7 +2397,7 @@ LLIMMgr::LLIMMgr()
 	mPendingInvitations = LLSD::emptyMap();
 	mPendingAgentListUpdates = LLSD::emptyMap();
 
-	LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLIMFloater::sRemoveTypingIndicator, _1));
+	LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLFloaterIMSession::sRemoveTypingIndicator, _1));
 }
 
 // Add a message to a session. 
@@ -2492,7 +2492,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 		LLChat chat(message);
 		chat.mSourceType = CHAT_SOURCE_SYSTEM;
 
-		LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
+		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 		if (nearby_chat)
 		{
 			nearby_chat->addMessage(chat);
@@ -2618,12 +2618,12 @@ LLUUID LLIMMgr::addSession(
 
 	if (floater_id.notNull())
 	{
-		LLIMFloater* im_floater = LLIMFloater::findInstance(floater_id);
+		LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(floater_id);
 
 		if (im_floater && im_floater->getStartConferenceInSameFloater())
 		{
 			// The IM floater should be initialized with a new session_id
-			// so that it is found by that id when creating a chiclet in LLIMFloater::onIMChicletCreated,
+			// so that it is found by that id when creating a chiclet in LLFloaterIMSession::onIMChicletCreated,
 			// and a new floater is not created.
 			im_floater->initIMSession(session_id);
 		}
@@ -2841,7 +2841,7 @@ void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
 
 void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body)
 {
-	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 	if ( im_floater )
 	{
 		im_floater->processAgentListUpdates(body);
@@ -3115,7 +3115,7 @@ void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
 void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
 {
 	LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
-	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 	if ( im_floater )
 	{
 		im_floater->processIMTyping(im_info, typing);
@@ -3160,7 +3160,7 @@ public:
 				speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
 			}
 
-			LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+			LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 			if ( im_floater )
 			{
 				if ( body.has("session_info") )
@@ -3254,7 +3254,7 @@ public:
 		const LLSD& input) const
 	{
 		LLUUID session_id = input["body"]["session_id"].asUUID();
-		LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+		LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 		if ( im_floater )
 		{
 			im_floater->processSessionUpdate(input["body"]["info"]);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 8b04af71c7..ffac67557a 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -46,7 +46,7 @@
 #include "llfriendcard.h"
 #include "llgesturemgr.h"
 #include "llgiveinventory.h" 
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h"
 #include "llclipboard.h"
 #include "llinventorydefines.h"
@@ -4683,7 +4683,7 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
 			LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID());
 			if (session_id != LLUUID::null)
 			{
-				LLIMFloaterContainer::getInstance()->showConversation(session_id);
+				LLFloaterIMContainer::getInstance()->showConversation(session_id);
 			}
 		}
 	}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index dafc71b59c..7c717af840 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -39,7 +39,7 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llfolderview.h"
 #include "llfolderviewitem.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
@@ -1087,7 +1087,7 @@ bool LLInventoryPanel::beginIMSession()
 	LLUUID session_id = gIMMgr->addSession(name, type, members[0], members);
 	if (session_id != LLUUID::null)
 	{
-		LLIMFloaterContainer::getInstance()->showConversation(session_id);
+		LLFloaterIMContainer::getInstance()->showConversation(session_id);
 	}
 		
 	return true;
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
deleted file mode 100644
index dbdf460785..0000000000
--- a/indra/newview/llnearbychat.cpp
+++ /dev/null
@@ -1,867 +0,0 @@
-/** 
- * @file LLNearbyChat.cpp
- * @brief LLNearbyChat class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "message.h"
-
-#include "lliconctrl.h"
-#include "llappviewer.h"
-#include "llchatentry.h"
-#include "llfloaterreg.h"
-#include "lltrans.h"
-#include "llimfloatercontainer.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfocusmgr.h"
-#include "lllogchat.h"
-#include "llresizebar.h"
-#include "llresizehandle.h"
-#include "lldraghandle.h"
-#include "llmenugl.h"
-#include "llviewermenu.h" // for gMenuHolder
-#include "llnearbychathandler.h"
-#include "llchannelmanager.h"
-#include "llchathistory.h"
-#include "llstylemap.h"
-#include "llavatarnamecache.h"
-#include "llfloaterreg.h"
-#include "lltrans.h"
-
-#include "llfirstuse.h"
-#include "llnearbychat.h"
-#include "llagent.h" // gAgent
-#include "llgesturemgr.h"
-#include "llmultigesture.h"
-#include "llkeyboard.h"
-#include "llanimationstates.h"
-#include "llviewerstats.h"
-#include "llcommandhandler.h"
-#include "llviewercontrol.h"
-#include "llnavigationbar.h"
-#include "llwindow.h"
-#include "llviewerwindow.h"
-#include "llrootview.h"
-#include "llviewerchat.h"
-#include "lltranslate.h"
-
-S32 LLNearbyChat::sLastSpecialChatChannel = 0;
-
-const S32 EXPANDED_HEIGHT = 266;
-const S32 COLLAPSED_HEIGHT = 60;
-const S32 EXPANDED_MIN_HEIGHT = 150;
-
-// legacy callback glue
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
-
-struct LLChatTypeTrigger {
-	std::string name;
-	EChatType type;
-};
-
-static LLChatTypeTrigger sChatTypeTriggers[] = {
-	{ "/whisper"	, CHAT_TYPE_WHISPER},
-	{ "/shout"	, CHAT_TYPE_SHOUT}
-};
-
-
-LLNearbyChat::LLNearbyChat(const LLSD& llsd)
-:	LLIMConversation(llsd),
-	//mOutputMonitor(NULL),
-	mSpeakerMgr(NULL),
-	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
-{
-    mIsP2PChat = false;
-	mIsNearbyChat = true;
-	setIsChrome(TRUE);
-	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
-	mSessionID = LLUUID();
-}
-
-//static
-LLNearbyChat* LLNearbyChat::buildFloater(const LLSD& key)
-{
-    LLFloaterReg::getInstance("im_container");
-    return new LLNearbyChat(key);
-}
-
-//virtual
-BOOL LLNearbyChat::postBuild()
-{
-    setIsSingleInstance(TRUE);
-    BOOL result = LLIMConversation::postBuild();
-	mInputEditor->setCommitCallback(boost::bind(&LLNearbyChat::onChatBoxCommit, this));
-	mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
-	mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
-	mInputEditor->setFocusReceivedCallback(boost::bind(&LLNearbyChat::onChatBoxFocusReceived, this));
-	mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle"));
-
-//	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
-//	mOutputMonitor->setVisible(FALSE);
-
-	// Register for font change notifications
-	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChat::onChatFontChange, this, _1));
-
-	// title must be defined BEFORE call addConversationListItem() because
-	// it is used for show the item's name in the conversations list
-	setTitle(LLTrans::getString("NearbyChatTitle"));
-
-	//for menu
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
-	enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
-	registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
-
-	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(menu)
-	{
-		mPopupMenuHandle = menu->getHandle();
-	}
-
-	// obsolete, but may be needed for backward compatibility?
-	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
-
-	if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
-	{
-		loadHistory();
-	}
-
-	return result;
-}
-
-// virtual
-void LLNearbyChat::refresh()
-{
-	displaySpeakingIndicator();
-	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
-
-	// *HACK: Update transparency type depending on whether our children have focus.
-	// This is needed because this floater is chrome and thus cannot accept focus, so
-	// the transparency type setting code from LLFloater::setFocus() isn't reached.
-	if (getTransparencyType() != TT_DEFAULT)
-	{
-		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
-	}
-}
-
-void LLNearbyChat::onNearbySpeakers()
-{
-	LLSD param;
-	param["people_panel_tab_name"] = "nearby_panel";
-	LLFloaterSidePanelContainer::showPanel("people", "panel_people", param);
-}
-
-void	LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
-{
-}
-
-bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
-{
-	std::string str = userdata.asString();
-	if(str == "nearby_people")
-		onNearbySpeakers();
-	return false;
-}
-
-
-BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	//fix for EXT-6625
-	//highlight NearbyChat history whenever mouseclick happen in NearbyChat
-	//setting focus to eidtor will force onFocusLost() call that in its turn will change
-	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
-
-	if(mChatHistory)
-	{
-		mChatHistory->setFocus(TRUE);
-	}
-
-	BOOL handled = LLPanel::handleMouseDown(x, y, mask);
-	setFocus(handled);
-	return handled;
-}
-
-void LLNearbyChat::reloadMessages()
-{
-	mChatHistory->clear();
-
-	LLSD do_not_log;
-	do_not_log["do_not_log"] = true;
-	for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)
-	{
-		// Update the messages without re-writing them to a log file.
-		addMessage(*it,false, do_not_log);
-	}
-}
-
-void LLNearbyChat::loadHistory()
-{
-	LLSD do_not_log;
-	do_not_log["do_not_log"] = true;
-
-	std::list<LLSD> history;
-	LLLogChat::loadChatHistory("chat", history);
-
-	std::list<LLSD>::const_iterator it = history.begin();
-	while (it != history.end())
-	{
-		const LLSD& msg = *it;
-
-		std::string from = msg[IM_FROM];
-		LLUUID from_id;
-		if (msg[IM_FROM_ID].isDefined())
-		{
-			from_id = msg[IM_FROM_ID].asUUID();
-		}
-		else
- 		{
-			std::string legacy_name = gCacheName->buildLegacyName(from);
- 			gCacheName->getUUID(legacy_name, from_id);
- 		}
-
-		LLChat chat;
-		chat.mFromName = from;
-		chat.mFromID = from_id;
-		chat.mText = msg[IM_TEXT].asString();
-		chat.mTimeStr = msg[IM_TIME].asString();
-		chat.mChatStyle = CHAT_STYLE_HISTORY;
-
-		chat.mSourceType = CHAT_SOURCE_AGENT;
-		if (from_id.isNull() && SYSTEM_FROM == from)
-		{
-			chat.mSourceType = CHAT_SOURCE_SYSTEM;
-
-		}
-		else if (from_id.isNull())
-		{
-			chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
-		}
-
-		addMessage(chat, true, do_not_log);
-
-		it++;
-	}
-}
-
-void LLNearbyChat::removeScreenChat()
-{
-	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
-	if(chat_channel)
-	{
-		chat_channel->removeToastsFromChannel();
-	}
-}
-
-
-void LLNearbyChat::setVisible(BOOL visible)
-{
-	LLIMConversation::setVisible(visible);
-
-	if(visible)
-	{
-		removeScreenChat();
-	}
-    setFocus(visible);
-}
-
-// virtual
-void LLNearbyChat::onTearOffClicked()
-{
-	LLIMConversation::onTearOffClicked();
-
-	// see CHUI-170: Save torn-off state of the nearby chat between sessions
-	BOOL in_the_multifloater = !isTornOff();
-	gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
-}
-
-
-// virtual
-void LLNearbyChat::onOpen(const LLSD& key)
-{
-	LLIMConversation::onOpen(key);
-	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
-}
-
-// virtual
-void LLNearbyChat::onClose(bool app_quitting)
-{
-	// Override LLIMConversation::onClose() so that Nearby Chat is not removed from the conversation floater
-}
-
-// virtual
-void LLNearbyChat::onClickCloseBtn()
-{
-	if (!isTornOff())
-		return;
-	onTearOffClicked();
-	
-	LLIMFloaterContainer *im_box = LLIMFloaterContainer::findInstance();
-	if (im_box)
-	{
-		im_box->onNearbyChatClosed();
-	}
-}
-
-void LLNearbyChat::onChatFontChange(LLFontGL* fontp)
-{
-	// Update things with the new font whohoo
-	if (mInputEditor)
-	{
-		mInputEditor->setFont(fontp);
-	}
-}
-
-
-void LLNearbyChat::show()
-{
-	if (isChatMultiTab())
-	{
-		openFloater(getKey());
-	}
-}
-
-bool LLNearbyChat::isChatVisible() const
-{
-	bool isVisible = false;
-	LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-	// Is the IM floater container ever null?
-	llassert(im_box != NULL);
-	if (im_box != NULL)
-	{
-		isVisible =
-				isChatMultiTab() && gSavedSettings.getBOOL("NearbyChatIsNotTornOff")?
-						im_box->getVisible() && !im_box->isMinimized() :
-						getVisible() && !isMinimized();
-	}
-
-	return isVisible;
-}
-
-void LLNearbyChat::showHistory()
-{
-	openFloater();
-	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-}
-
-std::string LLNearbyChat::getCurrentChat()
-{
-	return mInputEditor ? mInputEditor->getText() : LLStringUtil::null;
-}
-
-// virtual
-BOOL LLNearbyChat::handleKeyHere( KEY key, MASK mask )
-{
-	BOOL handled = FALSE;
-
-	if( KEY_RETURN == key && mask == MASK_CONTROL)
-	{
-		// shout
-		sendChat(CHAT_TYPE_SHOUT);
-		handled = TRUE;
-	}
-
-	return handled;
-}
-
-BOOL LLNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
-{
-	U32 in_len = in_str.length();
-	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
-	
-	bool string_was_found = false;
-
-	for (S32 n = 0; n < cnt && !string_was_found; n++)
-	{
-		if (in_len <= sChatTypeTriggers[n].name.length())
-		{
-			std::string trigger_trunc = sChatTypeTriggers[n].name;
-			LLStringUtil::truncate(trigger_trunc, in_len);
-
-			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
-			{
-				*out_str = sChatTypeTriggers[n].name;
-				string_was_found = true;
-			}
-		}
-	}
-
-	return string_was_found;
-}
-
-void LLNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata)
-{
-	LLFirstUse::otherAvatarChatFirst(false);
-
-	LLNearbyChat* self = (LLNearbyChat *)userdata;
-
-	LLWString raw_text = self->mInputEditor->getWText();
-
-	// Can't trim the end, because that will cause autocompletion
-	// to eat trailing spaces that might be part of a gesture.
-	LLWStringUtil::trimHead(raw_text);
-
-	S32 length = raw_text.length();
-
-	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences
-	{
-		gAgent.startTyping();
-	}
-	else
-	{
-		gAgent.stopTyping();
-	}
-
-	/* Doesn't work -- can't tell the difference between a backspace
-	   that killed the selection vs. backspace at the end of line.
-	if (length > 1 
-		&& text[0] == '/'
-		&& key == KEY_BACKSPACE)
-	{
-		// the selection will already be deleted, but we need to trim
-		// off the character before
-		std::string new_text = raw_text.substr(0, length-1);
-		self->mInputEditor->setText( new_text );
-		self->mInputEditor->setCursorToEnd();
-		length = length - 1;
-	}
-	*/
-
-	KEY key = gKeyboard->currentKey();
-
-	// Ignore "special" keys, like backspace, arrows, etc.
-	if (length > 1 
-		&& raw_text[0] == '/'
-		&& key < KEY_SPECIAL)
-	{
-		// we're starting a gesture, attempt to autocomplete
-
-		std::string utf8_trigger = wstring_to_utf8str(raw_text);
-		std::string utf8_out_str(utf8_trigger);
-
-		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
-		{
-			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
-
-			// Select to end of line, starting from the character
-			// after the last one the user typed.
-			self->mInputEditor->selectNext(rest_of_match, false);
-		}
-		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
-		{
-			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
-			self->mInputEditor->endOfDoc();
-		}
-
-		//llinfos << "GESTUREDEBUG " << trigger 
-		//	<< " len " << length
-		//	<< " outlen " << out_str.getLength()
-		//	<< llendl;
-	}
-}
-
-// static
-void LLNearbyChat::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
-{
-	// stop typing animation
-	gAgent.stopTyping();
-}
-
-void LLNearbyChat::onChatBoxFocusReceived()
-{
-	mInputEditor->setEnabled(!gDisconnected);
-}
-
-EChatType LLNearbyChat::processChatTypeTriggers(EChatType type, std::string &str)
-{
-	U32 length = str.length();
-	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
-	
-	for (S32 n = 0; n < cnt; n++)
-	{
-		if (length >= sChatTypeTriggers[n].name.length())
-		{
-			std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
-
-			if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
-			{
-				U32 trigger_length = sChatTypeTriggers[n].name.length();
-
-				// It's to remove space after trigger name
-				if (length > trigger_length && str[trigger_length] == ' ')
-					trigger_length++;
-
-				str = str.substr(trigger_length, length);
-
-				if (CHAT_TYPE_NORMAL == type)
-					return sChatTypeTriggers[n].type;
-				else
-					break;
-			}
-		}
-	}
-
-	return type;
-}
-
-void LLNearbyChat::sendChat( EChatType type )
-{
-	if (mInputEditor)
-	{
-		LLWString text = mInputEditor->getWText();
-		LLWStringUtil::trim(text);
-		LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
-		if (!text.empty())
-		{
-			// Check if this is destined for another channel
-			S32 channel = 0;
-			stripChannelNumber(text, &channel);
-			
-			std::string utf8text = wstring_to_utf8str(text);
-			// Try to trigger a gesture, if not chat to a script.
-			std::string utf8_revised_text;
-			if (0 == channel)
-			{
-				// discard returned "found" boolean
-				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
-			}
-			else
-			{
-				utf8_revised_text = utf8text;
-			}
-
-			utf8_revised_text = utf8str_trim(utf8_revised_text);
-
-			type = processChatTypeTriggers(type, utf8_revised_text);
-
-			if (!utf8_revised_text.empty())
-			{
-				// Chat with animation
-				sendChatFromViewer(utf8_revised_text, type, TRUE);
-			}
-		}
-
-		mInputEditor->setText(LLStringExplicit(""));
-	}
-
-	gAgent.stopTyping();
-
-	// If the user wants to stop chatting on hitting return, lose focus
-	// and go out of chat mode.
-	if (gSavedSettings.getBOOL("CloseChatOnReturn"))
-	{
-		stopChat();
-	}
-}
-
-void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
-{
-	appendMessage(chat, args);
-
-	if(archive)
-	{
-		mMessageArchive.push_back(chat);
-		if(mMessageArchive.size()>200)
-			mMessageArchive.erase(mMessageArchive.begin());
-	}
-
-	// logging
-	if (!args["do_not_log"].asBoolean()
-			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
-	{
-		std::string from_name = chat.mFromName;
-
-		if (chat.mSourceType == CHAT_SOURCE_AGENT)
-		{
-			// if the chat is coming from an agent, log the complete name
-			LLAvatarName av_name;
-			LLAvatarNameCache::get(chat.mFromID, &av_name);
-
-			if (!av_name.mIsDisplayNameDefault)
-			{
-				from_name = av_name.getCompleteName();
-			}
-		}
-
-		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
-	}
-}
-
-
-void LLNearbyChat::onChatBoxCommit()
-{
-	if (mInputEditor->getText().length() > 0)
-	{
-		sendChat(CHAT_TYPE_NORMAL);
-	}
-
-	gAgent.stopTyping();
-}
-
-void LLNearbyChat::displaySpeakingIndicator()
-{
-	LLSpeakerMgr::speaker_list_t speaker_list;
-	LLUUID id;
-
-	id.setNull();
-	mSpeakerMgr->update(TRUE);
-	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
-
-	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
-	{
-		LLPointer<LLSpeaker> s = *i;
-		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
-		{
-			id = s->mID;
-			break;
-		}
-	}
-
-	if (!id.isNull())
-	{
-		//mOutputMonitor->setVisible(TRUE);
-		//mOutputMonitor->setSpeakerId(id);
-	}
-	else
-	{
-		//mOutputMonitor->setVisible(FALSE);
-	}
-}
-
-void LLNearbyChat::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
-{
-	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
-}
-
-void LLNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
-{
-	// Look for "/20 foo" channel chats.
-	S32 channel = 0;
-	LLWString out_text = stripChannelNumber(wtext, &channel);
-	std::string utf8_out_text = wstring_to_utf8str(out_text);
-	std::string utf8_text = wstring_to_utf8str(wtext);
-
-	utf8_text = utf8str_trim(utf8_text);
-	if (!utf8_text.empty())
-	{
-		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
-	}
-
-	// Don't animate for chats people can't hear (chat to scripts)
-	if (animate && (channel == 0))
-	{
-		if (type == CHAT_TYPE_WHISPER)
-		{
-			lldebugs << "You whisper " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
-		}
-		else if (type == CHAT_TYPE_NORMAL)
-		{
-			lldebugs << "You say " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
-		}
-		else if (type == CHAT_TYPE_SHOUT)
-		{
-			lldebugs << "You shout " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
-		}
-		else
-		{
-			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
-			return;
-		}
-	}
-	else
-	{
-		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
-		{
-			lldebugs << "Channel chat: " << utf8_text << llendl;
-		}
-	}
-
-	send_chat_from_viewer(utf8_out_text, type, channel);
-}
-
-// static 
-bool LLNearbyChat::isWordsName(const std::string& name)
-{
-	// checking to see if it's display name plus username in parentheses
-	S32 open_paren = name.find(" (", 0);
-	S32 close_paren = name.find(')', 0);
-
-	if (open_paren != std::string::npos &&
-		close_paren == name.length()-1)
-	{
-		return true;
-	}
-	else
-	{
-		//checking for a single space
-		S32 pos = name.find(' ', 0);
-		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
-	}
-}
-
-// static 
-void LLNearbyChat::startChat(const char* line)
-{
-	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
-	if (nearby_chat)
-	{
-		nearby_chat->show();
-		nearby_chat->setVisible(TRUE);
-		nearby_chat->setFocus(TRUE);
-		nearby_chat->mInputEditor->setFocus(TRUE);
-
-		if (line)
-		{
-			std::string line_string(line);
-			nearby_chat->mInputEditor->setText(line_string);
-		}
-
-		nearby_chat->mInputEditor->endOfDoc();
-	}
-}
-
-// Exit "chat mode" and do the appropriate focus changes
-// static
-void LLNearbyChat::stopChat()
-{
-	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
-	if (nearby_chat)
-	{
-		nearby_chat->mInputEditor->setFocus(FALSE);
-	    gAgent.stopTyping();
-	}
-}
-
-// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
-// Otherwise returns input and channel 0.
-LLWString LLNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel)
-{
-	if (mesg[0] == '/'
-		&& mesg[1] == '/')
-	{
-		// This is a "repeat channel send"
-		*channel = sLastSpecialChatChannel;
-		return mesg.substr(2, mesg.length() - 2);
-	}
-	else if (mesg[0] == '/'
-			 && mesg[1]
-			 && LLStringOps::isDigit(mesg[1]))
-	{
-		// This a special "/20" speak on a channel
-		S32 pos = 0;
-
-		// Copy the channel number into a string
-		LLWString channel_string;
-		llwchar c;
-		do
-		{
-			c = mesg[pos+1];
-			channel_string.push_back(c);
-			pos++;
-		}
-		while(c && pos < 64 && LLStringOps::isDigit(c));
-		
-		// Move the pointer forward to the first non-whitespace char
-		// Check isspace before looping, so we can handle "/33foo"
-		// as well as "/33 foo"
-		while(c && iswspace(c))
-		{
-			c = mesg[pos+1];
-			pos++;
-		}
-		
-		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
-		*channel = sLastSpecialChatChannel;
-		return mesg.substr(pos, mesg.length() - pos);
-	}
-	else
-	{
-		// This is normal chat.
-		*channel = 0;
-		return mesg;
-	}
-}
-
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
-{
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ChatFromViewer);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_ChatData);
-	msg->addStringFast(_PREHASH_Message, utf8_out_text);
-	msg->addU8Fast(_PREHASH_Type, type);
-	msg->addS32("Channel", channel);
-
-	gAgent.sendReliableMessage();
-
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
-}
-
-class LLChatCommandHandler : public LLCommandHandler
-{
-public:
-	// not allowed from outside the app
-	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
-    // Your code here
-	bool handle(const LLSD& tokens, const LLSD& query_map,
-				LLMediaCtrl* web)
-	{
-		bool retval = false;
-		// Need at least 2 tokens to have a valid message.
-		if (tokens.size() < 2)
-		{
-			retval = false;
-		}
-		else
-		{
-		S32 channel = tokens[0].asInteger();
-			// VWR-19499 Restrict function to chat channels greater than 0.
-			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
-			{
-				retval = true;
-		// Send unescaped message, see EXT-6353.
-		std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
-		send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
-			}
-			else
-			{
-				retval = false;
-				// Tell us this is an unsupported SLurl.
-			}
-		}
-		return retval;
-	}
-};
-
-// Creating the object registers with the dispatcher.
-LLChatCommandHandler gChatHandler;
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
deleted file mode 100644
index c6a2637e8f..0000000000
--- a/indra/newview/llnearbychat.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/** 
- * @file llnearbychat.h
- * @brief LLNearbyChat class definition
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLNEARBYCHAT_H
-#define LL_LLNEARBYCHAT_H
-
-#include "llimconversation.h"
-#include "llcombobox.h"
-#include "llgesturemgr.h"
-#include "llchat.h"
-#include "llvoiceclient.h"
-#include "lloutputmonitorctrl.h"
-#include "llspeakers.h"
-#include "llscrollbar.h"
-#include "llviewerchat.h"
-#include "llpanel.h"
-
-class LLResizeBar;
-
-class LLNearbyChat
-	:	public LLIMConversation
-{
-public:
-	// constructor for inline chat-bars (e.g. hosted in chat history window)
-	LLNearbyChat(const LLSD& key = LLSD(LLUUID()));
-	~LLNearbyChat() {}
-
-	static LLNearbyChat* buildFloater(const LLSD& key);
-
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void onClose(bool app_quitting);
-	/*virtual*/ void setVisible(BOOL visible);
-
-	void loadHistory();
-    void reloadMessages();
-	void removeScreenChat();
-
-	void addToHost();
-	void show();
-	bool isChatVisible() const;
-
-	/** @param archive true - to save a message to the chat history log */
-	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());
-	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);
-	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
-
-	LLChatEntry* getChatBox() { return mInputEditor; }
-
-	std::string getCurrentChat();
-
-	virtual BOOL handleKeyHere( KEY key, MASK mask );
-	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
-
-	static void startChat(const char* line);
-	static void stopChat();
-
-	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
-	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
-
-	static bool isWordsName(const std::string& name);
-
-	void showHistory();
-
-protected:
-	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
-	static void onChatBoxKeystroke(LLTextEditor* caller, void* userdata);
-	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
-	void onChatBoxFocusReceived();
-
-	void sendChat( EChatType type );
-	void onChatBoxCommit();
-	void onChatFontChange(LLFontGL* fontp);
-
-	/*virtual*/ void onTearOffClicked();
-	/*virtual*/ void onClickCloseBtn();
-
-	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
-	EChatType processChatTypeTriggers(EChatType type, std::string &str);
-
-	void displaySpeakingIndicator();
-
-	// Which non-zero channel did we last chat on?
-	static S32 sLastSpecialChatChannel;
-
-	LLOutputMonitorCtrl*	mOutputMonitor;
-	LLLocalSpeakerMgr*		mSpeakerMgr;
-
-	S32 mExpandedHeight;
-
-private:
-
-	void	onNearbySpeakers	();
-
-	/*virtual*/ void refresh();
-
-	LLHandle<LLView>	mPopupMenuHandle;
-	std::vector<LLChat> mMessageArchive;
-
-};
-
-#endif
diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llnearbychatbarlistener.cpp
deleted file mode 100644
index 61815d1864..0000000000
--- a/indra/newview/llnearbychatbarlistener.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * @file   llnearbychatbarlistener.cpp
- * @author Dave Simmons
- * @date   2011-03-15
- * @brief  Implementation for LLNearbyChatBarListener.
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llnearbychatbarlistener.h"
-#include "llnearbychat.h"
-
-#include "llagent.h"
-#include "llchat.h"
-
-
-
-LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChat & chatbar)
-  : LLEventAPI("LLChatBar",
-               "LLChatBar listener to (e.g.) sendChat, etc."),
-	mChatbar(chatbar)
-{
-    add("sendChat",
-        "Send chat to the simulator:\n"
-        "[\"message\"] chat message text [required]\n"
-        "[\"channel\"] chat channel number [default = 0]\n"
-		"[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]",
-        &LLNearbyChatBarListener::sendChat);
-}
-
-
-// "sendChat" command
-void LLNearbyChatBarListener::sendChat(LLSD const & chat_data) const
-{
-	// Extract the data
-	std::string chat_text = chat_data["message"].asString();
-
-	S32 channel = 0;
-	if (chat_data.has("channel"))
-	{
-		channel = chat_data["channel"].asInteger();
-		if (channel < 0 || channel >= CHAT_CHANNEL_DEBUG)
-		{	// Use 0 up to (but not including) CHAT_CHANNEL_DEBUG
-			channel = 0;
-		}
-	}
-
-	EChatType type_o_chat = CHAT_TYPE_NORMAL;
-	if (chat_data.has("type"))
-	{
-		std::string type_string = chat_data["type"].asString();
-		if (type_string == "whisper")
-		{
-			type_o_chat = CHAT_TYPE_WHISPER;
-		}
-		else if (type_string == "shout")
-		{
-			type_o_chat = CHAT_TYPE_SHOUT;
-		}
-	}
-
-	// Have to prepend /42 style channel numbers
-	std::string chat_to_send;
-	if (channel == 0)
-	{
-		chat_to_send = chat_text;
-	}
-	else
-	{
-		chat_to_send += "/";
-		chat_to_send += chat_data["channel"].asString();
-		chat_to_send += " ";
-		chat_to_send += chat_text;
-	}
-
-	// Send it as if it was typed in
-	mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0));
-}
-
diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llnearbychatbarlistener.h
deleted file mode 100644
index 0537275424..0000000000
--- a/indra/newview/llnearbychatbarlistener.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file   llnearbychatbarlistener.h
- * @author Dave Simmons
- * @date   2011-03-15
- * @brief  Class definition for LLNearbyChatBarListener.
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-#ifndef LL_LLNEARBYCHATBARLISTENER_H
-#define LL_LLNEARBYCHATBARLISTENER_H
-
-#include "lleventapi.h"
-
-class LLSD;
-class LLNearbyChat;
-
-class LLNearbyChatBarListener : public LLEventAPI
-{
-public:
-	LLNearbyChatBarListener(LLNearbyChat & chatbar);
-
-private:
-    void sendChat(LLSD const & chat_data) const;
-
-	LLNearbyChat & mChatbar;
-};
-
-#endif // LL_LLNEARBYCHATBARLISTENER_H
-
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
deleted file mode 100644
index 1494d9d6ee..0000000000
--- a/indra/newview/llnearbychathandler.cpp
+++ /dev/null
@@ -1,630 +0,0 @@
-/** 
- * @file LLNearbyChatHandler.cpp
- * @brief Nearby chat chat managment
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llagentdata.h" // for gAgentID
-#include "llnearbychathandler.h"
-
-#include "llchatitemscontainerctrl.h"
-#include "llfirstuse.h"
-#include "llfloaterscriptdebug.h"
-#include "llhints.h"
-#include "llnearbychat.h"
-#include "llrecentpeople.h"
-
-#include "llviewercontrol.h"
-
-#include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
-#include "llviewerwindow.h"//for screen channel position
-#include "llnearbychat.h"
-#include "llrootview.h"
-#include "lllayoutstack.h"
-
-//add LLNearbyChatHandler to LLNotificationsUI namespace
-using namespace LLNotificationsUI;
-
-static LLNearbyChatToastPanel* createToastPanel()
-{
-	LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
-	return item;
-}
-
-
-//-----------------------------------------------------------------------------------------------
-//LLNearbyChatScreenChannel
-//-----------------------------------------------------------------------------------------------	
-
-class LLNearbyChatScreenChannel: public LLScreenChannelBase
-{
-	LOG_CLASS(LLNearbyChatScreenChannel);
-public:
-	typedef std::vector<LLHandle<LLToast> > toast_vec_t;
-	typedef std::list<LLHandle<LLToast> > toast_list_t;
-
-	LLNearbyChatScreenChannel(const Params& p)
-		: LLScreenChannelBase(p)
-	{
-		mStopProcessing = false;
-
-		LLControlVariable* ctrl = gSavedSettings.getControl("NearbyToastLifeTime").get();
-		if (ctrl)
-		{
-			ctrl->getSignal()->connect(boost::bind(&LLNearbyChatScreenChannel::updateToastsLifetime, this));
-		}
-
-		ctrl = gSavedSettings.getControl("NearbyToastFadingTime").get();
-		if (ctrl)
-		{
-			ctrl->getSignal()->connect(boost::bind(&LLNearbyChatScreenChannel::updateToastFadingTime, this));
-		}
-	}
-
-	void addChat	(LLSD& chat);
-	void arrangeToasts		();
-	
-	typedef boost::function<LLNearbyChatToastPanel* (void )> create_toast_panel_callback_t;
-	void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
-
-	void onToastDestroyed	(LLToast* toast, bool app_quitting);
-	void onToastFade		(LLToast* toast);
-
-	void redrawToasts()
-	{
-		arrangeToasts();
-	}
-
-	// hide all toasts from screen, but not remove them from a channel
-	// removes all toasts from a channel
-	virtual void		removeToastsFromChannel() 
-	{
-		for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
-		{
-			addToToastPool(it->get());
-		}
-		m_active_toasts.clear();
-	};
-
-	virtual void deleteAllChildren()
-	{
-		LL_DEBUGS("NearbyChat") << "Clearing toast pool" << llendl;
-		m_toast_pool.clear();
-		m_active_toasts.clear();
-		LLScreenChannelBase::deleteAllChildren();
-	}
-
-protected:
-	void	deactivateToast(LLToast* toast);
-	void	addToToastPool(LLToast* toast)
-	{
-		if (!toast) return;
-		LL_DEBUGS("NearbyChat") << "Pooling toast" << llendl;
-		toast->setVisible(FALSE);
-		toast->stopTimer();
-		toast->setIsHidden(true);
-
-		// Nearby chat toasts that are hidden, not destroyed. They are collected to the toast pool, so that
-		// they can be used next time, this is done for performance. But if the toast lifetime was changed
-		// (from preferences floater (STORY-36)) while it was shown (at this moment toast isn't in the pool yet)
-		// changes don't take affect.
-		// So toast's lifetime should be updated each time it's added to the pool. Otherwise viewer would have
-		// to be restarted so that changes take effect.
-		toast->setLifetime(gSavedSettings.getS32("NearbyToastLifeTime"));
-		toast->setFadingTime(gSavedSettings.getS32("NearbyToastFadingTime"));
-		m_toast_pool.push_back(toast->getHandle());
-	}
-
-	void	createOverflowToast(S32 bottom, F32 timer);
-
-	void 	updateToastsLifetime();
-
-	void	updateToastFadingTime();
-
-	create_toast_panel_callback_t m_create_toast_panel_callback_t;
-
-	bool	createPoolToast();
-	
-	toast_vec_t m_active_toasts;
-	toast_list_t m_toast_pool;
-
-	bool	mStopProcessing;
-	bool	mChannelRect;
-};
-
-
-
-//-----------------------------------------------------------------------------------------------
-// LLNearbyChatToast
-//-----------------------------------------------------------------------------------------------
-
-// We're deriving from LLToast to be able to override onClose()
-// in order to handle closing nearby chat toasts properly.
-class LLNearbyChatToast : public LLToast
-{
-	LOG_CLASS(LLNearbyChatToast);
-public:
-	LLNearbyChatToast(const LLToast::Params& p, LLNearbyChatScreenChannel* nc_channelp)
-	:	LLToast(p),
-	 	mNearbyChatScreenChannelp(nc_channelp)
-	{
-	}
-
-	/*virtual*/ void onClose(bool app_quitting);
-
-private:
-	LLNearbyChatScreenChannel*	mNearbyChatScreenChannelp;
-};
-
-//-----------------------------------------------------------------------------------------------
-// LLNearbyChatScreenChannel
-//-----------------------------------------------------------------------------------------------
-
-void LLNearbyChatScreenChannel::deactivateToast(LLToast* toast)
-{
-	toast_vec_t::iterator pos = std::find(m_active_toasts.begin(), m_active_toasts.end(), toast->getHandle());
-
-	if (pos == m_active_toasts.end())
-	{
-		llassert(pos == m_active_toasts.end());
-		return;
-	}
-
-	LL_DEBUGS("NearbyChat") << "Deactivating toast" << llendl;
-	m_active_toasts.erase(pos);
-}
-
-void	LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
-{
-	//we don't need overflow toast in nearby chat
-}
-
-void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting)
-{	
-	LL_DEBUGS("NearbyChat") << "Toast destroyed (app_quitting=" << app_quitting << ")" << llendl;
-
-	if (app_quitting)
-	{
-		// Viewer is quitting.
-		// Immediately stop processing chat messages (EXT-1419).
-	mStopProcessing = true;
-}
-	else
-	{
-		// The toast is being closed by user (STORM-192).
-		// Remove it from the list of active toasts to prevent
-		// further references to the invalid pointer.
-		deactivateToast(toast);
-	}
-}
-
-void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
-{	
-	LL_DEBUGS("NearbyChat") << "Toast fading" << llendl;
-
-	//fade mean we put toast to toast pool
-	if(!toast)
-		return;
-
-	deactivateToast(toast);
-
-	addToToastPool(toast);
-	
-	arrangeToasts();
-}
-
-void LLNearbyChatScreenChannel::updateToastsLifetime()
-{
-	S32 seconds = gSavedSettings.getS32("NearbyToastLifeTime");
-	toast_list_t::iterator it;
-
-	for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it)
-	{
-		(*it).get()->setLifetime(seconds);
-	}
-}
-
-void LLNearbyChatScreenChannel::updateToastFadingTime()
-{
-	S32 seconds = gSavedSettings.getS32("NearbyToastFadingTime");
-	toast_list_t::iterator it;
-
-	for(it = m_toast_pool.begin(); it != m_toast_pool.end(); ++it)
-	{
-		(*it).get()->setFadingTime(seconds);
-	}
-}
-
-bool	LLNearbyChatScreenChannel::createPoolToast()
-{
-	LLNearbyChatToastPanel* panel= m_create_toast_panel_callback_t();
-	if(!panel)
-		return false;
-	
-	LLToast::Params p;
-	p.panel = panel;
-	p.lifetime_secs = gSavedSettings.getS32("NearbyToastLifeTime");
-	p.fading_time_secs = gSavedSettings.getS32("NearbyToastFadingTime");
-
-	LLToast* toast = new LLNearbyChatToast(p, this);
-	
-	
-	toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
-
-	// If the toast gets somehow prematurely destroyed, deactivate it to prevent crash (STORM-1352).
-	toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1, false));
-
-	LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl;	
-	m_toast_pool.push_back(toast->getHandle());
-	return true;
-}
-
-void LLNearbyChatScreenChannel::addChat(LLSD& chat)
-{
-	//look in pool. if there is any message
-	if(mStopProcessing)
-		return;
-
-	/*
-    find last toast and check ID
-	*/
-
-	if(m_active_toasts.size())
-	{
-		LLUUID fromID = chat["from_id"].asUUID();		// agent id or object id
-		std::string from = chat["from"].asString();
-		LLToast* toast = m_active_toasts[0].get();
-		if (toast)
-		{
-			LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel());
-  
-			if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText())
-			{
-				panel->addMessage(chat);
-				toast->reshapeToPanel();
-				toast->startTimer();
-	  
-				arrangeToasts();
-				return;
-			}
-		}
-	}
-	
-
-	
-	if(m_toast_pool.empty())
-	{
-		//"pool" is empty - create one more panel
-		LL_DEBUGS("NearbyChat") << "Empty pool" << llendl;
-		if(!createPoolToast())//created toast will go to pool. so next call will find it
-			return;
-		addChat(chat);
-		return;
-	}
-
-	int chat_type = chat["chat_type"].asInteger();
-	
-	if( ((EChatType)chat_type == CHAT_TYPE_DEBUG_MSG))
-	{
-		if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) 
-			return;
-		if(gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)
-			return;
-	}
-		
-
-	//take 1st element from pool, (re)initialize it, put it in active toasts
-
-	LL_DEBUGS("NearbyChat") << "Getting toast from pool" << llendl;
-	LLToast* toast = m_toast_pool.back().get();
-
-	m_toast_pool.pop_back();
-
-
-	LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel());
-	if(!panel)
-		return;
-	panel->init(chat);
-
-	toast->reshapeToPanel();
-	toast->startTimer();
-	
-	m_active_toasts.push_back(toast->getHandle());
-
-	arrangeToasts();
-}
-
-static bool sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> second)
-{
-	if (!first.get() || !second.get()) return false; // STORM-1352
-
-	F32 v1 = first.get()->getTimeLeftToLive();
-	F32 v2 = second.get()->getTimeLeftToLive();
-	return v1 > v2;
-}
-
-void LLNearbyChatScreenChannel::arrangeToasts()
-{
-	if(mStopProcessing || isHovering())
-		return;
-
-	if (mFloaterSnapRegion == NULL)
-	{
-		mFloaterSnapRegion = gViewerWindow->getRootView()->getChildView("floater_snap_region");
-	}
-	
-	if (!getParent())
-	{
-		// connect to floater snap region just to get resize events, we don't care about being a proper widget 
-		mFloaterSnapRegion->addChild(this);
-		setFollows(FOLLOWS_ALL);
-	}
-
-	LLRect	toast_rect;	
-	updateRect();
-
-	LLRect channel_rect;
-	mFloaterSnapRegion->localRectToOtherView(mFloaterSnapRegion->getLocalRect(), &channel_rect, gFloaterView);
-	channel_rect.mLeft += 10;
-	channel_rect.mRight = channel_rect.mLeft + 300;
-
-	S32 channel_bottom = channel_rect.mBottom;
-
-	S32		bottom = channel_bottom + 80;
-	S32		margin = gSavedSettings.getS32("ToastGap");
-
-	//sort active toasts
-	std::sort(m_active_toasts.begin(),m_active_toasts.end(),sort_toasts_predicate);
-
-	//calc max visible item and hide other toasts.
-
-	for(toast_vec_t::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
-	{
-		LLToast* toast = it->get();
-		if (!toast)
-		{
-			llwarns << "NULL found in the active chat toasts list!" << llendl;
-			continue;
-		}
-
-		S32 toast_top = bottom + toast->getRect().getHeight() + margin;
-
-		if(toast_top > channel_rect.getHeight())
-		{
-			while(it!=m_active_toasts.end())
-			{
-				addToToastPool(it->get());
-				it=m_active_toasts.erase(it);
-			}
-			break;
-		}
-
-		toast_rect = toast->getRect();
-		toast_rect.setLeftTopAndSize(channel_rect.mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());
-
-		toast->setRect(toast_rect);
-		bottom += toast_rect.getHeight() - toast->getTopPad() + margin;
-	}
-	
-	// use reverse order to provide correct z-order and avoid toast blinking
-	
-	for(toast_vec_t::reverse_iterator it = m_active_toasts.rbegin(); it != m_active_toasts.rend(); ++it)
-	{
-		LLToast* toast = it->get();
-		if (toast)
-	{
-		toast->setIsHidden(false);
-		toast->setVisible(TRUE);
-		}
-	}
-
-}
-
-
-
-//-----------------------------------------------------------------------------------------------
-//LLNearbyChatHandler
-//-----------------------------------------------------------------------------------------------
-boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat"));
-
-LLNearbyChatHandler::LLNearbyChatHandler()
-{
-	// Getting a Channel for our notifications
-	LLNearbyChatScreenChannel::Params p;
-	p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
-	LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(p);
-	
-	LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
-
-	channel->setCreatePanelCallback(callback);
-
-	LLChannelManager::getInstance()->addChannel(channel);
-
-	mChannel = channel->getHandle();
-}
-
-LLNearbyChatHandler::~LLNearbyChatHandler()
-{
-}
-
-
-void LLNearbyChatHandler::initChannel()
-{
-	//LLRect snap_rect = gFloaterView->getSnapRect();
-	//mChannel->init(snap_rect.mLeft, snap_rect.mLeft + 200);
-}
-
-
-
-void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
-									  const LLSD &args)
-{
-	if(chat_msg.mMuted == TRUE)
-		return;
-
-	if(chat_msg.mText.empty())
-		return;//don't process empty messages
-
-    LLFloaterReg::getInstance("im_container");
-	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
-
-	// Build notification data 
-	LLSD chat;
-	chat["message"] = chat_msg.mText;
-	chat["from"] = chat_msg.mFromName;
-	chat["from_id"] = chat_msg.mFromID;
-	chat["time"] = chat_msg.mTime;
-	chat["source"] = (S32)chat_msg.mSourceType;
-	chat["chat_type"] = (S32)chat_msg.mChatType;
-	chat["chat_style"] = (S32)chat_msg.mChatStyle;
-	// Pass sender info so that it can be rendered properly (STORM-1021).
-	chat["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
-
-	if (chat_msg.mChatType == CHAT_TYPE_DIRECT &&
-		chat_msg.mText.length() > 0 &&
-		chat_msg.mText[0] == '@')
-	{
-		// Send event on to LLEventStream and exit
-		sChatWatcher->post(chat);
-		return;
-	}
-
-	// don't show toast and add message to chat history on receive debug message
-	// with disabled setting showing script errors or enabled setting to show script
-	// errors in separate window.
-	if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
-	{
-		if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE)
-			return;
-
-		// don't process debug messages from not owned objects, see EXT-7762
-		if (gAgentID != chat_msg.mOwnerID)
-		{
-			return;
-		}
-
-		if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat"))
-		{
-
-			LLColor4 txt_color;
-
-			LLViewerChat::getChatColor(chat_msg,txt_color);
-
-			LLFloaterScriptDebug::addScriptLine(chat_msg.mText,
-												chat_msg.mFromName,
-												txt_color,
-												chat_msg.mFromID);
-			return;
-		}
-	}
-
-	nearby_chat->addMessage(chat_msg, true, args);
-
-	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT 
-		&& chat_msg.mFromID.notNull() 
-		&& chat_msg.mFromID != gAgentID)
-	{
- 		LLFirstUse::otherAvatarChatFirst();
-
- 		// Add sender to the recent people list.
- 		LLRecentPeople::instance().add(chat_msg.mFromID);
-
-	}
-
-	// Send event on to LLEventStream
-	sChatWatcher->post(chat);
-
-	if( nearby_chat->isInVisibleChain()
-		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
-			&& gSavedSettings.getBOOL("UseChatBubbles") )
-		|| mChannel.isDead()
-		|| !mChannel.get()->getShowToasts() ) // to prevent toasts in Do Not Disturb mode
-		return;//no need in toast if chat is visible or if bubble chat is enabled
-
-	// arrange a channel on a screen
-	if(!mChannel.get()->getVisible())
-	{
-		initChannel();
-	}
-
-	/*
-	//comment all this due to EXT-4432
-	..may clean up after some time...
-
-	//only messages from AGENTS
-	if(CHAT_SOURCE_OBJECT == chat_msg.mSourceType)
-	{
-		if(chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
-			return;//ok for now we don't skip messeges from object, so skip only debug messages
-	}
-	*/
-
-	LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel.get());
-
-	if(channel)
-	{
-		// Handle IRC styled messages.
-		std::string toast_msg;
-		if (chat_msg.mChatStyle == CHAT_STYLE_IRC)
-		{
-			if (!chat_msg.mFromName.empty())
-			{
-				toast_msg += chat_msg.mFromName;
-			}
-			toast_msg += chat_msg.mText.substr(3);
-		}
-		else
-		{
-			toast_msg = chat_msg.mText;
-		}
-
-		// Add a nearby chat toast.
-		LLUUID id;
-		id.generate();
-		chat["id"] = id;
-		std::string r_color_name = "White";
-		F32 r_color_alpha = 1.0f; 
-		LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
-		
-		chat["text_color"] = r_color_name;
-		chat["color_alpha"] = r_color_alpha;
-		chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
-		chat["message"] = toast_msg;
-		channel->addChat(chat);	
-	}
-}
-
-
-//-----------------------------------------------------------------------------------------------
-// LLNearbyChatToast
-//-----------------------------------------------------------------------------------------------
-
-// virtual
-void LLNearbyChatToast::onClose(bool app_quitting)
-{
-	mNearbyChatScreenChannelp->onToastDestroyed(this, app_quitting);
-}
-
-// EOF
diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llnearbychathandler.h
deleted file mode 100644
index a5034ac1cb..0000000000
--- a/indra/newview/llnearbychathandler.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/** 
- * @file llnearbychathandler.h
- * @brief nearby chat notify
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLNEARBYCHATHANDLER_H
-#define LL_LLNEARBYCHATHANDLER_H
-
-#include "llnotificationhandler.h"
-
-class LLEventPump;
-
-//add LLNearbyChatHandler to LLNotificationsUI namespace
-namespace LLNotificationsUI{
-
-class LLNearbyChatHandler : public LLChatHandler
-{
-public:
-	LLNearbyChatHandler();
-	virtual ~LLNearbyChatHandler();
-
-
-	virtual void processChat(const LLChat& chat_msg, const LLSD &args);
-
-protected:
-	virtual void initChannel();
-
-	static boost::scoped_ptr<LLEventPump> sChatWatcher;
-};
-
-}
-
-#endif /* LL_LLNEARBYCHATHANDLER_H */
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 0899625242..4bded6ab30 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -36,7 +36,7 @@
 #include "llinstantmessage.h"
 #include "llnotificationptr.h"
 
-class LLIMFloater;
+class LLFloaterIMSession;
 
 namespace LLNotificationsUI
 {
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index b4e8927879..7f1216ff40 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -34,9 +34,9 @@
 #include "llurlaction.h"
 
 #include "llagent.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llimview.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotificationhandler.h"
 
 using namespace LLNotificationsUI;
@@ -52,7 +52,7 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
 
 	LLUUID from_id = notification->getPayload()["from_id"];
 	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
-	LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+	LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
 
 	if (im_floater != NULL)
 	{
@@ -164,7 +164,7 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
 // static
 void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
 {
-    LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
+    LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 	if (nearby_chat)
 	{
 		LLChat chat_msg(notification->getMessage());
@@ -244,7 +244,7 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification)
 // static
 void LLHandlerUtil::updateIMFLoaterMesages(const LLUUID& session_id)
 {
-	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 	if (im_floater != NULL && im_floater->getVisible())
 	{
 		im_floater->updateMessages();
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index 2862ad6962..56f13802e3 100644
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -31,7 +31,7 @@
 
 #include "llnotificationmanager.h"
 
-#include "llnearbychathandler.h"
+#include "llfloaterimnearbychathandler.h"
 #include "llnotifications.h"
 
 #include <boost/bind.hpp>
@@ -64,7 +64,7 @@ void LLNotificationManager::init()
 	mChannels.push_back(new LLOutboxNotification());
 	mChannels.push_back(new LLIMHandler());
   
-	mChatHandler = boost::shared_ptr<LLNearbyChatHandler>(new LLNearbyChatHandler());
+	mChatHandler = boost::shared_ptr<LLFloaterIMNearbyChatHandler>(new LLFloaterIMNearbyChatHandler());
 }
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
index c8afdf9e46..f37c6b833c 100644
--- a/indra/newview/llnotificationmanager.h
+++ b/indra/newview/llnotificationmanager.h
@@ -60,7 +60,7 @@ public:
 	void onChat(const LLChat& msg, const LLSD &args);
 
 private:
-	boost::shared_ptr<class LLNearbyChatHandler> mChatHandler;
+	boost::shared_ptr<class LLFloaterIMNearbyChatHandler> mChatHandler;
 	std::vector<LLNotificationChannelPtr> mChannels;
 };
 
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index a293e6acb6..faa67b5ea4 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -28,8 +28,8 @@
 #include "llviewerprecompiledheaders.h" // must be first include
 
 #include "llfloaterreg.h"
-#include "llnearbychat.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotificationhandler.h"
 #include "llnotifications.h"
 #include "lltoastnotifypanel.h"
@@ -85,7 +85,7 @@ bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 		LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
 
 		// don't show toast if Nearby Chat is opened
-		LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 		if (nearby_chat->isChatVisible())
 		{
 			return false;
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 9a4d1166db..9f89b5f809 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -28,7 +28,7 @@
 
 #include "llavatarnamecache.h"
 #include "llimview.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
 #include "llparticipantlist.h"
 #include "llspeakers.h"
 
@@ -316,7 +316,7 @@ bool LLParticipantList::onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> eve
 	if ( evt_data.has("id") )
 	{
 		LLUUID participant_id = evt_data["id"];
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
+		LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
 		if (im_box)
 		{
 			im_box->setTimeNow(mUUID,participant_id);
@@ -345,7 +345,7 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> e
 					mModeratorList.erase(id);
 				}
 			}
-			// *TODO : do we have to fire an event so that LLIMConversation::refreshConversation() gets called
+			// *TODO : do we have to fire an event so that LLFloaterIMSessionTab::refreshConversation() gets called
 		}
 	}
 	return true;
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index a4a0198305..3bcf36ffde 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -39,7 +39,7 @@
 
 #include "lldockablefloater.h"
 #include "llsyswellwindow.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llscriptfloater.h"
 #include "llrootview.h"
 
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 6f98be1cb8..dc12192697 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -41,7 +41,7 @@
 #include "lltoastscripttextbox.h"
 #include "lltrans.h"
 #include "llviewerwindow.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index c827b39d0e..8932d12e20 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -54,7 +54,7 @@
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
 #include "llhttpsender.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "lllocationhistory.h"
 #include "llimageworker.h"
 
@@ -63,8 +63,8 @@
 #include "llmemorystream.h"
 #include "llmessageconfig.h"
 #include "llmoveview.h"
-#include "llimfloatercontainer.h"
-#include "llnearbychat.h"
+#include "llfloaterimcontainer.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llteleporthistory.h"
@@ -1384,7 +1384,7 @@ bool idle_startup()
 
 		// create a container's instance for start a controlling conversation windows
 		// by the voice's events
-		LLIMFloaterContainer::getInstance();
+		LLFloaterIMContainer::getInstance();
 
 		// *Note: this is where gWorldMap used to be initialized.
 
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 4a49922656..65b4a3a44c 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -40,7 +40,7 @@
 #include "lltrans.h"
 #include "llnotificationsutil.h"
 #include "llviewermessage.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 
 const S32 BOTTOM_PAD = VPAD * 3;
 const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index b99d04abae..c6b28b9e5e 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -71,7 +71,7 @@
 #include "llfloatermediasettings.h"
 #include "llfloaterhud.h"
 #include "llfloaterimagepreview.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llfloaterinspect.h"
 #include "llfloaterinventory.h"
 #include "llfloaterjoystick.h"
@@ -120,14 +120,14 @@
 #include "llfloaterwhitelistentry.h"
 #include "llfloaterwindowsize.h"
 #include "llfloaterworldmap.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
 #include "llinspectavatar.h"
 #include "llinspectgroup.h"
 #include "llinspectobject.h"
 #include "llinspectremoteobject.h"
 #include "llinspecttoast.h"
 #include "llmoveview.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llpanelblockedlist.h"
 #include "llpanelclassified.h"
 #include "llpreviewanim.h"
@@ -193,7 +193,7 @@ void LLViewerFloaterReg::registerFloaters()
 
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
 	LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
-	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLNearbyChat::buildFloater);
+	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
 	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
 
@@ -217,8 +217,8 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);	
 	LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
 
-	LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
-	LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>);
+	LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMSession>);
+	LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMContainer>);
 	LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>);
 	LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
 	LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index 71608b5280..3f35a5001d 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -41,7 +41,7 @@
 #include "llviewermessage.h" // send_guid_sound_trigger
 #include "llviewernetwork.h"
 #include "llagent.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 
 // Globals
 LLViewerGestureList gGestureList;
@@ -131,7 +131,7 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
 	{
 		// Don't play nodding animation, since that might not blend
 		// with the gesture animation.
-		(LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->
+		(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
 				sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
 	}
 }
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index f8e988bc0c..4ecdc31e21 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -32,7 +32,7 @@
 #include "llmath.h"
 #include "llagent.h"
 #include "llagentcamera.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llviewercontrol.h"
 #include "llfocusmgr.h"
 #include "llmorphview.h"
@@ -535,7 +535,7 @@ void stop_moving( EKeystate s )
 void start_chat( EKeystate s )
 {
 	// start chat
-	LLNearbyChat::startChat(NULL);
+	LLFloaterIMNearbyChat::startChat(NULL);
 }
 
 void start_gesture( EKeystate s )
@@ -544,15 +544,15 @@ void start_gesture( EKeystate s )
 	if (KEYSTATE_UP == s &&
 		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
 	{
- 		if ((LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat"))->getCurrentChat().empty())
+ 		if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty())
  		{
  			// No existing chat in chat editor, insert '/'
- 			LLNearbyChat::startChat("/");
+ 			LLFloaterIMNearbyChat::startChat("/");
  		}
  		else
  		{
  			// Don't overwrite existing text in chat editor
- 			LLNearbyChat::startChat(NULL);
+ 			LLFloaterIMNearbyChat::startChat(NULL);
  		}
 	}
 }
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 1ddfc51f27..47249fad70 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -68,7 +68,7 @@
 #include "llinventoryfunctions.h"
 #include "llinventoryobserver.h"
 #include "llinventorypanel.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llpanelgrouplandmoney.h"
@@ -2295,7 +2295,7 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m
 	// Treat like a system message and put in chat history.
 	chat.mText = av_name.getCompleteName() + ": " + message;
 
-	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 	if (nearby_chat)
 	{
 		nearby_chat->addMessage(chat);
@@ -2877,7 +2877,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
 			// IMs from obejcts don't open IM sessions.
-			LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat");
+			LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 			if(!chat_from_system && nearby_chat)
 			{
 				chat.mOwnerID = from_id;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ee838b19b7..afc3e3965c 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -188,7 +188,7 @@
 #include "llviewerjoystick.h"
 #include "llviewernetwork.h"
 #include "llpostprocess.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llagentui.h"
 #include "llwearablelist.h"
 
@@ -2496,7 +2496,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		return TRUE;
 	}
 
-	LLNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat");
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 
 	// Traverses up the hierarchy
 	if( keyboard_focus )
@@ -2574,7 +2574,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 			LLFloaterReg::toggleInstanceOrBringToFront(name);
 		}
 
-		LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLNearbyChat>("nearby_chat")->getChatBox();
+		LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
-- 
cgit v1.2.3


From 828374749682a5febc6ebac81321e80dee11085e Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 12 Nov 2012 16:25:35 +0200
Subject: CHUI-386 FIXED Vertical scrollbar not fully showing in conversation
 message panel

---
 .../skins/default/xui/en/floater_im_session.xml    | 26 +++++++++++-----------
 1 file changed, 13 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index a889eb7933..1d74f1bc25 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -203,7 +203,7 @@
              name="translate_chat_checkbox_lp"
              top_delta="0"
              visible="true"
-             width="230">
+             width="210">
                 <check_box
                  top="10"
                  control_name="TranslateChat"
@@ -217,7 +217,7 @@
             </layout_panel>
             <layout_panel
              height="248"
-             width="230"
+             width="210"
              layout="topleft"
              follows="all"
              left_delta="0"
@@ -227,17 +227,17 @@
              user_resize="true"
              auto_resize="true"
              name="chat_holder">      
-        <chat_history
-	 font="SansSerifSmall"
-             		follows="all"
-             		visible="true"
-             		height="240"
-         name="chat_history"
-         parse_highlights="true"
-         parse_urls="true"
-       	 width="230"
-       	 left="5">
-        </chat_history>
+               <chat_history
+                font="SansSerifSmall"
+                follows="all"
+                visible="true"
+                height="240"
+                name="chat_history"
+                parse_highlights="true"
+                parse_urls="true"
+                right="-5"
+                left="5">
+               </chat_history>
             </layout_panel>
            </layout_stack>
            </panel>
-- 
cgit v1.2.3


From 2813e49d198400a0f6416e01f720bdeb5f506144 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 9 Nov 2012 15:13:52 +0200
Subject: CHUI-362 WIP (Torn off conversation name is highlighted when selected
 in conversation list with different conversation showing in message panel):
 implemented method for a switch off tabs (switching to an invisible state)

---
 indra/llui/lltabcontainer.cpp | 11 +++++++++++
 indra/llui/lltabcontainer.h   |  3 ++-
 2 files changed, 13 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index d0920685bf..c24eb2ee90 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1556,6 +1556,17 @@ BOOL LLTabContainer::setTab(S32 which)
 	return is_visible;
 }
 
+
+void LLTabContainer::hideAllTabs()
+{
+	setCurrentPanelIndex(-1);
+	for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
+	{
+		(* iter)->mTabPanel->setVisible(FALSE);
+	}
+}
+
+
 BOOL LLTabContainer::selectTabByName(const std::string& name)
 {
 	LLPanel* panel = getPanelByName(name);
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index cebace2ceb..a9cdf22b16 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -188,10 +188,11 @@ public:
 	void		selectFirstTab();
 	void		selectLastTab();
 	void		selectNextTab();
-	 void		selectPrevTab();
+	void		selectPrevTab();
 	BOOL 		selectTabPanel( LLPanel* child );
 	BOOL 		selectTab(S32 which);
 	BOOL 		selectTabByName(const std::string& title);
+	void        hideAllTabs();
 
 	BOOL        getTabPanelFlashing(LLPanel* child);
 	void		setTabPanelFlashing(LLPanel* child, BOOL state);
-- 
cgit v1.2.3


From 3d42133ecb7671d8284bc0309f8df9e6e7f2df9c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 9 Nov 2012 17:04:21 +0200
Subject: CHUI-362 WIP (Torn off conversation name is highlighted when selected
 in conversation list with different conversation showing in message panel):
 implemented the stub panel and a control of it's visibility

---
 indra/newview/llfloaterimcontainer.cpp             | 12 +++++++
 indra/newview/llfloaterimcontainer.h               |  3 ++
 indra/newview/llfloaterimsessiontab.cpp            |  1 +
 .../skins/default/xui/en/floater_im_container.xml  | 42 +++++++++++++++++++++-
 4 files changed, 57 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2789b78c2d..994a76189a 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -141,6 +141,8 @@ BOOL LLFloaterIMContainer::postBuild()
 	// mTabContainer will be initialized in LLMultiFloater::addChild()
 	
 	setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
+	mStubPanel = getChild<LLPanel>("stub_panel");
+    mStubTextBox = getChild<LLTextBox>("stub_textbox");
 
 	mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
 	mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel");
@@ -494,6 +496,16 @@ void LLFloaterIMContainer::tabClose()
 	}
 }
 
+void LLFloaterIMContainer::showStub(bool stub_is_visible)
+{
+	if (stub_is_visible)
+	{
+		mTabContainer->hideAllTabs();
+	}
+
+	mStubPanel->setVisible(stub_is_visible);
+}
+
 void LLFloaterIMContainer::setVisible(BOOL visible)
 {	LLFloaterIMNearbyChat* nearby_chat;
 	if (visible)
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index f65e946dad..a09cde60f5 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -71,6 +71,7 @@ public:
     BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
 
 	/*virtual*/ void tabClose();
+	void showStub(bool visible);
 
 	static LLFloater* getCurrentVoiceFloater();
 	static LLFloaterIMContainer* findInstance();
@@ -146,6 +147,8 @@ private:
 	void openNearbyChat();
 
 	LLButton* mExpandCollapseBtn;
+	LLPanel* mStubPanel;
+	LLTextBox* mStubTextBox;
 	LLLayoutPanel* mMessagesPane;
 	LLLayoutPanel* mConversationsPane;
 	LLLayoutStack* mConversationsStack;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index c39319b373..3a1cc2880a 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -313,6 +313,7 @@ void LLFloaterIMSessionTab::onFocusReceived()
 	if (container)
 	{
 		container->selectConversationPair(mSessionID, true);
+		container->showStub(! getHost());
 	}
 }
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 590ce45c33..e3db3d52ed 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -124,7 +124,47 @@
              left="0"
              name="im_box_tab_container"
              top="0"
-             width="412"/>
+             width="412">
+             <panel
+               follows="all"
+               layout="topleft"
+               name="stub_panel"
+               opaque="true"
+               top_pad="0"
+               left="0"
+               height="430"
+               width="412">
+                 <text
+                   type="string"
+                   clip_partial="false"
+                   follows="left|top"
+                   layout="topleft"
+                   left="20"
+                   right="-20"
+                   name="stub_textbox_1"
+                   top="10"
+                   height="20"
+                   valign="center"
+                   wrap="true">
+                   This conversation is in a separate window.
+                 </text>
+                 <text
+                   type="string"
+                   clip_partial="false"
+                   follows="left|top"
+                   layout="topleft"
+                   left="20"
+                   right="-20"
+                   name="stub_textbox_2"
+                   top="40"
+                   height="20"
+                   valign="center"
+                   parse_urls="false"
+                   wrap="true">
+                     Bring it back.
+                </text>
+             </panel>
+            </panel_container>
         </layout_panel>
     </layout_stack>
 </multi_floater>
-- 
cgit v1.2.3


From 5790565ec6a2885fbe494c04c687e98cabf514a6 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 9 Nov 2012 19:44:37 +0200
Subject: Additional fix for CHUI-473

---
 indra/newview/llconversationview.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 3495d74191..295dd2ae6d 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -207,11 +207,11 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
 {
 	LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
     LLUUID session_id = item? item->getUUID() : LLUUID();
-
+    BOOL result = LLFolderViewFolder::handleMouseDown(x, y, mask);
 	(LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
     		selectConversationPair(session_id, false);
 
-	return LLFolderViewFolder::handleMouseDown(x, y, mask);
+	return result;
 }
 
 // virtual
@@ -240,7 +240,7 @@ void LLConversationViewSession::toggleOpen()
 		{
 			getParentFolder()->setSelection(this, true);
 		}
-		
+
 	}
 }
 
@@ -504,11 +504,11 @@ BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
 	    item = dynamic_cast<LLConversationItem*>(session_widget->getViewModelItem());
 	}
     LLUUID session_id = item? item->getUUID() : LLUUID();
+    BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask);
+    (LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
+        		selectConversationPair(session_id, false);
 
-	(LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
-    		selectConversationPair(session_id, false);
-
-	return LLFolderViewItem::handleMouseDown(x, y, mask);
+	return result;
 }
 
 S32 LLConversationViewParticipant::getLabelXPos()
-- 
cgit v1.2.3


From 4f58b4088a469d907eb33f1e338569016ba4c1f1 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 9 Nov 2012 14:41:50 -0800
Subject: CHUI-517: Altering the behavior and copy of the main menu status
 choices.  Busy has been replaced with Do Not Disturb.  And both status
 options have been switched to be indicated with a check rather than
 alternating text.

---
 indra/newview/llagent.cpp                          | 18 +----------
 indra/newview/llviewermenu.cpp                     | 25 +++++++++++----
 indra/newview/llviewermenu.h                       |  2 --
 indra/newview/skins/default/xui/en/menu_viewer.xml | 37 ++++++++++++++--------
 indra/newview/skins/default/xui/en/strings.xml     |  6 ----
 5 files changed, 44 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 9c3a7ac45b..d548ca8fb9 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1356,12 +1356,7 @@ void LLAgent::setAFK()
 	{
 		sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_START);
 		setControlFlags(AGENT_CONTROL_AWAY | AGENT_CONTROL_STOP);
-		LL_INFOS("AFK") << "Setting Away" << LL_ENDL;
 		gAwayTimer.start();
-		if (gAFKMenu)
-		{
-			gAFKMenu->setLabel(LLTrans::getString("AvatarSetNotAway"));
-		}
 	}
 }
 
@@ -1380,11 +1375,6 @@ void LLAgent::clearAFK()
 	{
 		sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_STOP);
 		clearControlFlags(AGENT_CONTROL_AWAY);
-		LL_INFOS("AFK") << "Clearing Away" << LL_ENDL;
-		if (gAFKMenu)
-		{
-			gAFKMenu->setLabel(LLTrans::getString("AvatarSetAway"));
-		}
 	}
 }
 
@@ -1402,13 +1392,7 @@ BOOL LLAgent::getAFK() const
 void LLAgent::setDoNotDisturb(bool pIsDotNotDisturb)
 {
 	mIsDoNotDisturb = pIsDotNotDisturb;
-	EAnimRequest animRequest = (pIsDotNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
-
-	sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, animRequest);
-	if (gDoNotDisturbMenu)
-	{
-		gDoNotDisturbMenu->setLabel(LLTrans::getString((pIsDotNotDisturb ? "AvatarSetAvailable" : "AvatarSetDoNotDisturb")));
-	}
+	sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, (pIsDotNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP));
 	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDotNotDisturb);
 }
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ac6110f84f..511807ec2f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -178,9 +178,6 @@ LLContextMenu* gDetachPieMenu = NULL;
 LLContextMenu* gDetachScreenPieMenu = NULL;
 LLContextMenu* gDetachBodyPartPieMenus[8];
 
-LLMenuItemCallGL* gAFKMenu = NULL;
-LLMenuItemCallGL* gDoNotDisturbMenu = NULL;
-
 //
 // Local prototypes
 
@@ -470,8 +467,6 @@ void init_menus()
 	gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost);
 	gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
 	
-	gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE);
-	gDoNotDisturbMenu = gMenuBarView->getChild<LLMenuItemCallGL>("set_do_not_disturb", TRUE);
 	gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
 	gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
 
@@ -7843,6 +7838,22 @@ class LLViewCheckRenderType : public view_listener_t
 	}
 };
 
+class LLViewStatusAway : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		return (gAgent.isInitialized() && gAgent.getAFK());
+	}
+};
+
+class LLViewStatusDoNotDisturb : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		return (gAgent.isInitialized() && gAgent.isDoNotDisturb());
+	}
+};
+
 class LLViewShowHUDAttachments : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -8276,8 +8287,10 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
 	view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
 	view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
+	view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway");
+	view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");
 	view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
-
+	
 	// Me > Movement
 	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
 	
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index e8665a6ef6..139f898b76 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -187,8 +187,6 @@ extern LLContextMenu* gDetachPieMenu;
 extern LLContextMenu* gAttachBodyPartPieMenus[8];
 extern LLContextMenu* gDetachBodyPartPieMenus[8];
 
-extern LLMenuItemCallGL* gAFKMenu;
-extern LLMenuItemCallGL* gDoNotDisturbMenu;
 extern LLMenuItemCallGL* gMutePieMenu;
 extern LLMenuItemCallGL* gMuteObjectPieMenu;
 extern LLMenuItemCallGL* gBuyPassPieMenu;
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index f6a307d9d0..b1e3a2d41f 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -130,19 +130,22 @@
        label="Status"
        name="Status"
        tear_off="true">
-        <menu_item_call
-         label="Away"
-         name="Set Away">
-          <menu_item_call.on_click
+        <menu_item_check
+         label="Away">
+          <menu_item_check.on_check
+           function="View.Status.CheckAway" />
+          <menu_item_check.on_click
            function="World.SetAway" />
-        </menu_item_call>
-        <menu_item_call
-         label="Busy"
-         name="set_do_not_disturb">
-          <menu_item_call.on_click
+        </menu_item_check>
+        <menu_item_check
+         label="Do Not Disturb">
+          <menu_item_check.on_check
+           function="View.Status.CheckDoNotDisturb" />
+          <menu_item_check.on_click
            function="World.SetDoNotDisturb"/>
-        </menu_item_call>
-      </menu>
+        </menu_item_check>
+      
+    </menu>
 
       <menu_item_separator/>
 
@@ -254,8 +257,7 @@
              parameter="speak" />
         </menu_item_check>
         <menu_item_check
-         label="Conversations Log..."
-         name="ConversationsLog">
+         label="Conversation Log...">
             <menu_item_check.on_check
              function="Floater.Visible"
              parameter="conversation" />
@@ -318,6 +320,15 @@
               function="SideTray.PanelPeopleTab"
               parameter="blocked_panel" />
         </menu_item_call>
+      <menu_item_separator/>
+      <menu_item_check
+       label="Do Not Disturb">
+        <menu_item_check.on_check
+         function="View.Status.CheckDoNotDisturb" />
+        <menu_item_check.on_click
+         function="World.SetDoNotDisturb"/>
+      </menu_item_check>
+
     </menu>
     <menu
      create_jump_keys="true"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 04b6326769..f873bfe6c7 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2074,12 +2074,6 @@ For AI Character: Get the closest navigable point to the point provided.
 	</string>
 
 
-  <!-- Avatar busy/away mode -->
-	<string name="AvatarSetNotAway">Not Away</string>
-	<string name="AvatarSetAway">Away</string>
-	<string name="AvatarSetAvailable">Not Busy</string>
-	<string name="AvatarSetDoNotDisturb">Busy</string>
-
 	<!-- Wearable Types -->
 	<string name="shape">Shape</string>
 	<string name="skin">Skin</string>
-- 
cgit v1.2.3


From 69f81d5bb6390ed4b3c766fc64605d6f15d5df31 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 9 Nov 2012 14:58:37 -0800
Subject: CHUI-517: Updating the do not disturb message automatically sent to
 other users when they attempt to contact a person in do not disturb mode.

---
 indra/newview/app_settings/settings_per_account.xml | 2 +-
 indra/newview/llviewermessage.cpp                   | 4 +---
 indra/newview/skins/default/xui/en/strings.xml      | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 8126e20b1b..ca22041671 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -20,7 +20,7 @@
         <key>Type</key>
             <string>String</string>
         <key>Value</key>
-            <string>The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>
+            <string>This resident has turned on &apos;Do Not Disturb&apos; and will see your message later.</string>
         </map>
     <key>ConversationsExpandMessagePaneFirst</key>
     <map>
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 47249fad70..56c9f81259 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2941,9 +2941,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		}
 		else
 		{
-			// TODO: after LLTrans hits release, get "busy response" into translatable file
-			buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.c_str());
-			gIMMgr->addMessage(session_id, from_id, name, buffer);
+			gIMMgr->addMessage(session_id, from_id, name, message);
 		}
 		break;
 		
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f873bfe6c7..79ee83969b 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2520,7 +2520,7 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="PanelContentsNewScript">New Script</string>
 
   <!-- panel preferences general -->
-  <string name="DoNotDisturbModeResponseDefault">The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>
+  <string name="DoNotDisturbModeResponseDefault">This resident has turned on &apos;Do Not Disturb&apos; and will see your message later.</string>
 
 	<!-- Mute -->
 	<string name="MuteByName">(By name)</string>
-- 
cgit v1.2.3


From 873057a21aaa4e21d75998f604119024947ac773 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 9 Nov 2012 15:45:07 -0800
Subject: CHUI-517: Updating notification copy for Do Not Disturb mode.

---
 indra/newview/skins/default/xui/en/notifications.xml | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 1c1642abac..d63c91a0e6 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3693,8 +3693,11 @@ Cannot offer friendship at this time. Please try again in a moment.
    icon="alert.tga"
    name="DoNotDisturbModeSet"
    type="alert">
-Busy mode is set.
-Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash.
+Do Not Disturb is on.  You will not be notified of incoming communications.
+
+- Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
+- Teleportation offers will be declined.
+- Inventory offers will go to your Trash.
     <usetemplate
      ignoretext="I change my status to Do Not Disturb mode"
      name="okignore"
@@ -5170,9 +5173,9 @@ Do you want to replace it with the selected object?
    label="Do Not Disturb Mode Warning"
    name="DoNotDisturbModePay"
    type="alert">
-You are in Busy Mode, which means you will not receive any items offered in exchange for this payment.
+You have turned on Do Not Disturb. You will not receive any items offered in exchange for this payment.
 
-Would you like to leave Busy Mode before completing this transaction?
+Would you like to turn off Do Not Disturb before completing this transaction?
     <tag>confirm</tag>
     <form name="form">
       <ignore name="ignore"
-- 
cgit v1.2.3


From 312cb2ab61a20fe1e011e41e82bfae5f50fd7a84 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 9 Nov 2012 15:53:58 -0800
Subject: Cleaning up white-space in an xml file.

---
 .../default/xui/en/panel_preferences_chat.xml      | 594 ++++++++++-----------
 1 file changed, 294 insertions(+), 300 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 28434a670e..5524d0e4f0 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -1,151 +1,150 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Text Chat"
- layout="topleft"
- left="102"
- name="chat"
- top="1"
- width="517">
+    border="true"
+    follows="left|top|right|bottom"
+    height="408"
+    label="Text Chat"
+    layout="topleft"
+    left="102"
+    name="chat"
+    top="1"
+    width="517">
 
   <panel
-  border="false"
-  follows="left|top"
-  height="90"
-  layout="topleft"
-  top="10"
-  left="13"
-  width="517">
+      border="false"
+      follows="left|top"
+      height="90"
+      layout="topleft"
+      top="10"
+      left="13"
+      width="517">
 
     <check_box
-       control_name="PlayTypingAnim"
-       height="16"
-       initial_value="true"
-       label="Play typing animation when chatting"
-       layout="topleft"
-       top="0"
-       name="play_typing_animation"
-       width="330" />
+        control_name="PlayTypingAnim"
+        height="16"
+        initial_value="true"
+        label="Play typing animation when chatting"
+        layout="topleft"
+        top="0"
+        name="play_typing_animation"
+        width="330" />
     <check_box
-     enabled="false"
-     height="16"
-     label="Email me IMs when I'm offline"
-     layout="topleft"
-     name="send_im_to_email"
-     top_pad="6"
-     width="330" />
+        enabled="false"
+        height="16"
+        label="Email me IMs when I'm offline"
+        layout="topleft"
+        name="send_im_to_email"
+        top_pad="6"
+        width="330" />
     <check_box
-    height="16"
-    label="Keep a conversation log and transcripts"
-    layout="topleft"
-    name="keep_convo_log_and_transcripts"
-    top_pad="6"
-    width="330" />
+        height="16"
+        label="Keep a conversation log and transcripts"
+        layout="topleft"
+        name="keep_convo_log_and_transcripts"
+        top_pad="6"
+        width="330" />
     <check_box
-     control_name="UseChatBubbles"
-     follows="left|top"
-     height="16"
-     label="Bubble Chat"
-     layout="topleft"
-     top_pad="6"
-     name="bubble_text_chat"
-     width="330" />
+        control_name="UseChatBubbles"
+        follows="left|top"
+        height="16"
+        label="Bubble Chat"
+        layout="topleft"
+        top_pad="6"
+        name="bubble_text_chat"
+        width="330" />
     <text
-     follows="left|top"
-     layout="topleft"
-     left="345"
-     height="12"
-     name="font_size"
-     width="120"
-     top="0">
+        follows="left|top"
+        layout="topleft"
+        left="345"
+        height="12"
+        name="font_size"
+        width="120"
+        top="0">
       Font size:
     </text>
     <radio_group
-       height="90"
-       layout="topleft"
-       left="352"
-     control_name="ChatFontSize"
-       name="chat_font_size"
-       top_pad="0"
-       width="50">
+        height="90"
+        layout="topleft"
+        left="352"
+        control_name="ChatFontSize"
+        name="chat_font_size"
+        top_pad="0"
+        width="50">
       <radio_item
-       height="16"
-       label="Small"
-       layout="topleft"
-       name="radio"
-       value="0"
-       top="10"
-       width="125" />
+          height="16"
+          label="Small"
+          layout="topleft"
+          name="radio"
+          value="0"
+          top="10"
+          width="125" />
       <radio_item
-       height="16"
-       label="Medium"
-       layout="topleft"
-       name="radio2"
-       value="1"
-       top_pad="6"
-       width="125" />
+          height="16"
+          label="Medium"
+          layout="topleft"
+          name="radio2"
+          value="1"
+          top_pad="6"
+          width="125" />
       <radio_item
-       height="16"
-       label="Large"
-       layout="topleft"
-       name="radio3"
-       value="2"
-       top_pad="6"
-       width="125" />
+          height="16"
+          label="Large"
+          layout="topleft"
+          name="radio3"
+          value="2"
+          top_pad="6"
+          width="125" />
     </radio_group>    
     
   </panel>  
 
   <panel
-  border="false"
-  follows="left|top"
-  height="193"
-  layout="topleft"
-  left="13"
-  width="517">
+      border="false"
+      follows="left|top"
+      height="193"
+      layout="topleft"
+      left="13"
+      width="517">
 
     <text
-     follows="left|top"
-     layout="topleft"
-     height="12"
-     name="notifications"
-     left="0"
-     width="120">
+        follows="left|top"
+        layout="topleft"
+        height="12"
+        name="notifications"
+        left="0"
+        width="120">
       Notifications:
     </text>
     <text
-     follows="left|top"
-     layout="topleft"
-     height="12"
-     name="friend_ims"
-     width="145"
-     left="0"
-     top_pad="15"
-     >
+        follows="left|top"
+        layout="topleft"
+        height="12"
+        name="friend_ims"
+        width="145"
+        left="0"
+        top_pad="15">
       Friend IMs:
     </text>
     <combo_box
-             control_name="NotificationFriendIMOptions"
-             height="23"
-             layout="topleft"
-             left_pad="5"
-             top_delta="-6"
-             name="FriendIMOptions"
-             width="223">
+        control_name="NotificationFriendIMOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="FriendIMOptions"
+        width="223">
       <combo_box.item
-       label="Pop up the message"
-       name="0"
-       value="0"/>
+          label="Pop up the message"
+          name="0"
+          value="0"/>
       <combo_box.item
-       label="Flash toolbar button"
-       name="1"
-       value="1"/>
+          label="Flash toolbar button"
+          name="1"
+          value="1"/>
       <combo_box.item
-       label="None"
-       name="2"
-       value="2"/>
+          label="None"
+          name="2"
+          value="2"/>
     </combo_box>
     <text
         follows="left|top"
@@ -154,244 +153,239 @@
         name="non_friend_ims"
         width="145"
         left="0"
-     top_pad="15"
-     >
+        top_pad="15">
       Non-friend IMs:
     </text>
     <combo_box
-             control_name="NotificationNonFriendIMOptions"
-             height="23"
-             layout="topleft"
-             left_pad="5"
-             top_delta="-6"
-             name="NonFriendIMOptions"
-             width="223">
+        control_name="NotificationNonFriendIMOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="NonFriendIMOptions"
+        width="223">
       <combo_box.item
-       label="Pop up the message"
-       name="0"
-       value="0"/>
+          label="Pop up the message"
+          name="0"
+          value="0"/>
       <combo_box.item
-       label="Flash toolbar button"
-       name="1"
-       value="1"/>
+          label="Flash toolbar button"
+          name="1"
+          value="1"/>
       <combo_box.item
-       label="None"
-       name="2"
-       value="2"/>
+          label="None"
+          name="2"
+          value="2"/>
     </combo_box>
     <text
-          follows="left|top"
-          layout="topleft"
-          left="0"
-          height="13"
-          name="conference_ims"
-          width="145"
-          top_pad="14"
-     >
+        follows="left|top"
+        layout="topleft"
+        left="0"
+        height="13"
+        name="conference_ims"
+        width="145"
+        top_pad="14">
       Conference IMs:
     </text>
     <combo_box
-             control_name="NotificationConferenceIMOptions"
-             height="23"
-             layout="topleft"
-             left_pad="5"
-             top_delta="-6"
-             name="ConferenceIMOptions"
-             width="223">
+        control_name="NotificationConferenceIMOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="ConferenceIMOptions"
+        width="223">
       <combo_box.item
-       label="Pop up the message"
-       name="0"
-       value="0"/>
+          label="Pop up the message"
+          name="0"
+          value="0"/>
       <combo_box.item
-       label="Flash toolbar button"
-       name="1"
-       value="1"/>
+          label="Flash toolbar button"
+          name="1"
+          value="1"/>
       <combo_box.item
-       label="None"
-       name="2"
-       value="2"/>
+          label="None"
+          name="2"
+          value="2"/>
     </combo_box>
     <text
-          follows="left|top"
-          layout="topleft"
-          left="0"
-          height="13"
-          name="group_chat"
-          width="145"
-          top_pad="14"
-     >
+        follows="left|top"
+        layout="topleft"
+        left="0"
+        height="13"
+        name="group_chat"
+        width="145"
+        top_pad="14">
       Group chat:
     </text>
     <combo_box
-             control_name="NotificationGroupChatOptions"
-             height="23"
-             layout="topleft"
-             left_pad="5"
-             top_delta="-6"
-             name="GroupChatOptions"
-             width="223">
+        control_name="NotificationGroupChatOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="GroupChatOptions"
+        width="223">
       <combo_box.item
-       label="Pop up the message"
-       name="0"
-       value="0"/>
+          label="Pop up the message"
+          name="0"
+          value="0"/>
       <combo_box.item
-       label="Flash toolbar button"
-       name="1"
-       value="1"/>
+          label="Flash toolbar button"
+          name="1"
+          value="1"/>
       <combo_box.item
-       label="None"
-       name="2"
-       value="2"/>
+          label="None"
+          name="2"
+          value="2"/>
     </combo_box>
     <text
-            follows="left|top"
-            layout="topleft"
-            left="0"
-            height="12"
-            name="nearby_chat"
-            width="145"
-            top_pad="14"
-     >
+        follows="left|top"
+        layout="topleft"
+        left="0"
+        height="12"
+        name="nearby_chat"
+        width="145"
+        top_pad="14">
       Nearby chat:
     </text>
     <combo_box
-             control_name="NotificationNearbyChatOptions"
-             height="23"
-             layout="topleft"
-             left_pad="5"
-             top_delta="-6"
-             name="NearbyChatOptions"
-             width="223">
+        control_name="NotificationNearbyChatOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="NearbyChatOptions"
+        width="223">
       <combo_box.item
-       label="Pop up the message"
-       name="0"
-       value="0"/>
+          label="Pop up the message"
+          name="0"
+          value="0"/>
       <combo_box.item
-       label="Flash toolbar button"
-       name="1"
-       value="1"/>
+          label="Flash toolbar button"
+          name="1"
+          value="1"/>
       <combo_box.item
-       label="None"
-       name="2"
-       value="2"/>
+          label="None"
+          name="2"
+          value="2"/>
     </combo_box>
     <text
-            follows="left|top"
-            layout="topleft"
-            left="0"
-            height="12"
-            name="notifications_alert"
-            width="350"
-            top_pad="11"
-            visible="true"
-            text_color="DrYellow"
-     >
+        follows="left|top"
+        layout="topleft"
+        left="0"
+        height="12"
+        name="notifications_alert"
+        width="350"
+        top_pad="11"
+        visible="true"
+        text_color="DrYellow">
       To temporarily stop all notifications, use Me > Status > Busy.
     </text>
 
   </panel>
 
   <panel
-  border="false"
-  follows="left|top"
-  height="1"
-  layout="topleft"
-  left="13"
-  width="517">
-
-    <text
+      border="false"
       follows="left|top"
+      height="1"
       layout="topleft"
-      left="0"
-      name="play_sound"
-      width="100"
-      top_pad="13"
-      visible="true">
+      left="13"
+      width="517">
+
+    <text
+        follows="left|top"
+        layout="topleft"
+        left="0"
+        name="play_sound"
+        width="100"
+        top_pad="13"
+        visible="true">
       Play sound:
     </text>
     <check_box
-         control_name="NewConversation"
-         height="16"
-         initial_value="true"
-         label="New conversation"
-         layout="topleft"
-         left_pad="15"
-         top_pad="-10"
-         name="new_conversation"
-         width="150" />
+        control_name="NewConversation"
+        height="16"
+        initial_value="true"
+        label="New conversation"
+        layout="topleft"
+        left_pad="15"
+        top_pad="-10"
+        name="new_conversation"
+        width="150" />
     <check_box
-         control_name="IncomingVoiceCall"
-         height="16"
-         initial_value="true"
-         label="Incoming voice call"
-         layout="topleft"
-         top_pad="6"
-         name="incoming_voice_call"
-         width="150" />
+        control_name="IncomingVoiceCall"
+        height="16"
+        initial_value="true"
+        label="Incoming voice call"
+        layout="topleft"
+        top_pad="6"
+        name="incoming_voice_call"
+        width="150" />
     <check_box
-         control_name="GroupChatMessages"
-         height="16"
-         initial_value="false"
-         label="Group chat messages"
-         layout="topleft"
-         top_pad="6"
-         name="group_chat_messages"
-         width="150" />
+        control_name="GroupChatMessages"
+        height="16"
+        initial_value="false"
+        label="Group chat messages"
+        layout="topleft"
+        top_pad="6"
+        name="group_chat_messages"
+        width="150" />
     <check_box
-         control_name="TeleportOffer"
-         height="16"
-         initial_value="true"
-         label="Teleport offer"
-         layout="topleft"
-         left_pad="35"
-         top_pad="-59"
-         name="teleport_offer"
-         width="150" />
+        control_name="TeleportOffer"
+        height="16"
+        initial_value="true"
+        label="Teleport offer"
+        layout="topleft"
+        left_pad="35"
+        top_pad="-59"
+        name="teleport_offer"
+        width="150" />
     <check_box
-         control_name="InventoryOffer"
-         height="16"
-         initial_value="false"
-         label="Inventory offer"
-         layout="topleft"
-         top_pad="6"
-         name="inventory_offer"
-         width="150" />
+        control_name="InventoryOffer"
+        height="16"
+        initial_value="false"
+        label="Inventory offer"
+        layout="topleft"
+        top_pad="6"
+        name="inventory_offer"
+        width="150" />
 
   </panel>
-    
+  
   <button
-   follows="left|top"
-   height="23"
-   label="Translation..."
-   layout="topleft"
-   left="9"
-   name="ok_btn"
-   top="-29"
-   width="170">
-   <button.commit_callback
-    function="Pref.TranslationSettings" />
+      follows="left|top"
+      height="23"
+      label="Translation..."
+      layout="topleft"
+      left="9"
+      name="ok_btn"
+      top="-29"
+      width="170">
+    <button.commit_callback
+        function="Pref.TranslationSettings" />
   </button>
   <button
-   follows="top|left"
-   height="23"
-   layout="topleft"
-   top_pad="-23"
-   left_pad="5"
-   name="autoreplace_showgui"
-   commit_callback.function="Pref.AutoReplace"
-   label="Auto-Replace..."
-   width="150">
+      follows="top|left"
+      height="23"
+      layout="topleft"
+      top_pad="-23"
+      left_pad="5"
+      name="autoreplace_showgui"
+      commit_callback.function="Pref.AutoReplace"
+      label="Auto-Replace..."
+      width="150">
   </button>
   <button
-   follows="top|left"
-   height="23"
-   layout="topleft"
-   top_pad="-23"
-   left_pad="5"
-   name="spellcheck_showgui"
-   commit_callback.function="Pref.SpellChecker"
-   label="Spell Checking..."
-   width="150">
+      follows="top|left"
+      height="23"
+      layout="topleft"
+      top_pad="-23"
+      left_pad="5"
+      name="spellcheck_showgui"
+      commit_callback.function="Pref.SpellChecker"
+      label="Spell Checking..."
+      width="150">
   </button>
 
 </panel>
-- 
cgit v1.2.3


From 908f8735d4d60266504c97c13d65fda74045b731 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 9 Nov 2012 16:09:06 -0800
Subject: CHUI-517: Updating the copy in Preferences for Do Not Disturb mode.

---
 .../newview/skins/default/xui/en/panel_preferences_chat.xml  | 12 ++++++------
 .../skins/default/xui/en/panel_preferences_general.xml       |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 5524d0e4f0..4964df53bb 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -101,7 +101,7 @@
   <panel
       border="false"
       follows="left|top"
-      height="193"
+      height="198"
       layout="topleft"
       left="13"
       width="517">
@@ -274,13 +274,13 @@
         follows="left|top"
         layout="topleft"
         left="0"
-        height="12"
+        height="13"
         name="notifications_alert"
-        width="350"
+        width="500"
         top_pad="11"
         visible="true"
         text_color="DrYellow">
-      To temporarily stop all notifications, use Me > Status > Busy.
+      To temporarily stop all notifications, use Communicate &gt; Do Not Disturb.
     </text>
 
   </panel>
@@ -288,7 +288,7 @@
   <panel
       border="false"
       follows="left|top"
-      height="1"
+      height="67"
       layout="topleft"
       left="13"
       width="517">
@@ -299,7 +299,7 @@
         left="0"
         name="play_sound"
         width="100"
-        top_pad="13"
+        top_pad="8"
         visible="true">
       Play sound:
     </text>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 2cb063e8ee..ea0f7d8593 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -409,7 +409,7 @@
      name="text_box3"
      top_pad="3"
      width="240">
-       Busy mode response:
+       Do Not Disturb response:
     </text>
     <text_editor
      control_name="DoNotDisturbModeResponse"
-- 
cgit v1.2.3


From 1786a7150e754ea10dfd5172ec2491dd67e83a9a Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 9 Nov 2012 16:16:06 -0800
Subject: CHUI-517: Updating the copy for the avatar in-world name bubble
 status for Do Not Disturb mode.

---
 indra/newview/skins/default/xui/en/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 79ee83969b..8310e0c62d 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -295,7 +295,7 @@ Please try logging in again in a minute.</string>
 	<!-- llvoavatar. Displayed in the avatar chat bubble -->
 	<string name="AvatarEditingAppearance">(Editing Appearance)</string>
 	<string name="AvatarAway">Away</string>
-	<string name="AvatarDoNotDisturb">Busy</string>
+	<string name="AvatarDoNotDisturb">Do Not Disturb</string>
 	<string name="AvatarMuted">Blocked</string>
 
 	<!-- animations -->
-- 
cgit v1.2.3


From f429decb0c222b293cee4d3b27c8340262fab572 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 9 Nov 2012 17:00:43 -0800
Subject: CHUI-486: Now the new chat preferences in drop down lists and
 checkboxes are storable. These values are accessible globally using
 gSavedSettings.

---
 indra/llui/llcheckboxctrl.cpp                      |  14 +--
 indra/llui/llcheckboxctrl.h                        |   2 -
 indra/newview/app_settings/settings.xml            | 121 +++++++++++++++++++++
 .../default/xui/en/panel_preferences_chat.xml      |  46 ++++----
 4 files changed, 143 insertions(+), 40 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 4fe444c1a4..5525520d78 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -107,7 +107,7 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
 	LLButton::Params params = p.check_button;
 	params.rect(btn_rect);
 	//params.control_name(p.control_name);
-	params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onButtonPress, this, _2));
+	params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onCommit, this));
 	params.commit_on_return(false);
 	// Checkboxes only allow boolean initial values, but buttons can
 	// take any LLSD.
@@ -123,18 +123,6 @@ LLCheckBoxCtrl::~LLCheckBoxCtrl()
 	// Children all cleaned up by default view destructor.
 }
 
-
-// static
-void LLCheckBoxCtrl::onButtonPress( const LLSD& data )
-{
-	//if (mRadioStyle)
-	//{
-	//	setValue(TRUE);
-	//}
-
-	onCommit();
-}
-
 void LLCheckBoxCtrl::onCommit()
 {
 	if( getEnabled() )
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 67d8091a97..5ce45b2135 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -103,8 +103,6 @@ public:
 	
 	virtual void		setControlName(const std::string& control_name, LLView* context);
 
-	void				onButtonPress(const LLSD& data);
-
 	virtual BOOL		isDirty()	const;		// Returns TRUE if the user has modified this control.
 	virtual void		resetDirty();			// Clear dirty state
 
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 5694cb9f30..bba1f4910a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4667,6 +4667,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>KeepConversationLogTranscripts</key>
+    <map>
+      <key>Comment</key>
+      <string>Keep a conversation log and transcripts</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>LandBrushSize</key>
     <map>
       <key>Comment</key>
@@ -6285,6 +6296,61 @@
       <key>Value</key>
       <integer>305</integer>
     </map>
+    <key>NotificationConferenceIMOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Conference IM Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>0</string>
+    </map>  
+    <key>NotificationFriendIMOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Friend IM Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>0</string>
+    </map>
+    <key>NotificationGroupChatOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Group Chat Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>0</string>
+    </map>
+    <key>NotificationNearbyChatOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Nearby Chat Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>0</string>
+    </map>
+    <key>NotificationNonFriendIMOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Non Friend IM Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>0</string>
+    </map>  
     <key>NotificationToastLifeTime</key>
     <map>
       <key>Comment</key>
@@ -6801,6 +6867,61 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>PlaySoundGroupChatMessages</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when have a group chat message.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>  
+    <key>PlaySoundIncomingVoiceCall</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when have an incoming voice call.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>PlaySoundInventoryOffer</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when have an inventory offer.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>  
+    <key>PlaySoundNewConversation</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when have a new conversation.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>PlaySoundTeleportOffer</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when have a teleport offer.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>PluginAttachDebuggerToPlugins</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 4964df53bb..f1b11e2ca8 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -37,6 +37,7 @@
         top_pad="6"
         width="330" />
     <check_box
+        control_name="KeepConversationLogTranscripts"
         height="16"
         label="Keep a conversation log and transcripts"
         layout="topleft"
@@ -135,15 +136,15 @@
         width="223">
       <combo_box.item
           label="Pop up the message"
-          name="0"
+          name="PopUpMessage"
           value="0"/>
       <combo_box.item
           label="Flash toolbar button"
-          name="1"
+          name="FlashToolbarButton"
           value="1"/>
       <combo_box.item
           label="None"
-          name="2"
+          name="None"
           value="2"/>
     </combo_box>
     <text
@@ -166,15 +167,15 @@
         width="223">
       <combo_box.item
           label="Pop up the message"
-          name="0"
+          name="PopUpMessage"
           value="0"/>
       <combo_box.item
           label="Flash toolbar button"
-          name="1"
+          name="FlashToolbarButton"
           value="1"/>
       <combo_box.item
           label="None"
-          name="2"
+          name="None"
           value="2"/>
     </combo_box>
     <text
@@ -197,15 +198,15 @@
         width="223">
       <combo_box.item
           label="Pop up the message"
-          name="0"
+          name="PopUpMessage"
           value="0"/>
       <combo_box.item
           label="Flash toolbar button"
-          name="1"
+          name="FlashToolbarButton"
           value="1"/>
       <combo_box.item
           label="None"
-          name="2"
+          name="None"
           value="2"/>
     </combo_box>
     <text
@@ -228,15 +229,15 @@
         width="223">
       <combo_box.item
           label="Pop up the message"
-          name="0"
+          name="PopUpMessage"
           value="0"/>
       <combo_box.item
           label="Flash toolbar button"
-          name="1"
+          name="FlashToolbarButton"
           value="1"/>
       <combo_box.item
           label="None"
-          name="2"
+          name="None"
           value="2"/>
     </combo_box>
     <text
@@ -259,15 +260,15 @@
         width="223">
       <combo_box.item
           label="Pop up the message"
-          name="0"
+          name="PopUpMessage"
           value="0"/>
       <combo_box.item
           label="Flash toolbar button"
-          name="1"
+          name="FlashToolBarButton"
           value="1"/>
       <combo_box.item
           label="None"
-          name="2"
+          name="None"
           value="2"/>
     </combo_box>
     <text
@@ -304,9 +305,8 @@
       Play sound:
     </text>
     <check_box
-        control_name="NewConversation"
+        control_name="PlaySoundNewConversation"
         height="16"
-        initial_value="true"
         label="New conversation"
         layout="topleft"
         left_pad="15"
@@ -314,27 +314,24 @@
         name="new_conversation"
         width="150" />
     <check_box
-        control_name="IncomingVoiceCall"
+        control_name="PlaySoundIncomingVoiceCall"
         height="16"
-        initial_value="true"
         label="Incoming voice call"
         layout="topleft"
         top_pad="6"
         name="incoming_voice_call"
         width="150" />
     <check_box
-        control_name="GroupChatMessages"
+        control_name="PlaySoundGroupChatMessages"
         height="16"
-        initial_value="false"
         label="Group chat messages"
         layout="topleft"
         top_pad="6"
         name="group_chat_messages"
         width="150" />
     <check_box
-        control_name="TeleportOffer"
+        control_name="PlaySoundTeleportOffer"
         height="16"
-        initial_value="true"
         label="Teleport offer"
         layout="topleft"
         left_pad="35"
@@ -342,9 +339,8 @@
         name="teleport_offer"
         width="150" />
     <check_box
-        control_name="InventoryOffer"
+        control_name="PlaySoundInventoryOffer"
         height="16"
-        initial_value="false"
         label="Inventory offer"
         layout="topleft"
         top_pad="6"
-- 
cgit v1.2.3


From ff1dab1792f8d8ba6681e59978383304e25dabe2 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 9 Nov 2012 17:19:03 -0800
Subject: CHUI-450 : Fixed how the list of speakers is updated, always add the
 agent avatar in it, takes voice activation into account

---
 indra/newview/llfloaterimcontainer.cpp |  4 ++--
 indra/newview/llspeakers.cpp           | 26 +++++++++++---------------
 2 files changed, 13 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index b20d19d0fd..2789b78c2d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1126,7 +1126,7 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     /* widget processing */
     if (select_widget)
     {
-    	LLFolderViewItem* widget = mConversationsWidgets[session_id];
+		LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
     	if (widget && widget->getParentFolder())
     	{
     		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
@@ -1539,7 +1539,7 @@ void LLFloaterIMContainer::openNearbyChat()
 	//(which it should be...), open it so to make the list of participants visible. This happens to be the most common case when opening the Chat floater.
 	if(mConversationsItems.size() == 1)
 	{
-		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(mConversationsWidgets[LLUUID()]);
+		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,LLUUID()));
 		if (nearby_chat)
 		{
 			nearby_chat->setOpen(TRUE);
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 726199b7aa..5036334bdd 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -503,27 +503,23 @@ void LLSpeakerMgr::update(BOOL resort_ok)
 
 void LLSpeakerMgr::updateSpeakerList()
 {
-	// are we bound to the currently active voice channel?
-	if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel))
-	{
-	        std::set<LLUUID> participants;
-	        LLVoiceClient::getInstance()->getParticipantList(participants);
-		// add new participants to our list of known speakers
-		for (std::set<LLUUID>::iterator participant_it = participants.begin();
-			 participant_it != participants.end(); 
-			 ++participant_it)
+	// Are we bound to the currently active voice channel?
+	if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
+	{
+		std::set<LLUUID> participants;
+		LLVoiceClient::getInstance()->getParticipantList(participants);
+		// If we are, add all voice client participants to our list of known speakers
+		for (std::set<LLUUID>::iterator participant_it = participants.begin(); participant_it != participants.end(); ++participant_it)
 		{
 				setSpeaker(*participant_it, 
 						   LLVoiceClient::getInstance()->getDisplayName(*participant_it),
 						   LLSpeaker::STATUS_VOICE_ACTIVE, 
 						   (LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
-
-
 		}
 	}
 	else 
 	{
-		// Check if the list is empty, except if it's Nearby Chat (session_id NULL).
+		// If not, check if the list is empty, except if it's Nearby Chat (session_id NULL).
 		LLUUID session_id = getSessionID();
 		if ((mSpeakers.size() == 0) && (!session_id.isNull()))
 		{
@@ -533,16 +529,16 @@ void LLSpeakerMgr::updateSpeakerList()
 			LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
 			for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
 			{
-				// Allow to set buddies if they are on line. Allow any other avatar.
+				// Add buddies if they are on line, add any other avatar.
 				if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it))
 				{
 					setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 				}
 			}
-			// Also add the current agent
-			setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 		}
 	}
+	// Finally, always add the current agent (it has to be there no matter what...)
+	setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 }
 
 void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
-- 
cgit v1.2.3


From 99181a9777b7e42ed6e863a074789f37aa6b43f8 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 9 Nov 2012 19:06:00 -0800
Subject: CHUI-479 : WIP : Fixed the missing agent appearance in torn off
 dialogs by adding a consistency check and rebuild.

---
 indra/newview/llfloaterimsessiontab.cpp | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index a47c9177a1..c39319b373 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -263,11 +263,21 @@ void LLFloaterIMSessionTab::draw()
 {
 	if (mRefreshTimer->hasExpired())
 	{
-		if (getParticipantList())
+		LLParticipantList* item = getParticipantList();
+		if (item)
 		{
-			getParticipantList()->update();
+			// Update all model items
+			item->update();
+			// If the model and view list diverge in count, rebuild
+			// Note: this happens sometimes right around init (add participant events fire but get dropped) and is the cause
+			// of missing participants, often, the user agent itself. As there will be no other event fired, there's
+			// no other choice but get those inconsistencies regularly (and lightly) checked and scrubbed.
+			if (item->getChildrenCount() != mConversationsWidgets.size())
+			{
+				buildConversationViewParticipant();
+			}
 		}
-
+		
 		refreshConversation();
 
 		// Restart the refresh timer
@@ -376,7 +386,7 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
 	LLParticipantList* item = getParticipantList();
 	if (!item)
 	{
-		// Nothing to do if the model list is empty
+		// Nothing to do if the model list is inexistent
 		return;
 	}
 
@@ -470,7 +480,8 @@ void LLFloaterIMSessionTab::refreshConversation()
 			session_name = LLIMModel::instance().getName(mSessionID);
 		}
 		updateSessionName(session_name);
-	} 
+	}
+	
 	mConversationViewModel.requestSortAll();
 	mConversationsRoot->arrangeAll();
 	mConversationsRoot->update();
-- 
cgit v1.2.3


From ab5a0a1d4d0a029dd92c9fc108638736a57ce7c6 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 12 Nov 2012 15:06:42 +0200
Subject: CHUI-362 FIXED (Torn off conversation name is highlighted when
 selected in conversation list with different conversation showing in message
 panel): connect new method "returnFloaterToHost" to click on quasi-URL "Bring
 it back"

---
 indra/newview/llfloaterimcontainer.cpp                      | 12 ++++++++++--
 indra/newview/llfloaterimcontainer.h                        |  2 +-
 indra/newview/llfloaterimsessiontab.h                       |  2 +-
 indra/newview/skins/default/xui/en/floater_im_container.xml |  4 ++--
 4 files changed, 14 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 994a76189a..2707e3dcbb 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -133,7 +133,6 @@ void LLFloaterIMContainer::onCurrentChannelChanged(const LLUUID& session_id)
     }
 }
 
-
 BOOL LLFloaterIMContainer::postBuild()
 {
 	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLFloaterIMContainer::onNewMessageReceived, this, _1));
@@ -142,7 +141,8 @@ BOOL LLFloaterIMContainer::postBuild()
 	
 	setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
 	mStubPanel = getChild<LLPanel>("stub_panel");
-    mStubTextBox = getChild<LLTextBox>("stub_textbox");
+    mStubTextBox = getChild<LLTextBox>("stub_textbox_2");
+    mStubTextBox->setURLClickedCallback(boost::bind(&LLFloaterIMContainer::returnFloaterToHost, this));
 
 	mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
 	mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel");
@@ -506,6 +506,14 @@ void LLFloaterIMContainer::showStub(bool stub_is_visible)
 	mStubPanel->setVisible(stub_is_visible);
 }
 
+// listener for click on mStubTextBox2
+void LLFloaterIMContainer::returnFloaterToHost()
+{
+	LLUUID session_id = this->getSelectedSession();
+	LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id);
+	floater->onTearOffClicked();
+}
+
 void LLFloaterIMContainer::setVisible(BOOL visible)
 {	LLFloaterIMNearbyChat* nearby_chat;
 	if (visible)
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index a09cde60f5..e60576a50d 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -65,7 +65,7 @@ public:
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
 								BOOL select_added_floater, 
 								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
-    
+	void returnFloaterToHost();
     void showConversation(const LLUUID& session_id);
     void selectConversation(const LLUUID& session_id);
     BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 94854ee9ee..8f5a8c2c1b 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -91,6 +91,7 @@ public:
 	void buildConversationViewParticipant();
 
 	void setSortOrder(const LLConversationSort& order);
+	virtual void onTearOffClicked();
 	
 	virtual void updateMessages() {}
 
@@ -106,7 +107,6 @@ protected:
 	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
 	static void onSlide(LLFloaterIMSessionTab *self);
-	virtual void onTearOffClicked();
 
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index e3db3d52ed..1388b9e474 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -159,9 +159,9 @@
                    top="40"
                    height="20"
                    valign="center"
-                   parse_urls="false"
+                   parse_urls="true"
                    wrap="true">
-                     Bring it back.
+                     [secondlife:/// Bring it back.]
                 </text>
              </panel>
             </panel_container>
-- 
cgit v1.2.3


From 91781df3701da9852dbe87a4d5c9d5e3abf09987 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 12 Nov 2012 18:18:34 -0800
Subject: CHUI-486: Now toasts only appear when proper 'Chat Preference'
 setting is set to 'Pop Up Message'.

---
 indra/newview/llfloaterimnearbychathandler.cpp |  6 ++++
 indra/newview/llimview.cpp                     | 45 ++++++++++++++++++--------
 2 files changed, 38 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 0dfaa9174b..f382b65b1d 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -283,6 +283,12 @@ bool	LLFloaterIMNearbyChatScreenChannel::createPoolToast()
 
 void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat)
 {
+    //Ignore Nearby Toasts
+    if(gSavedSettings.getString("NotificationNearbyChatOptions") != "0")
+    {
+        return;
+    }
+
 	//look in pool. if there is any message
 	if(mStopProcessing)
 		return;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 6712127750..e4b51b719b 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -139,19 +139,38 @@ void toast_callback(const LLSD& msg){
 		return;
 	}
 
-	// *NOTE Skip toasting if the user disable it in preferences/debug settings ~Alexandrea
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				msg["session_id"]);
-	if (!gSavedSettings.getBOOL("EnableGroupChatPopups")
-			&& session->isGroupSessionType())
-	{
-		return;
-	}
-	if (!gSavedSettings.getBOOL("EnableIMChatPopups")
-			&& !session->isGroupSessionType())
-	{
-		return;
-	}
+    // *NOTE Skip toasting if the user disable it in preferences/debug settings ~Alexandrea
+    LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
+        msg["session_id"]);
+
+
+    //Ignore P2P Friend/Non-Friend toasts
+    if(session->isP2PSessionType())
+    {
+        //Ignores non-friends
+        if(LLAvatarTracker::instance().getBuddyInfo(msg["from_id"]) == NULL &&
+            gSavedSettings.getString("NotificationNonFriendIMOptions") != "0")
+        {
+            return;
+        }
+        //Ignores friends
+        else if(gSavedSettings.getString("NotificationFriendIMOptions") != "0")
+        {
+            return;
+        }
+    }
+    //Ignore Ad Hoc Toasts
+    else if(session->isAdHocSessionType() &&
+        gSavedSettings.getString("NotificationConferenceIMOptions") != "0")
+    {
+        return;
+    }
+    //Ignore Group Toasts
+    else if(session->isGroupSessionType() &&
+        gSavedSettings.getString("NotificationGroupChatOptions") != "0")
+    {
+        return;
+    }
 
 	LLAvatarNameCache::get(msg["from_id"].asUUID(),
 		boost::bind(&on_avatar_name_cache_toast,
-- 
cgit v1.2.3


From 6ba822c0fffcf86c79d25c44625c2667ac23e64a Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 13 Nov 2012 13:32:24 +0200
Subject: CHUI-460 FIXED Reselect floater after toggling the participant list
 open or closed

---
 indra/newview/llconversationview.cpp   |  2 +-
 indra/newview/llfloaterimcontainer.cpp | 12 +++++++++++-
 indra/newview/llfloaterimcontainer.h   |  1 +
 3 files changed, 13 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 295dd2ae6d..53392ac372 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -240,7 +240,7 @@ void LLConversationViewSession::toggleOpen()
 		{
 			getParentFolder()->setSelection(this, true);
 		}
-
+		mContainer->reSelectConversation();
 	}
 }
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2707e3dcbb..962e9f4df6 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -334,7 +334,7 @@ void LLFloaterIMContainer::onExpandCollapseButtonClicked()
 	{
 		collapseConversationsPane(!mConversationsPane->isCollapsed());
 	}
-	selectConversation(mSelectedSession);
+	reSelectConversation();
 }
 
 LLFloaterIMContainer* LLFloaterIMContainer::findInstance()
@@ -1574,4 +1574,14 @@ void LLFloaterIMContainer::onNearbyChatClosed()
 		closeFloater();
 }
 
+void LLFloaterIMContainer::reSelectConversation()
+{
+	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+	if (session_floater->getHost())
+	{
+		selectFloater(session_floater);
+	}
+
+}
+
 // EOF
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index e60576a50d..ad1f0039e9 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -163,6 +163,7 @@ public:
 	LLConversationItem* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
 	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
 	void setNearbyDistances();
+	void reSelectConversation();
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
-- 
cgit v1.2.3


From aa2640f13ab61fa55819af26b001978fa2dd9a3f Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 13 Nov 2012 14:04:14 +0200
Subject: CHUI-447 FIXED Set session name as avatar's display name, if session
 is created by getting new message.

---
 indra/newview/llimview.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 6712127750..781b0cb2ea 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2424,14 +2424,21 @@ void LLIMMgr::addMessage(
 
 	//*NOTE session_name is empty in case of incoming P2P sessions
 	std::string fixed_session_name = from;
+	bool name_is_setted = false;
 	if(!session_name.empty() && session_name.size()>1)
 	{
 		fixed_session_name = session_name;
+		name_is_setted = true;
 	}
 
 	bool new_session = !hasSession(new_session_id);
 	if (new_session)
 	{
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
+		{
+			fixed_session_name = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
+		}
 		LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg);
 
 		// When we get a new IM, and if you are a god, display a bit
-- 
cgit v1.2.3


From 5a31b5dceaeb7dd7089c7426371aac39927c5c02 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 13 Nov 2012 11:19:45 -0800
Subject: CHUI-486: Code cleanup, instead of using values such as 0, 1, 2 now
 using strings 'toast', 'flash', 'none'. These values are used whether to show
 a notification or not.

---
 indra/newview/app_settings/settings.xml            | 10 ++++----
 indra/newview/llfloaterimnearbychathandler.cpp     |  2 +-
 indra/newview/llimview.cpp                         |  9 ++++---
 .../default/xui/en/panel_preferences_chat.xml      | 30 +++++++++++-----------
 4 files changed, 26 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 9b8c86ffc8..b703b9cc8e 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6316,7 +6316,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>0</string>
+      <string>toast</string>
     </map>  
     <key>NotificationFriendIMOptions</key>
     <map>
@@ -6327,7 +6327,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>0</string>
+      <string>toast</string>
     </map>
     <key>NotificationGroupChatOptions</key>
     <map>
@@ -6338,7 +6338,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>0</string>
+      <string>toast</string>
     </map>
     <key>NotificationNearbyChatOptions</key>
     <map>
@@ -6349,7 +6349,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>0</string>
+      <string>toast</string>
     </map>
     <key>NotificationNonFriendIMOptions</key>
     <map>
@@ -6360,7 +6360,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>0</string>
+      <string>toast</string>
     </map>  
     <key>NotificationToastLifeTime</key>
     <map>
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index f382b65b1d..ab81b85d04 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -284,7 +284,7 @@ bool	LLFloaterIMNearbyChatScreenChannel::createPoolToast()
 void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat)
 {
     //Ignore Nearby Toasts
-    if(gSavedSettings.getString("NotificationNearbyChatOptions") != "0")
+    if(gSavedSettings.getString("NotificationNearbyChatOptions") != "toast")
     {
         return;
     }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e4b51b719b..d57ffb9a11 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -149,29 +149,30 @@ void toast_callback(const LLSD& msg){
     {
         //Ignores non-friends
         if(LLAvatarTracker::instance().getBuddyInfo(msg["from_id"]) == NULL &&
-            gSavedSettings.getString("NotificationNonFriendIMOptions") != "0")
+            gSavedSettings.getString("NotificationNonFriendIMOptions") != "toast")
         {
             return;
         }
         //Ignores friends
-        else if(gSavedSettings.getString("NotificationFriendIMOptions") != "0")
+        else if(gSavedSettings.getString("NotificationFriendIMOptions") != "toast")
         {
             return;
         }
     }
     //Ignore Ad Hoc Toasts
     else if(session->isAdHocSessionType() &&
-        gSavedSettings.getString("NotificationConferenceIMOptions") != "0")
+        gSavedSettings.getString("NotificationConferenceIMOptions") != "toast")
     {
         return;
     }
     //Ignore Group Toasts
     else if(session->isGroupSessionType() &&
-        gSavedSettings.getString("NotificationGroupChatOptions") != "0")
+        gSavedSettings.getString("NotificationGroupChatOptions") != "toast")
     {
         return;
     }
 
+    //Show toast
 	LLAvatarNameCache::get(msg["from_id"].asUUID(),
 		boost::bind(&on_avatar_name_cache_toast,
 			_1, _2, msg));
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index f1b11e2ca8..8ab5c9a99c 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -137,15 +137,15 @@
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
-          value="0"/>
+          value="toast"/>
       <combo_box.item
           label="Flash toolbar button"
           name="FlashToolbarButton"
-          value="1"/>
+          value="flash"/>
       <combo_box.item
           label="None"
           name="None"
-          value="2"/>
+          value="none"/>
     </combo_box>
     <text
         follows="left|top"
@@ -168,15 +168,15 @@
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
-          value="0"/>
+          value="toast"/>
       <combo_box.item
           label="Flash toolbar button"
           name="FlashToolbarButton"
-          value="1"/>
+          value="flash"/>
       <combo_box.item
           label="None"
           name="None"
-          value="2"/>
+          value="none"/>
     </combo_box>
     <text
         follows="left|top"
@@ -199,15 +199,15 @@
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
-          value="0"/>
+          value="toast"/>
       <combo_box.item
           label="Flash toolbar button"
           name="FlashToolbarButton"
-          value="1"/>
+          value="flash"/>
       <combo_box.item
           label="None"
           name="None"
-          value="2"/>
+          value="none"/>
     </combo_box>
     <text
         follows="left|top"
@@ -230,15 +230,15 @@
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
-          value="0"/>
+          value="toast"/>
       <combo_box.item
           label="Flash toolbar button"
           name="FlashToolbarButton"
-          value="1"/>
+          value="flash"/>
       <combo_box.item
           label="None"
           name="None"
-          value="2"/>
+          value="none"/>
     </combo_box>
     <text
         follows="left|top"
@@ -261,15 +261,15 @@
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
-          value="0"/>
+          value="toast"/>
       <combo_box.item
           label="Flash toolbar button"
           name="FlashToolBarButton"
-          value="1"/>
+          value="flash"/>
       <combo_box.item
           label="None"
           name="None"
-          value="2"/>
+          value="none"/>
     </combo_box>
     <text
         follows="left|top"
-- 
cgit v1.2.3


From 29e9f792bb9595dbacbc8a4b584b5bf62e7db6c6 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 13 Nov 2012 21:20:05 +0200
Subject: CHUI-512 FIXED (New incoming conversations take focus in message
 panel only and do not show toasts). Rejected update message when floater
 hasn't focus

---
 indra/newview/llfloaterimsession.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 0c622e07c4..e1dc5b91d0 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -142,7 +142,7 @@ void LLFloaterIMSession::newIMCallback(const LLSD& data)
 		LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
 
         // update if visible, otherwise will be updated when opened
-		if (floater && floater->getVisible())
+		if (floater && (floater->getHost()? floater->hasFocus() : floater->getVisible()))
 		{
 			floater->updateMessages();
 		}
-- 
cgit v1.2.3


From df1fd5d4bbe8e71389872e4cdbac3e9f165cc3f8 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 14 Nov 2012 00:07:46 +0200
Subject: CHUI-508 FIXED Attach to and Attach to HUD menus not showing in
 inventory floater to select attachment point

---
 indra/newview/llinventorybridge.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 280a1775e9..52f2897788 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -5453,6 +5453,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 						p.on_enable.parameter = cbparams;
 						LLView* parent = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu;
 						LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
+						items.push_back(p.name);
 					}
 				}
 			}
-- 
cgit v1.2.3


From d75824d520ba1965e48196f8b230ded0f15c5841 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 13 Nov 2012 16:45:56 -0800
Subject: CHUI-486: Post code review changes for last submit, just added in
 some parenthesis for conditional statements, thus making them more clear.

---
 indra/newview/llimview.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3b217ef482..0f4bbd054a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -148,8 +148,8 @@ void toast_callback(const LLSD& msg){
     if(session->isP2PSessionType())
     {
         //Ignores non-friends
-        if(LLAvatarTracker::instance().getBuddyInfo(msg["from_id"]) == NULL &&
-            gSavedSettings.getString("NotificationNonFriendIMOptions") != "toast")
+        if((LLAvatarTracker::instance().getBuddyInfo(msg["from_id"]) == NULL) 
+            && (gSavedSettings.getString("NotificationNonFriendIMOptions") != "toast"))
         {
             return;
         }
@@ -160,14 +160,14 @@ void toast_callback(const LLSD& msg){
         }
     }
     //Ignore Ad Hoc Toasts
-    else if(session->isAdHocSessionType() &&
-        gSavedSettings.getString("NotificationConferenceIMOptions") != "toast")
+    else if(session->isAdHocSessionType() 
+            && (gSavedSettings.getString("NotificationConferenceIMOptions") != "toast"))
     {
         return;
     }
     //Ignore Group Toasts
-    else if(session->isGroupSessionType() &&
-        gSavedSettings.getString("NotificationGroupChatOptions") != "toast")
+    else if(session->isGroupSessionType() 
+            && (gSavedSettings.getString("NotificationGroupChatOptions") != "toast"))
     {
         return;
     }
-- 
cgit v1.2.3


From 40949724345a00a22b1fae5d0645c244cbf47567 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 14 Nov 2012 15:28:05 +0200
Subject: CHUI-389 FIXED Added parameter for sessionAdded to get access to
 has_offline_msg value. Set UnreadIMs icon to visible if messages were sent
 while offline.

---
 indra/newview/llchiclet.h                   |  2 +-
 indra/newview/llchicletbar.cpp              |  2 +-
 indra/newview/llchicletbar.h                |  2 +-
 indra/newview/llconversationlog.cpp         | 33 +++++++++++++++++++++++------
 indra/newview/llconversationlog.h           | 12 ++++++-----
 indra/newview/llconversationloglist.cpp     |  4 ++++
 indra/newview/llconversationloglistitem.cpp |  5 +++++
 indra/newview/llconversationloglistitem.h   |  1 +
 indra/newview/llfloaterimcontainer.cpp      |  2 +-
 indra/newview/llfloaterimcontainer.h        |  2 +-
 indra/newview/llimview.cpp                  |  6 +++---
 indra/newview/llimview.h                    |  4 ++--
 indra/newview/llsyswellwindow.cpp           |  2 +-
 indra/newview/llsyswellwindow.h             |  2 +-
 14 files changed, 55 insertions(+), 24 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 3c8389e20d..d6be2df103 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -873,7 +873,7 @@ class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
 {
 	friend class LLUICtrlFactory;
 public:
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) {}
     /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index ad7890b47a..c66ae1cdd0 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -84,7 +84,7 @@ LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id)
 }
 
 //virtual
-void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
 {
 	if (!getChicletPanel()) return;
 
diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h
index a9a5b61ae7..dc991ca772 100644
--- a/indra/newview/llchicletbar.h
+++ b/indra/newview/llchicletbar.h
@@ -50,7 +50,7 @@ public:
 	LLChicletPanel*	getChicletPanel() { return mChicletPanel; }
 
 	// LLIMSessionObserver observe triggers
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
     /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 3d2b6a5c00..a0765f5e16 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -223,13 +223,17 @@ void LLConversationLog::enableLogging(bool enable)
 	notifyObservers();
 }
 
-void LLConversationLog::logConversation(const LLUUID& session_id)
+void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offline_msg)
 {
 	const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 	LLConversation* conversation = findConversation(session);
 
 	if (session && conversation)
 	{
+		if(has_offline_msg)
+		{
+			updateOfflineIMs(session, has_offline_msg);
+		}
 		updateConversationTimestamp(conversation);
 	}
 	else if (session && !conversation)
@@ -265,7 +269,22 @@ void LLConversationLog::updateConversationName(const LLIMModel::LLIMSession* ses
 	if (conversation)
 	{
 		conversation->setConverstionName(name);
-		notifyPrticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME);
+		notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME);
+	}
+}
+
+void LLConversationLog::updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages)
+{
+	if (!session)
+	{
+		return;
+	}
+
+	LLConversation* conversation = findConversation(session);
+	if (conversation)
+	{
+		conversation->setOfflineMessages(new_messages);
+		notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_OfflineIMs);
 	}
 }
 
@@ -274,7 +293,7 @@ void LLConversationLog::updateConversationTimestamp(LLConversation* conversation
 	if (conversation)
 	{
 		conversation->updateTimestamp();
-		notifyPrticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME);
+		notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME);
 	}
 }
 
@@ -337,9 +356,9 @@ void LLConversationLog::removeObserver(LLConversationLogObserver* observer)
 	mObservers.erase(observer);
 }
 
-void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
 {
-	logConversation(session_id);
+	logConversation(session_id, has_offline_msg);
 }
 
 void LLConversationLog::cache()
@@ -477,7 +496,7 @@ void LLConversationLog::notifyObservers()
 	}
 }
 
-void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask)
+void LLConversationLog::notifyParticularConversationObservers(const LLUUID& session_id, U32 mask)
 {
 	std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
 	for (; iter != mObservers.end(); ++iter)
@@ -489,7 +508,7 @@ void LLConversationLog::notifyPrticularConversationObservers(const LLUUID& sessi
 void LLConversationLog::onNewMessageReceived(const LLSD& data)
 {
 	const LLUUID session_id = data["session_id"].asUUID();
-	logConversation(session_id);
+	logConversation(session_id, false);
 }
 
 void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session)
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 7d0b9113c6..8f6ac3f5d1 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -59,7 +59,7 @@ public:
 	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }
 
 	void setConverstionName(std::string conv_name) { mConversationName = conv_name; }
-
+	void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
 	bool isOlderThan(U32 days) const;
 
 	/*
@@ -123,7 +123,7 @@ public:
 	void removeObserver(LLConversationLogObserver* observer);
 
 	// LLIMSessionObserver triggers
-	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
     virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; // Stub
 	virtual void sessionRemoved(const LLUUID& session_id){}											// Stub
 	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){};								// Stub
@@ -147,9 +147,9 @@ private:
 	/**
 	 * adds conversation to the conversation list and notifies observers
 	 */
-	void logConversation(const LLUUID& session_id);
+	void logConversation(const LLUUID& session_id, BOOL has_offline_msg);
 
-	void notifyPrticularConversationObservers(const LLUUID& session_id, U32 mask);
+	void notifyParticularConversationObservers(const LLUUID& session_id, U32 mask);
 
 	/**
 	 * constructs file name in which conversations log will be saved
@@ -165,6 +165,7 @@ private:
 	void createConversation(const LLIMModel::LLIMSession* session);
 	void updateConversationTimestamp(LLConversation* conversation);
 	void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name);
+	void updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages);
 
 	LLConversation* findConversation(const LLIMModel::LLIMSession* session);
 
@@ -184,7 +185,8 @@ public:
 	enum EConversationChange
 		{
 			CHANGED_TIME = 1, // last interaction time changed
-			CHANGED_NAME = 2  // conversation name changed
+			CHANGED_NAME = 2,  // conversation name changed
+			CHANGED_OfflineIMs = 3
 		};
 
 	virtual ~LLConversationLogObserver(){}
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 429e99f7ad..6dbcb7bef7 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -171,6 +171,10 @@ void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)
 			mIsDirty = true;
 		}
 	}
+	else if (mask & LLConversationLogObserver::CHANGED_OfflineIMs)
+	{
+		item->updateOfflineIMs();
+	}
 }
 
 void LLConversationLogList::addNewItem(const LLConversation* conversation)
diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
index 9fad0e603e..4e984d603b 100644
--- a/indra/newview/llconversationloglistitem.cpp
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -119,6 +119,11 @@ void LLConversationLogListItem::updateName()
 	mConversationName->setValue(mConversation->getConversationName());
 }
 
+void LLConversationLogListItem::updateOfflineIMs()
+{
+	getChild<LLIconCtrl>("unread_ims_icon")->setVisible(mConversation->hasOfflineMessages());
+}
+
 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 57f72db382..ee28456bbb 100644
--- a/indra/newview/llconversationloglistitem.h
+++ b/indra/newview/llconversationloglistitem.h
@@ -69,6 +69,7 @@ public:
 	 */
 	void updateTimestamp();
 	void updateName();
+	void updateOfflineIMs();
 
 private:
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 962e9f4df6..af5db13023 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -96,7 +96,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer()
 	}
 }
 
-void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
 {
 	addConversationListItem(session_id);
 	LLFloaterIMSessionTab::addToHost(session_id);
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index ad1f0039e9..afc8d00174 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -85,7 +85,7 @@ public:
 	static void idle(void* user_data);
 
 	// LLIMSessionObserver observe triggers
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
     /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 0f4bbd054a..0bb370e6fe 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -724,7 +724,7 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co
 	// When notifying observer, name of session is used instead of "name", because they may not be the
 	// same if it is an adhoc session (in this case name is localized in LLIMSession constructor).
 	std::string session_name = LLIMModel::getInstance()->getName(session_id);
-	LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id);
+	LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id,has_offline_msg);
 
 	return true;
 
@@ -2974,11 +2974,11 @@ void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
 	}
 }
 
-void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg)
 {
 	for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
 	{
-		(*it)->sessionAdded(session_id, name, other_participant_id);
+		(*it)->sessionAdded(session_id, name, other_participant_id, has_offline_msg);
 	}
 }
 
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 054388bc6c..19b738069c 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -295,7 +295,7 @@ class LLIMSessionObserver
 {
 public:
 	virtual ~LLIMSessionObserver() {}
-	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) = 0;
     virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
 	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) = 0;
 	virtual void sessionRemoved(const LLUUID& session_id) = 0;
@@ -462,7 +462,7 @@ private:
 
 	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
 
-	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg);
     //Triggers when a session has already been added
     void notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
 	void notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id);
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 18e0d9d0d2..1b8bdf3b46 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -617,7 +617,7 @@ BOOL LLIMWellWindow::postBuild()
 
 //virtual
 void LLIMWellWindow::sessionAdded(const LLUUID& session_id,
-								   const std::string& name, const LLUUID& other_participant_id)
+								   const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
 {
 	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
 	if (!session) return;
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 378d5e0aa2..d6480f1fc6 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -170,7 +170,7 @@ public:
 	/*virtual*/ BOOL postBuild();
 
 	// LLIMSessionObserver observe triggers
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
     /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
 	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
 	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
-- 
cgit v1.2.3


From 7a088e9b2c8ffddbf5cd8dad72281a64a32d7c63 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 14 Nov 2012 19:39:50 +0200
Subject: CHUI-501 FIXED Add link to Privacy tab from Comms floater

---
 indra/newview/llfloaterimcontainer.cpp               | 19 +++++++++++--------
 indra/newview/llfloaterpreference.cpp                | 20 ++++++++++++++++++++
 indra/newview/llfloaterpreference.h                  |  4 ++++
 .../skins/default/xui/en/menu_participant_view.xml   |  7 +++++++
 4 files changed, 42 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index af5db13023..ec1068d191 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -717,15 +717,18 @@ void LLFloaterIMContainer::onCustomAction(const LLSD& userdata)
 	}
 	if ("chat_preferences" == command)
 	{
-		LLFloaterPreference* floater_prefs = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
-		if (floater_prefs)
+		LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+		if (floater_prefp)
 		{
-			LLTabContainer* tab_container = floater_prefs->getChild<LLTabContainer>("pref core");
-			LLPanel* chat_panel = tab_container->getPanelByName("chat");
-			if (tab_container && chat_panel)
-			{
-				tab_container->selectTabPanel(chat_panel);
-			}
+			floater_prefp->selectChatPanel();
+		}
+	}
+	if ("privacy_preferences" == command)
+	{
+		LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+		if (floater_prefp)
+		{
+			floater_prefp->selectPrivacyPanel();
 		}
 	}
 }
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 7c5e0776a7..ffd59ba8b6 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1570,6 +1570,26 @@ void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location)
 	cache_location_editor->setToolTip(location);
 }
 
+void LLFloaterPreference::selectPanel(const LLSD& name)
+{
+	LLTabContainer * tab_containerp = getChild<LLTabContainer>("pref core");
+	LLPanel * panel = tab_containerp->getPanelByName(name);
+	if (NULL != panel)
+	{
+		tab_containerp->selectTabPanel(panel);
+	}
+}
+
+void LLFloaterPreference::selectPrivacyPanel()
+{
+	selectPanel("im");
+}
+
+void LLFloaterPreference::selectChatPanel()
+{
+	selectPanel("chat");
+}
+
 //------------------------------Updater---------------------------------------
 
 static bool handleBandwidthChanged(const LLSD& newvalue)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 10a416beb5..4c1c122fb1 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -82,6 +82,8 @@ public:
 	void processProfileProperties(const LLAvatarData* pAvatarData );
 	void storeAvatarProperties( const LLAvatarData* pAvatarData );
 	void saveAvatarProperties( void );
+	void selectPrivacyPanel();
+	void selectChatPanel();
 
 protected:	
 	void		onBtnOK();
@@ -164,6 +166,8 @@ public:
 	
 	void buildPopupLists();
 	static void refreshSkin(void* data);
+	void selectPanel(const LLSD& name);
+
 private:
 	static std::string sSkin;
 	bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index 6fa0707eea..523ce7b35b 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -68,6 +68,13 @@
          function="IMFloaterContainer.Action"
          parameter="chat_preferences" />
       </menu_item_call>
+    <menu_item_call
+         label="Privacy preferences..."
+         name="privacy_preferences">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="privacy_preferences" />
+    </menu_item_call>
     <menu_item_check
          label="Open conversation log"
          name="Conversation"
-- 
cgit v1.2.3


From e15921e42b4ac14504b22b0acbb349aa6d19664b Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 14 Nov 2012 10:37:52 -0800
Subject: CHUI-479 : WIP : Small refactoring to allow participant to be added
 to session whether or not its parent folder is.

---
 indra/newview/llconversationview.cpp    | 21 +++++++++++++--------
 indra/newview/llconversationview.h      |  1 +
 indra/newview/llfloaterimsessiontab.cpp |  1 +
 3 files changed, 15 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 295dd2ae6d..ad334869fb 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -460,21 +460,26 @@ void LLConversationViewParticipant::refresh()
 
 void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
 {
-    //Add the item to the folder (conversation)
+    // Add the item to the folder (conversation)
     LLFolderViewItem::addToFolder(folder);
 	
-    //Now retrieve the folder (conversation) UUID, which is the speaker session
+    // Retrieve the folder (conversation) UUID, which is also the speaker session UUID
     LLConversationItem* vmi = this->getParentFolder() ? dynamic_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
-    if(vmi)
+    if (vmi)
     {
-        //Allows speaking icon image to be loaded based on mUUID
-        mAvatarIcon->setValue(mUUID);
-
-        //Allows the speaker indicator to be activated based on the user and conversation
-        mSpeakingIndicator->setSpeakerId(mUUID, vmi->getUUID()); 
+		addToSession(vmi->getUUID());
     }
 }
 
+void LLConversationViewParticipant::addToSession(const LLUUID& session_id)
+{
+	//Allows speaking icon image to be loaded based on mUUID
+	mAvatarIcon->setValue(mUUID);
+	
+	//Allows the speaker indicator to be activated based on the user and conversation
+	mSpeakingIndicator->setSpeakerId(mUUID, session_id); 
+}
+
 void LLConversationViewParticipant::onInfoBtnClick()
 {
 	LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID));
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index cc6995c207..3610ac67de 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -121,6 +121,7 @@ public:
     bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
     virtual void refresh();
     void addToFolder(LLFolderViewFolder* folder);
+	void addToSession(const LLUUID& session_id);
 
     /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
 
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index c39319b373..e78422145d 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -417,6 +417,7 @@ void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* p
 		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
 		mConversationsWidgets[uuid] = participant_view;
 		participant_view->addToFolder(mConversationsRoot);
+		participant_view->addToSession(mSessionID);
 		participant_view->setVisible(TRUE);
 		refreshConversation();
 	}
-- 
cgit v1.2.3


From 33068c6da8f079c557e4fb520b074f6e5ce40ba4 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 14 Nov 2012 10:40:51 -0800
Subject: CHUI-479 : WIP : Add debug tracing into speaking indicator manager
 and monitors (to be deleted eventually).

---
 indra/newview/llconversationmodel.cpp        | 10 +++++++++
 indra/newview/llconversationmodel.h          |  1 +
 indra/newview/llconversationview.cpp         | 32 ++++++++++++++++++++++++++++
 indra/newview/llconversationview.h           |  8 +++++--
 indra/newview/lloutputmonitorctrl.cpp        | 29 +++++++++++++++++++++++--
 indra/newview/llspeakingindicatormanager.cpp |  7 ++++++
 indra/newview/llspeakingindicatormanager.h   |  2 +-
 7 files changed, 84 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 47a82bfe17..8aa740e5d1 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -440,6 +440,16 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	}
 }
 
+LLConversationItemSession* LLConversationItemParticipant::getParentSession()
+{
+	LLConversationItemSession* parent_session = NULL;
+	if (hasParent())
+	{
+		parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+	}
+	return parent_session;
+}
+
 void LLConversationItemParticipant::dumpDebugData()
 {
 	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 481d46af58..2ee21d0c16 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -195,6 +195,7 @@ public:
 	virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
 
 	void fetchAvatarName();
+	LLConversationItemSession* getParentSession();
 
 	void dumpDebugData();
 
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 295dd2ae6d..11eef3f7dc 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -327,6 +327,7 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
 			mSpeakingIndicator->setSpeakerId(is_active ? gAgentID : LLUUID::null);
 		}
 
+		llinfos << "Merov debug : onCurrentVoiceSessionChanged, switchIndicator is_active = " << is_active << llendl;
 		mSpeakingIndicator->switchIndicator(is_active);
 		mCallIconLayoutPanel->setVisible(is_active);
 	}
@@ -366,6 +367,11 @@ LLConversationViewParticipant::LLConversationViewParticipant( const LLConversati
 {
 }
 
+LLConversationViewParticipant::~LLConversationViewParticipant()
+{
+	mActiveVoiceChannelConnection.disconnect();
+}
+
 void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params)
 {	
     LLAvatarIconCtrl::Params avatar_icon_params(params.avatar_icon());
@@ -392,6 +398,7 @@ BOOL LLConversationViewParticipant::postBuild()
 	mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
 	mInfoBtn->setVisible(false);
 
+	mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewParticipant::onCurrentVoiceSessionChanged, this, _1));
 	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
 
     if (!sStaticInitialized)
@@ -445,6 +452,29 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
     return arranged;
 }
 
+void LLConversationViewParticipant::onCurrentVoiceSessionChanged(const LLUUID& session_id)
+{
+	llinfos << "Merov debug : onCurrentVoiceSessionChanged begin, uuid = " << mUUID << ", session_id = " << session_id << llendl;
+	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
+	//llinfos << "Merov debug : onCurrentVoiceSessionChanged participant_model = " << participant_model << llendl;
+	
+	if (participant_model)
+	{
+		//llinfos << "Merov debug : onCurrentVoiceSessionChanged enter if 1" << llendl;
+		LLConversationItemSession* parent_session = participant_model->getParentSession();
+		//llinfos << "Merov debug : onCurrentVoiceSessionChanged parent_session = " << parent_session << llendl;
+		if (parent_session)
+		{
+			//llinfos << "Merov debug : onCurrentVoiceSessionChanged enter if 2" << llendl;
+			bool is_active = (parent_session->getUUID() == session_id);
+			//llinfos << "Merov debug : onCurrentVoiceSessionChanged, is_active = " << is_active << llendl;
+			mSpeakingIndicator->switchIndicator(is_active);
+			//llinfos << "Merov debug : onCurrentVoiceSessionChanged switchIndicator done" << llendl;
+		}
+	}
+	//llinfos << "Merov debug : onCurrentVoiceSessionChanged end" << llendl;
+}
+
 void LLConversationViewParticipant::refresh()
 {
 	// Refresh the participant view from its model data
@@ -453,6 +483,7 @@ void LLConversationViewParticipant::refresh()
 	
 	// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
 	mSpeakingIndicator->setIsMuted(vmi->isMuted());
+	//mSpeakingIndicator->switchIndicator(true);
 	
 	// Do the regular upstream refresh
 	LLFolderViewItem::refresh();
@@ -471,6 +502,7 @@ void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
         mAvatarIcon->setValue(mUUID);
 
         //Allows the speaker indicator to be activated based on the user and conversation
+//		llinfos << "Merov debug : setSpeakerId of " << mUUID << ", session id = " << vmi->getUUID() << llendl;
         mSpeakingIndicator->setSpeakerId(mUUID, vmi->getUUID()); 
     }
 }
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index cc6995c207..4b2c9b2d76 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -94,7 +94,7 @@ private:
 	bool					mMinimizedMode;
 
 	LLVoiceClientStatusObserver* mVoiceClientObserver;
-
+	
 	boost::signals2::connection mActiveVoiceChannelConnection;
 };
 
@@ -116,7 +116,7 @@ public:
 		Params();
 	};
 	
-    virtual ~LLConversationViewParticipant( void ) { }
+    virtual ~LLConversationViewParticipant( void );
 
     bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
     virtual void refresh();
@@ -140,6 +140,8 @@ protected:
 	void onInfoBtnClick();
 
 private:
+	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
+
     LLAvatarIconCtrl* mAvatarIcon;
 	LLButton * mInfoBtn;
     LLOutputMonitorCtrl* mSpeakingIndicator;
@@ -156,6 +158,8 @@ private:
     static void initChildrenWidths(LLConversationViewParticipant* self);
     void updateChildren();
     LLView* getItemChildView(EAvatarListItemChildIndex child_view_index);
+	
+	boost::signals2::connection mActiveVoiceChannelConnection;
 };
 
 #endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 4a9a50d96a..3569516388 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -278,21 +278,45 @@ BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 
 void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */)
 {
+	static LLUUID test_uuid("c684ce33-89fb-4544-8f7b-dae243c8b214");
+	bool test_on = (speaker_id == test_uuid);
+	if (test_on)
+	{
+		llinfos << "Merov debug : setSpeakerId, this = " << this << ", session_id = " << session_id << llendl;
+	}
 	if (speaker_id.isNull() && mSpeakerId.notNull())
 	{
 		LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
 	}
 
-	if (speaker_id.isNull() || speaker_id == mSpeakerId) return;
+	if (speaker_id.isNull() || speaker_id == mSpeakerId) 
+	{
+		if (test_on)
+		{
+			llinfos << "Merov debug : setSpeakerId, nothing done because mSpeakerId == speaker_id" << llendl;
+		}
+		return;
+	}
 
 	if (mSpeakerId.notNull())
 	{
+		if (test_on)
+		{
+			llinfos << "Merov debug : setSpeakerId, unregisterSpeakingIndicator" << llendl;
+		}
 		// Unregister previous registration to avoid crash. EXT-4782.
-		LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
+		if (getTargetSessionID() == session_id)
+		{
+			LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
+		}
 	}
 
 	mShowParticipantsSpeaking = show_other_participants_speaking;
 	mSpeakerId = speaker_id;
+	if (test_on)
+	{
+		llinfos << "Merov debug : setSpeakerId, registerSpeakingIndicator" << llendl;
+	}
 	LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this, session_id);
 
 	//mute management
@@ -320,6 +344,7 @@ void LLOutputMonitorCtrl::onChange()
 // virtual
 void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
 {
+	llinfos << "Merov debug : switchIndicator, mSpeakerId = " << mSpeakerId << ", switch_on = " << switch_on << llendl;
 	// ensure indicator is visible in case it is not in visible chain
 	// to be called when parent became visible next time to notify parent that visibility is changed.
 	setVisible(TRUE);
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 900379ae1e..316a2739b8 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -155,6 +155,7 @@ void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_i
 	BOOL is_in_same_voice = LLVoiceClient::getInstance()->isParticipant(speaker_id);
 
 	speakers_uuids.insert(speaker_id);
+	llinfos << "Merov debug : registerSpeakingIndicator call switchSpeakerIndicators, switch = " << is_in_same_voice << llendl;	
 	switchSpeakerIndicators(speakers_uuids, is_in_same_voice);
 }
 
@@ -195,6 +196,7 @@ SpeakingIndicatorManager::~SpeakingIndicatorManager()
 
 void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
 {
+	llinfos << "Merov debug : sOnCurrentChannelChanged call switchSpeakerIndicators, FALSE" << llendl;	
 	switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
 	mSwitchedIndicatorsOn.clear();
 }
@@ -208,16 +210,21 @@ void SpeakingIndicatorManager::onParticipantsChanged()
 
 	LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL;
 	// switch all indicators off
+	llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, FALSE" << llendl;	
 	switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
+	llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, end FALSE switch" << llendl;	
 	mSwitchedIndicatorsOn.clear();
 
 	LL_DEBUGS("SpeakingIndicator") << "Switching all ON, count: " << speakers_uuids.size() << LL_ENDL;
 	// then switch current voice participants indicators on
+	llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, TRUE" << llendl;	
 	switchSpeakerIndicators(speakers_uuids, TRUE);
+	llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, end TRUE switch" << llendl;	
 }
 
 void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on)
 {
+	llinfos << "Merov debug : switchSpeakerIndicators, switch_on = " << switch_on << llendl;
 	LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
 	LLUUID session_id;
 	if (voice_channel)
diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h
index b0a147865b..c2cf2a3702 100644
--- a/indra/newview/llspeakingindicatormanager.h
+++ b/indra/newview/llspeakingindicatormanager.h
@@ -37,7 +37,7 @@ public:
 	virtual ~LLSpeakingIndicator(){}
 	virtual void switchIndicator(bool switch_on) = 0;
 
-private:
+//private:
 	friend class SpeakingIndicatorManager;
 	// Accessors for target voice session UUID.
 	// They are intended to be used only from SpeakingIndicatorManager to ensure target session is 
-- 
cgit v1.2.3


From d541d99fce104d28eac378947261297461603462 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 14 Nov 2012 21:44:58 +0200
Subject: CHUI-487, CHUI-488 W.I.P. #1 (Enable flashing FUI button behavior and
 Implement Flashing Conversations panel line item behavior): build new class
 LLFlashTimer based on LLSysWellChiclet::FlashToLitTimer; prepared it for
 general purpose; replaced LLSysWellChiclet::FlashToLitTimer to LLFlashTimer

---
 indra/newview/CMakeLists.txt            |  2 +
 indra/newview/app_settings/settings.xml |  4 +-
 indra/newview/llchiclet.cpp             | 65 ++-------------------------------
 indra/newview/llchiclet.h               |  5 ++-
 4 files changed, 10 insertions(+), 66 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f652c9e50c..574fdc495a 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -178,6 +178,7 @@ set(viewer_SOURCE_FILES
     llfilepicker.cpp
     llfilteredwearablelist.cpp
     llfirstuse.cpp
+    llflashtimer.cpp
     llflexibleobject.cpp
     llfloaterabout.cpp
     llfloaterbvhpreview.cpp
@@ -762,6 +763,7 @@ set(viewer_HEADER_FILES
     llfilepicker.h
     llfilteredwearablelist.h
     llfirstuse.h
+    llflashtimer.h
     llflexibleobject.h
     llfloaterabout.h
     llfloaterbvhpreview.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b703b9cc8e..14117ee47b 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13142,7 +13142,7 @@
       <key>Value</key>
       <real>50.0</real>
     </map>
-    <key>WellIconFlashCount</key>
+    <key>FlashCount</key>
     <map>
       <key>Comment</key>
       <string>Number of flashes of IM Well and Notification Well icons after which flashing buttons stay lit up. Requires restart.</string>
@@ -13153,7 +13153,7 @@
       <key>Value</key>
       <integer>3</integer>
     </map>
-    <key>WellIconFlashPeriod</key>
+    <key>FlashPeriod</key>
     <map>
       <key>Comment</key>
       <string>Period at which IM Well and Notification Well icons flash (seconds). Requires restart.</string>
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 64d8a68a99..d6860640b7 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -67,60 +67,6 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-/**
- * Updates the Well's 'Lit' state to flash it when "new messages" are come.
- *
- * It gets callback which will be called 2*N times with passed period. See EXT-3147
- */
-class LLSysWellChiclet::FlashToLitTimer : public LLEventTimer
-{
-public:
-	typedef boost::function<void()> callback_t;
-
-	/**
-	 * Constructor.
-	 *
-	 * @param count - how many times callback should be called (twice to not change original state)
-	 * @param period - how frequently callback should be called
-	 * @param cb - callback to be called each tick
-	 */
-	FlashToLitTimer(S32 count, F32 period, callback_t cb)
-		: LLEventTimer(period)
-		, mCallback(cb)
-		, mFlashCount(2 * count)
-		, mCurrentFlashCount(0)
-	{
-		mEventTimer.stop();
-	}
-
-	BOOL tick()
-	{
-		mCallback();
-
-		if (++mCurrentFlashCount == mFlashCount) mEventTimer.stop();
-		return FALSE;
-	}
-
-	void flash()
-	{
-		mCurrentFlashCount = 0;
-		mEventTimer.start();
-	}
-
-	void stopFlashing()
-	{
-		mEventTimer.stop();
-	}
-
-private:
-	callback_t		mCallback;
-
-	/**
-	 * How many times Well will blink.
-	 */
-	S32 mFlashCount;
-	S32 mCurrentFlashCount;
-};
 
 LLSysWellChiclet::Params::Params()
 : button("button")
@@ -145,13 +91,8 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
 	mButton = LLUICtrlFactory::create<LLButton>(button_params);
 	addChild(mButton);
 
-	// use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
-	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
-	// in runtime. So, both settings are made as required restart.
-	static S32 flash_to_lit_count = gSavedSettings.getS32("WellIconFlashCount");
-	static F32 flash_period = gSavedSettings.getF32("WellIconFlashPeriod");
 
-	mFlashToLitTimer = new FlashToLitTimer(flash_to_lit_count, flash_period, boost::bind(&LLSysWellChiclet::changeLitState, this));
+	mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1));
 }
 
 LLSysWellChiclet::~LLSysWellChiclet()
@@ -191,7 +132,7 @@ void LLSysWellChiclet::setToggleState(BOOL toggled) {
 	mButton->setToggleState(toggled);
 }
 
-void LLSysWellChiclet::changeLitState()
+void LLSysWellChiclet::changeLitState(bool blink)
 {
 	setNewMessagesState(!mIsNewMessagesState);
 }
@@ -320,7 +261,7 @@ void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
 	// we have to flash to 'Lit' state each time new unread message is coming.
 	if (counter > mCounter && im_not_visible)
 	{
-		mFlashToLitTimer->flash();
+		mFlashToLitTimer->startFlashing();
 	}
 	else if (counter == 0)
 	{
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index d6be2df103..79ffad92ef 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -29,6 +29,7 @@
 
 #include "llavatariconctrl.h"
 #include "llbutton.h"
+#include "llflashtimer.h"
 #include "llpanel.h"
 #include "lltextbox.h"
 #include "lloutputmonitorctrl.h"
@@ -844,7 +845,7 @@ protected:
 	 * There is an assumption that it will be called 2*N times to do not change its start state.
 	 * @see FlashToLitTimer
 	 */
-	void changeLitState();
+	void changeLitState(bool blink);
 
 	/**
 	 * Displays menu.
@@ -860,7 +861,7 @@ protected:
 	S32 mMaxDisplayedCount;
 	bool mIsNewMessagesState;
 
-	FlashToLitTimer* mFlashToLitTimer;
+	LLFlashTimer* mFlashToLitTimer;
 	LLContextMenu* mContextMenu;
 };
 
-- 
cgit v1.2.3


From bd62d1d33717536e71f5fbb5ab4a477a69494c77 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 14 Nov 2012 20:00:01 -0800
Subject: CHUI-479 : WIP : More tracing

---
 indra/newview/llconversationmodel.cpp        | 18 ++++++++++++------
 indra/newview/llconversationmodel.h          |  2 +-
 indra/newview/lloutputmonitorctrl.cpp        |  8 +++++++-
 indra/newview/llspeakingindicatormanager.cpp |  8 ++++----
 4 files changed, 24 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 8aa740e5d1..1c56bd672d 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -349,15 +349,21 @@ const bool LLConversationItemSession::getTime(F64& time) const
 	return has_time;
 }
 
-void LLConversationItemSession::dumpDebugData()
+void LLConversationItemSession::dumpDebugData(bool dump_children)
 {
+	// Session info
 	llinfos << "Merov debug : session " << this << ", uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl;
-	LLConversationItemParticipant* participant = NULL;
-	child_list_t::iterator iter;
-	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+	// Children info
+	if (dump_children)
 	{
-		participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
-		participant->dumpDebugData();
+		for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); iter++)
+		{
+			LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+			if (participant)
+			{
+				participant->dumpDebugData();
+			}
+		}
 	}
 }
 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 2ee21d0c16..dd849210a8 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -168,7 +168,7 @@ public:
     void addVoiceOptions(menuentry_vec_t& items);
 	virtual const bool getTime(F64& time) const;
 
-	void dumpDebugData();
+	void dumpDebugData(bool dump_children = false);
 
 private:
 	bool mIsLoaded;		// true if at least one participant has been added to the session, false otherwise
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 3569516388..063b90e76b 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -48,6 +48,8 @@ LLColor4	LLOutputMonitorCtrl::sColorBound;
 //F32			LLOutputMonitorCtrl::sRectWidthRatio	= 0.f;
 //F32			LLOutputMonitorCtrl::sRectHeightRatio	= 0.f;
 
+static LLUUID test_uuid("c684ce33-89fb-4544-8f7b-dae243c8b214");
+
 LLOutputMonitorCtrl::Params::Params()
 :	draw_border("draw_border"),
 	image_mute("image_mute"),
@@ -278,7 +280,6 @@ BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 
 void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */)
 {
-	static LLUUID test_uuid("c684ce33-89fb-4544-8f7b-dae243c8b214");
 	bool test_on = (speaker_id == test_uuid);
 	if (test_on)
 	{
@@ -345,6 +346,11 @@ void LLOutputMonitorCtrl::onChange()
 void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
 {
 	llinfos << "Merov debug : switchIndicator, mSpeakerId = " << mSpeakerId << ", switch_on = " << switch_on << llendl;
+	bool test_on = (mSpeakerId == test_uuid);
+	if (test_on && !switch_on)
+	{
+		llinfos << "Merov debug : switching agent off!" << llendl;
+	}
 	// ensure indicator is visible in case it is not in visible chain
 	// to be called when parent became visible next time to notify parent that visibility is changed.
 	setVisible(TRUE);
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 316a2739b8..752218c776 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -224,13 +224,13 @@ void SpeakingIndicatorManager::onParticipantsChanged()
 
 void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on)
 {
-	llinfos << "Merov debug : switchSpeakerIndicators, switch_on = " << switch_on << llendl;
 	LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
 	LLUUID session_id;
 	if (voice_channel)
 	{
 		session_id = voice_channel->getSessionID();
 	}
+	llinfos << "Merov debug : switchSpeakerIndicators, switch_on = " << switch_on << ", voice channel = " << session_id << llendl;
 
 	speaker_ids_t::const_iterator it_uuid = speakers_uuids.begin(); 
 	for (; it_uuid != speakers_uuids.end(); ++it_uuid)
@@ -255,17 +255,17 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea
 			}
 			was_switched_on = was_switched_on || switch_current_on;
 
+			llinfos << "Merov debug : indicator for " << *it_uuid << ", switch_current_on = " << switch_current_on << ", session = " << indicator->getTargetSessionID() << llendl;
 			indicator->switchIndicator(switch_current_on);
-
 		}
 
 		if (was_found)
 		{
-			LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL;
+			LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators were found" << LL_ENDL;
 
 			if (switch_on && !was_switched_on)
 			{
-				LL_DEBUGS("SpeakingIndicator") << "but non of them where switched on" << LL_ENDL;
+				LL_DEBUGS("SpeakingIndicator") << "but none of them were switched on" << LL_ENDL;
 			}
 
 			if (was_switched_on)
-- 
cgit v1.2.3


From dbc37f6ca74dba6c6d5194e0397d5cfe6f570c1d Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 15 Nov 2012 10:38:21 +0200
Subject: CHUI-397 (Delay in removing names from participant list in nearby
 chat) CHUI-440 (Nearby chat participant list does not clear after teleport
 when conversation floater is closed/minimized) fixed

---
 indra/llui/llfolderviewitem.h        |  1 +
 indra/newview/llconversationview.cpp | 14 +++++++++++++-
 indra/newview/llspeakers.cpp         |  8 ++++++++
 indra/newview/llspeakers.h           |  3 +++
 4 files changed, 25 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index b157aabdcf..152ca242e1 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -118,6 +118,7 @@ protected:
 
 	// For now assuming all colors are the same in derived classes.
 	static LLUIColor			sFgColor;
+	static LLUIColor			sFgDisabledColor;
 	static LLUIColor			sHighlightBgColor;
 	static LLUIColor			sHighlightFgColor;
 	static LLUIColor			sFocusOutlineColor;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 53392ac372..d1649a93b1 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -409,6 +409,7 @@ BOOL LLConversationViewParticipant::postBuild()
 void LLConversationViewParticipant::draw()
 {
     static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+	static LLUIColor sFgDisabledColor = LLUIColorTable::instance().getColor("MenuItemDisabledColor", DEFAULT_WHITE);
     static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
     static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
     static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
@@ -421,7 +422,18 @@ void LLConversationViewParticipant::draw()
 
     F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad;
     F32 text_left = (F32)getLabelXPos();
-    LLColor4 color = mIsSelected ? sHighlightFgColor : sFgColor;
+	
+	LLColor4 color;
+	LLLocalSpeakerMgr *speakerMgr = LLLocalSpeakerMgr::getInstance();
+
+	if (speakerMgr && speakerMgr->isSpeakerToBeRemoved(mUUID))
+	{
+		color = sFgDisabledColor;
+	}
+	else
+	{
+		color = mIsSelected ? sHighlightFgColor : sFgColor;
+	}
 
     drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
     drawLabel(font, text_left, y, color, right_x);
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 5036334bdd..88f29d7587 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -254,6 +254,10 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_
 	return true;
 }
 
+bool LLSpeakersDelayActionsStorage::isTimerStarted(const LLUUID& speaker_id)
+{
+	return (mActionTimersMap.size() > 0) && (mActionTimersMap.find(speaker_id) != mActionTimersMap.end());
+}
 
 //
 // ModerationResponder
@@ -603,6 +607,10 @@ const LLUUID LLSpeakerMgr::getSessionID()
 	return mVoiceChannel->getSessionID(); 
 }
 
+bool LLSpeakerMgr::isSpeakerToBeRemoved(const LLUUID& speaker_id)
+{
+	return mSpeakerDelayRemover && mSpeakerDelayRemover->isTimerStarted(speaker_id);
+}
 
 void LLSpeakerMgr::setSpeakerTyping(const LLUUID& speaker_id, BOOL typing)
 {
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 8ab08661d3..7d518fe07b 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -193,6 +193,8 @@ public:
 	void unsetActionTimer(const LLUUID& speaker_id);
 
 	void removeAllTimers();
+
+	bool isTimerStarted(const LLUUID& speaker_id);
 private:
 	/**
 	 * Callback of the each instance of LLSpeakerActionTimer.
@@ -237,6 +239,7 @@ public:
 	void getSpeakerList(speaker_list_t* speaker_list, BOOL include_text);
 	LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
 	const LLUUID getSessionID();
+	bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
 
 	/**
 	 * Removes avaline speaker.
-- 
cgit v1.2.3


From 0b910871ab2935bde912314515f8b53ec3ff754e Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 15 Nov 2012 13:12:04 +0200
Subject: CHUI-487, CHUI-488 W.I.P. #2 (Enable flashing FUI button behavior and
 Implement Flashing Conversations panel line item behavior): build new class
 LLFlashTimer based on LLSysWellChiclet::FlashToLitTimer; prepared it for
 general purpose; replaced LLSysWellChiclet::FlashToLitTimer to LLFlashTimer

---
 indra/newview/llflashtimer.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++
 indra/newview/llflashtimer.h   | 62 ++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+)
 create mode 100644 indra/newview/llflashtimer.cpp
 create mode 100644 indra/newview/llflashtimer.h

(limited to 'indra')

diff --git a/indra/newview/llflashtimer.cpp b/indra/newview/llflashtimer.cpp
new file mode 100644
index 0000000000..f44ca9f90c
--- /dev/null
+++ b/indra/newview/llflashtimer.cpp
@@ -0,0 +1,72 @@
+/**
+ * @file llflashtimer.cpp
+ * @brief LLFlashTimer class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llflashtimer.h"
+#include "llviewercontrol.h"
+
+LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
+		: LLEventTimer(period)
+		, mCallback(cb)
+		, mCurrentTickCount(0)
+{
+	mEventTimer.stop();
+
+	// By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
+	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
+	// in runtime. So, both settings are made as required restart.
+	mFlashCount = 2 * ((count>0)? count : gSavedSettings.getS32("FlashCount"));
+	if (mPeriod<=0)
+	{
+		mPeriod = gSavedSettings.getF32("FlashPeriod");
+	}
+}
+
+BOOL LLFlashTimer::tick()
+{
+	bool blink = !(mCurrentTickCount % 2);
+	mCallback(blink);
+
+	if (++mCurrentTickCount >= mFlashCount)
+	{
+		mEventTimer.stop();
+	}
+
+	return FALSE;
+}
+
+void LLFlashTimer::startFlashing()
+{
+	mCurrentTickCount = 0;
+	mEventTimer.start();
+}
+
+void LLFlashTimer::stopFlashing()
+{
+	mEventTimer.stop();
+}
diff --git a/indra/newview/llflashtimer.h b/indra/newview/llflashtimer.h
new file mode 100644
index 0000000000..95e458dff6
--- /dev/null
+++ b/indra/newview/llflashtimer.h
@@ -0,0 +1,62 @@
+/**
+ * @file llflashtimer.h
+ * @brief LLFlashTimer class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLASHTIMER_H
+#define LL_FLASHTIMER_H
+
+#include "lleventtimer.h"
+
+class LLFlashTimer : public LLEventTimer
+{
+public:
+
+	typedef boost::function<void (bool)> callback_t;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param count - how many times callback should be called (twice to not change original state)
+	 * @param period - how frequently callback should be called
+	 * @param cb - callback to be called each tick
+	 */
+	LLFlashTimer(callback_t cb, S32 count = 0, F32 period = 0.0);
+	~LLFlashTimer() {};
+
+	/*virtual*/ BOOL tick();
+
+	void startFlashing();
+	void stopFlashing();
+
+private:
+	callback_t		mCallback;
+	/**
+	 * How many times Well will blink.
+	 */
+	S32 mFlashCount;
+	S32 mCurrentTickCount;
+};
+
+#endif /* LL_FLASHTIMER_H */
-- 
cgit v1.2.3


From 70b9dd6ee6af483bf1c96631bb25fd6a3703b351 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Thu, 15 Nov 2012 10:41:53 -0800
Subject: CHUI-524: FIX Removing a function call that results in a circular
 logic loop and an eventual stack overflow crash.

---
 indra/newview/llfloaterimsessiontab.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 3a1cc2880a..26a97ea422 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -313,7 +313,13 @@ void LLFloaterIMSessionTab::onFocusReceived()
 	if (container)
 	{
 		container->selectConversationPair(mSessionID, true);
+		// XXX stinson 11/15/2012 : calling show stub from this focus handler results in a circular
+		// logic loop of function calls that eventually result in a stack overflow.
+		// See CHUI-524 for documentation
+#define	XXX_STINSON_HACK_CHUI_524 1
+#if !XXX_STINSON_HACK_CHUI_524
 		container->showStub(! getHost());
+#endif
 	}
 }
 
-- 
cgit v1.2.3


From 4ea44918dd040520bdd8eb1e52f2b6ba6cfa6f8b Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Fri, 16 Nov 2012 19:36:46 +0200
Subject: CHUI-525 FIXED Tootlips are added for Info buttons

---
 indra/newview/skins/default/xui/en/panel_avatar_list_item.xml | 1 +
 indra/newview/skins/default/xui/en/panel_group_list_item.xml  | 1 +
 2 files changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index b7c58eb6ab..aa1b929412 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -129,6 +129,7 @@
      left_pad="3"
      right="-53"
      name="info_btn"
+     tool_tip="More info"
      tab_stop="false"
      top_delta="0"
      width="16" />
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
index 12735026fa..cfe3aeb7c9 100644
--- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
@@ -56,6 +56,7 @@
      left_pad="3"
      right="-31"
      name="info_btn"
+     tool_tip="More info"
      tab_stop="false"
      top_delta="-2"
      width="16" />
-- 
cgit v1.2.3


From 16f5a67e6550c2041b69b5c8523ad9884d7110f1 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 15 Nov 2012 23:35:14 +0200
Subject: CHUI-442 FIXED Nearby chat does not open conversations floater when
 clicking first nearby chat toast in a session

---
 indra/newview/llfloaterimsessiontab.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 3a1cc2880a..da77ca0079 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -165,6 +165,11 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
 				floater_container->addFloater(conversp, TRUE, LLTabContainer::END);
+
+				if (!floater_container->getVisible())
+				{
+					LLFloaterReg::toggleInstanceOrBringToFront("im_container");			
+				}
 			}
 			else
 			{
-- 
cgit v1.2.3


From e89616aac812a7c6080d577f8a284f6df56a51ea Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Thu, 15 Nov 2012 15:11:22 -0800
Subject: Backed out changeset: 80bab29003f8   Removing hack fix for CHUI-524.

---
 indra/newview/llfloaterimsessiontab.cpp | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 26a97ea422..3a1cc2880a 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -313,13 +313,7 @@ void LLFloaterIMSessionTab::onFocusReceived()
 	if (container)
 	{
 		container->selectConversationPair(mSessionID, true);
-		// XXX stinson 11/15/2012 : calling show stub from this focus handler results in a circular
-		// logic loop of function calls that eventually result in a stack overflow.
-		// See CHUI-524 for documentation
-#define	XXX_STINSON_HACK_CHUI_524 1
-#if !XXX_STINSON_HACK_CHUI_524
 		container->showStub(! getHost());
-#endif
 	}
 }
 
-- 
cgit v1.2.3


From 37d7f469055d3ba4b81815fa2ac8459022e1e3cf Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 15 Nov 2012 15:32:02 -0800
Subject: CHUI-524: The root reason of crash was in the infinity recursion in
 the chain of calls
 LLFloater::setFocus->LLFloater::setFrontmost->LLFloaterView::bringToFront.
 And problem was not related to CHUI-362.  Reviewed by Stinson.

---
 indra/llui/llfloater.cpp | 10 +++++++++-
 indra/llui/llfloater.h   |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 0e57ba02bf..1b6e4ed0e5 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2234,7 +2234,8 @@ LLFloaterView::LLFloaterView (const Params& p)
 	mFocusCycleMode(FALSE),
 	mMinimizePositionVOffset(0),
 	mSnapOffsetBottom(0),
-	mSnapOffsetRight(0)
+	mSnapOffsetRight(0),
+	mFrontChild(NULL)
 {
 	mSnapView = getHandle();
 }
@@ -2383,6 +2384,13 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
 
 void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 {
+	if (mFrontChild == child)
+	{
+		return;
+	}
+
+	mFrontChild = child;
+
 	// *TODO: make this respect floater's mAutoFocus value, instead of
 	// using parameter
 	if (child->getHost())
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 07b79d5523..ca0710cdc1 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -576,6 +576,7 @@ private:
 	S32				mMinimizePositionVOffset;
 	typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
 	hidden_floaters_t mHiddenFloaters;
+	LLFloater *		mFrontChild;
 };
 
 //
-- 
cgit v1.2.3


From d3474c6eaf5f26986e7988f4ca773f67e034c49d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 15 Nov 2012 15:42:22 -0800
Subject: CHUI-489: Now sounds exist for teleport and inventory offers. The
 sound is specified in notifications.xml. Also changes for CHUI 486, which
 allow the user to set preferences for hearing sounds for a New Conversation,
 Incoming Voice Call, Teleport Offer and Inventory Offer.

---
 indra/llui/llfloater.cpp                                  | 15 ++++++++++++++-
 indra/llui/llnotifications.cpp                            |  5 +++++
 indra/llui/llnotifications.h                              |  1 +
 indra/newview/llimview.cpp                                |  6 +++++-
 indra/newview/lltoastnotifypanel.cpp                      | 15 +++++++++++++++
 indra/newview/skins/default/xui/en/notifications.xml      |  6 ++++--
 .../skins/default/xui/en/panel_preferences_chat.xml       |  1 +
 7 files changed, 45 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 0e57ba02bf..3ab66f3321 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -64,6 +64,8 @@
 // use this to control "jumping" behavior when Ctrl-Tabbing
 const S32 TABBED_FLOATER_OFFSET = 0;
 
+extern LLControlGroup gSavedSettings;
+
 namespace LLInitParam
 {
 	void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues()
@@ -660,7 +662,18 @@ void LLFloater::openFloater(const LLSD& key)
 		&& !getFloaterHost()
 		&& (!getVisible() || isMinimized()))
 	{
-		make_ui_sound("UISndWindowOpen");
+        bool playSound = true;
+
+        //Don't play a sound for incoming voice call based upon chat preference setting
+        if(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE)
+        {
+            playSound = false;
+        }
+
+        if(playSound)
+        {
+            make_ui_sound("UISndWindowOpen");
+        }
 	}
 
 	//RN: for now, we don't allow rehosting from one multifloater to another
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 929b7da081..fe84dbbdaf 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -899,6 +899,11 @@ bool LLNotification::hasFormElements() const
 	return mTemplatep->mForm->getNumElements() != 0;
 }
 
+void LLNotification::playSound()
+{ 
+    LLUI::sAudioCallback(mTemplatep->mSoundEffect);
+}
+
 LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const
 {
 	return mTemplatep->mCombineBehavior;
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index c677dfe298..088931858a 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -524,6 +524,7 @@ public:
 	bool canLogToIM() const;
 	bool canShowToast() const;
 	bool hasFormElements() const;
+    void playSound();
 
 	typedef enum e_combine_behavior
 	{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 0f4bbd054a..f7b182e891 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2494,7 +2494,11 @@ void LLIMMgr::addMessage(
 			return;
 		}
 
-		make_ui_sound("UISndNewIncomingIMSession");
+        //Play sound for new conversations
+        if(gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE)
+        {
+            make_ui_sound("UISndNewIncomingIMSession");
+        }
 	}
 
 	bool skip_message = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") &&
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index ccad49bc30..8672dc479d 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -493,6 +493,21 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
 	}
 	// adjust panel's height to the text size
 	snapToMessageHeight(mTextBox, MAX_LENGTH);
+
+    bool playSound = true;
+
+    if((mNotification->getName() == "UserGiveItem"
+            && gSavedSettings.getBOOL("PlaySoundInventoryOffer") == FALSE)
+        ||  mNotification->getName() == "TeleportOffered"
+            && gSavedSettings.getBOOL("PlaySoundTeleportOffer") == FALSE)
+    {
+        playSound = false;
+    }
+
+    if(playSound)
+    {
+        mNotification->playSound();
+    }
 }
 
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6c2ad869ac..bf2bfaf386 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6460,7 +6460,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    icon="notify.tga"
    name="UserGiveItem"
    log_to_im ="true"
-   type="offer">
+   type="offer"
+   sound="UISndNewIncomingIMSession">
 [NAME_SLURL] has given you this [OBJECTTYPE]:
 [ITEM_SLURL]
     <form name="form">
@@ -6517,7 +6518,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    name="TeleportOffered"
    log_to_im="true"
    log_to_chat="false"
-   type="offer">
+   type="offer"
+   sound="UISndNewIncomingIMSession">
 [NAME_SLURL] has offered to teleport you to their location:
 
 “[MESSAGE]”
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 8ab5c9a99c..712e8bff7f 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -322,6 +322,7 @@
         name="incoming_voice_call"
         width="150" />
     <check_box
+        enabled="false"
         control_name="PlaySoundGroupChatMessages"
         height="16"
         label="Group chat messages"
-- 
cgit v1.2.3


From 89f7335a52ec9955432dbe8bfa5903f605b7362c Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 15 Nov 2012 17:34:34 -0800
Subject: CHUI-489: Found a bug in last commit for this issue. The sound
 notification (for inventory/teleport offer) would be played for the toast
 popup as well as once the conversations floater was opened. And also when a
 button was clicked in the conversation floater to 'accept' or 'deny' the
 offer. Now only playing the sound notification when the initial offer has
 been made.

---
 indra/newview/llnotificationofferhandler.cpp | 17 +++++++++++++++++
 indra/newview/lltoastnotifypanel.cpp         | 15 +--------------
 2 files changed, 18 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 6e641575fa..8b7cac9f4b 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -117,6 +117,23 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
 			if(channel)
 				channel->addToast(p);
+
+            bool playSound = true;
+
+            //Play notification sound for inventory offer and teleport offer based upon chat preference
+            if((notification->getName() == "UserGiveItem"
+                && gSavedSettings.getBOOL("PlaySoundInventoryOffer") == FALSE)
+                ||  notification->getName() == "TeleportOffered"
+                && gSavedSettings.getBOOL("PlaySoundTeleportOffer") == FALSE)
+            {
+                playSound = false;
+            }
+
+            if(playSound)
+            {
+                notification->playSound();
+            }
+
 		}
 
 		if (notification->canLogToIM())
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 8672dc479d..844d7314d9 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -494,20 +494,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
 	// adjust panel's height to the text size
 	snapToMessageHeight(mTextBox, MAX_LENGTH);
 
-    bool playSound = true;
-
-    if((mNotification->getName() == "UserGiveItem"
-            && gSavedSettings.getBOOL("PlaySoundInventoryOffer") == FALSE)
-        ||  mNotification->getName() == "TeleportOffered"
-            && gSavedSettings.getBOOL("PlaySoundTeleportOffer") == FALSE)
-    {
-        playSound = false;
-    }
-
-    if(playSound)
-    {
-        mNotification->playSound();
-    }
+
 }
 
 
-- 
cgit v1.2.3


From ec5d1e48c4071500400b885e5893373bab0e3d99 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 15 Nov 2012 18:07:57 -0800
Subject: CHUI-479 : WIP : Introduce a publicly available
 LLSpeakingIndicatorManager::updateSpeakingIndicators() method so to reset all
 indicators when creating new dialogs.

---
 indra/newview/llconversationview.cpp         | 25 ++++++++++++-------------
 indra/newview/lloutputmonitorctrl.cpp        |  5 -----
 indra/newview/llspeakingindicatormanager.cpp | 28 ++++++++++++++++++----------
 indra/newview/llspeakingindicatormanager.h   |  5 +++++
 4 files changed, 35 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index cc7a76e353..d971c943f0 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -307,7 +307,9 @@ void LLConversationViewSession::refresh()
 		mSessionTitle->setText(vmi->getDisplayName());
 	}
 
-	// Note: for the moment, all that needs to be done is done by LLFolderViewItem::refresh()
+	// Update all speaking indicators
+	llinfos << "Merov debug : LLConversationViewSession::refresh, updateSpeakingIndicators" << llendl;
+	LLSpeakingIndicatorManager::updateSpeakingIndicators();
 	
 	// Do the regular upstream refresh
 	LLFolderViewFolder::refresh();
@@ -327,7 +329,6 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
 			mSpeakingIndicator->setSpeakerId(is_active ? gAgentID : LLUUID::null);
 		}
 
-		llinfos << "Merov debug : onCurrentVoiceSessionChanged, switchIndicator is_active = " << is_active << llendl;
 		mSpeakingIndicator->switchIndicator(is_active);
 		mCallIconLayoutPanel->setVisible(is_active);
 	}
@@ -456,34 +457,32 @@ void LLConversationViewParticipant::onCurrentVoiceSessionChanged(const LLUUID& s
 {
 	llinfos << "Merov debug : onCurrentVoiceSessionChanged begin, uuid = " << mUUID << ", session_id = " << session_id << llendl;
 	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
-	//llinfos << "Merov debug : onCurrentVoiceSessionChanged participant_model = " << participant_model << llendl;
 	
 	if (participant_model)
 	{
-		//llinfos << "Merov debug : onCurrentVoiceSessionChanged enter if 1" << llendl;
 		LLConversationItemSession* parent_session = participant_model->getParentSession();
-		//llinfos << "Merov debug : onCurrentVoiceSessionChanged parent_session = " << parent_session << llendl;
 		if (parent_session)
 		{
-			//llinfos << "Merov debug : onCurrentVoiceSessionChanged enter if 2" << llendl;
 			bool is_active = (parent_session->getUUID() == session_id);
-			//llinfos << "Merov debug : onCurrentVoiceSessionChanged, is_active = " << is_active << llendl;
 			mSpeakingIndicator->switchIndicator(is_active);
-			//llinfos << "Merov debug : onCurrentVoiceSessionChanged switchIndicator done" << llendl;
 		}
 	}
-	//llinfos << "Merov debug : onCurrentVoiceSessionChanged end" << llendl;
 }
 
 void LLConversationViewParticipant::refresh()
 {
 	// Refresh the participant view from its model data
-	LLConversationItemParticipant* vmi = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
-	vmi->resetRefresh();
+	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
+	participant_model->resetRefresh();
 	
 	// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
-	mSpeakingIndicator->setIsMuted(vmi->isMuted());
-	//mSpeakingIndicator->switchIndicator(true);
+	mSpeakingIndicator->setIsMuted(participant_model->isMuted());
+	//LLConversationItemSession* parent_session = participant_model->getParentSession();
+	//if (parent_session)
+	//{
+	//	bool is_active = (parent_session->getUUID() == session_id);
+	//	mSpeakingIndicator->switchIndicator(is_active);
+	//}
 	
 	// Do the regular upstream refresh
 	LLFolderViewItem::refresh();
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 063b90e76b..536f1fbd73 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -346,11 +346,6 @@ void LLOutputMonitorCtrl::onChange()
 void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
 {
 	llinfos << "Merov debug : switchIndicator, mSpeakerId = " << mSpeakerId << ", switch_on = " << switch_on << llendl;
-	bool test_on = (mSpeakerId == test_uuid);
-	if (test_on && !switch_on)
-	{
-		llinfos << "Merov debug : switching agent off!" << llendl;
-	}
 	// ensure indicator is visible in case it is not in visible chain
 	// to be called when parent became visible next time to notify parent that visibility is changed.
 	setVisible(TRUE);
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 752218c776..d9f9ed5966 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -74,6 +74,16 @@ public:
 	 */
 	void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
 
+	/**
+	 * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
+	 *
+	 * Switches off indicators had been switched on and switches on indicators of current participants list.
+	 * There is only a few indicators in lists should be switched off/on.
+	 * So, method does not calculate difference between these list it only switches off already 
+	 * switched on indicators and switches on indicators of voice channel participants
+	 */
+	void onParticipantsChanged();
+	
 private:
 	typedef std::set<LLUUID> speaker_ids_t;
 	typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t;
@@ -93,16 +103,6 @@ private:
 	 */
 	void sOnCurrentChannelChanged(const LLUUID& session_id);
 
-	/**
-	 * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
-	 *
-	 * Switches off indicators had been switched on and switches on indicators of current participants list.
-	 * There is only a few indicators in lists should be switched off/on.
-	 * So, method does not calculate difference between these list it only switches off already 
-	 * switched on indicators and switches on indicators of voice channel participants
-	 */
-	void onParticipantsChanged();
-
 	/**
 	 * Changes state of indicators specified by LLUUIDs
 	 *
@@ -321,5 +321,13 @@ void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speak
 	}
 }
 
+void LLSpeakingIndicatorManager::updateSpeakingIndicators()
+{
+	if(SpeakingIndicatorManager::instanceExists())
+	{
+		SpeakingIndicatorManager::instance().onParticipantsChanged();
+	}
+}
+
 // EOF
 
diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h
index c2cf2a3702..8ee368e258 100644
--- a/indra/newview/llspeakingindicatormanager.h
+++ b/indra/newview/llspeakingindicatormanager.h
@@ -78,6 +78,11 @@ namespace LLSpeakingIndicatorManager
 	 * @param speaking_indicator instance of the speaker indicator to be unregistered.
 	 */
 	void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
+
+	/**
+	 * Switch on/off registered speaking indicator according to the most current voice client status
+	 */
+	 void updateSpeakingIndicators();
 }
 
 #endif // LL_LLSPEAKINGINDICATORMANAGER_H
-- 
cgit v1.2.3


From 568d818ffe214c358f92717ceb86dd20cb4aed26 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Thu, 15 Nov 2012 19:08:08 -0800
Subject: CHUI-518: WIP First pass as implementing auto-reject voice calls in
 do not disturb mode.

---
 indra/newview/llimview.cpp                           | 16 +++++++++++-----
 indra/newview/llviewermessage.cpp                    |  4 +---
 indra/newview/llviewermessage.h                      |  2 ++
 indra/newview/skins/default/xui/en/notifications.xml |  1 +
 indra/newview/skins/default/xui/en/strings.xml       |  3 ++-
 5 files changed, 17 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 0bb370e6fe..50e2b48f30 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -64,6 +64,7 @@
 #include "lltoolbarview.h"
 #include "llviewercontrol.h"
 #include "llviewerparcelmgr.h"
+#include "message.h"
 
 
 const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -2801,12 +2802,17 @@ void LLIMMgr::inviteToSession(
 
 	if (voice_invite)
 	{
-		if	(	// if we are rejecting group calls 
-				(gSavedSettings.getBOOL("VoiceCallsRejectGroup") && notify_box_type == "VoiceInviteGroup") ||
-				// or we're rejecting non-friend voice calls and this isn't a friend	
-				(gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL))
-			)
+		bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup"));
+		bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL));
+		bool isRejectDoNotDisturb = gAgent.isDoNotDisturb();
+		if	(isRejectGroupCall || isRejectNonFriendCall || isRejectDoNotDisturb)
 		{
+			if (isRejectDoNotDisturb && !isRejectGroupCall && !isRejectNonFriendCall)
+			{
+				LLSD args;
+				LLIMMgr::getInstance()->addSystemMessage(session_id, "you_auto_rejected_call", args);
+				send_do_not_disturb_message(gMessageSystem, caller_id, session_id);
+			}
 			// silently decline the call
 			LLIncomingCallDialog::processCallResponse(1, payload);
 			return;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 56c9f81259..e21db146db 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -179,8 +179,6 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
 	FALSE	// TeleportYourAgent
 };
 
-static void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null);
-
 bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -3240,7 +3238,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	}
 }
 
-static void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
+void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
 {
 	if (gAgent.isDoNotDisturb())
 	{
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index b298f0060b..447fdeb9c7 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -152,6 +152,8 @@ void send_group_notice(const LLUUID& group_id,
 					   const std::string& message,
 					   const LLInventoryItem* item);
 
+void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null);
+
 void handle_lure(const LLUUID& invitee);
 void handle_lure(const uuid_vec_t& ids);
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6c2ad869ac..eaa020ff49 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3695,6 +3695,7 @@ Do Not Disturb is on.  You will not be notified of incoming communications.
 
 - Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
 - Teleportation offers will be declined.
+- Voice calls will be rejected.
 - Inventory offers will go to your Trash.
     <usetemplate
      ignoretext="I change my status to Do Not Disturb mode"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 8489e8ca0f..18b914c764 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3384,7 +3384,8 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 	<string name="answered_call">Your call has been answered</string>
 	<string name="you_started_call">You started a voice call</string>
 	<string name="you_joined_call">You joined the voice call</string>
-	<string name="name_started_call">[NAME] started a voice call</string>
+  <string name="you_auto_rejected_call-im">You automatically rejected the voice call while &apos;Do Not Disturb&apos; was on.</string>
+  <string name="name_started_call">[NAME] started a voice call</string>
 
   <string name="ringing-im">
     Joining voice call...
-- 
cgit v1.2.3


From 987350fcb3cf2da03b70ac3fbadb0429f523d07a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 15 Nov 2012 19:24:45 -0800
Subject: CHUI-489: Code review cleanup for both CHUI-489 and CHUI-486. This
 should be last commit for CHUI-489.

---
 indra/llui/llfloater.cpp                     |  7 +------
 indra/llui/llnotifications.cpp               |  7 ++++---
 indra/llui/llnotificationtemplate.h          |  6 ++----
 indra/newview/llnotificationofferhandler.cpp | 16 +++++-----------
 4 files changed, 12 insertions(+), 24 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index a3b5fb993d..ada2bde55e 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -662,13 +662,8 @@ void LLFloater::openFloater(const LLSD& key)
 		&& !getFloaterHost()
 		&& (!getVisible() || isMinimized()))
 	{
-        bool playSound = true;
-
         //Don't play a sound for incoming voice call based upon chat preference setting
-        if(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE)
-        {
-            playSound = false;
-        }
+        bool playSound = !(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE);
 
         if(playSound)
         {
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index fe84dbbdaf..9618c002f5 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -413,12 +413,13 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()),
 	mLogToChat(p.log_to_chat),
 	mLogToIM(p.log_to_im),
-	mShowToast(p.show_toast)
+	mShowToast(p.show_toast),
+    mSoundName("")
 {
 	if (p.sound.isProvided()
 		&& LLUI::sSettingGroups["config"]->controlExists(p.sound))
 	{
-		mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound));
+		mSoundName = p.sound;
 	}
 
 	BOOST_FOREACH(const LLNotificationTemplate::UniquenessContext& context, p.unique.contexts)
@@ -901,7 +902,7 @@ bool LLNotification::hasFormElements() const
 
 void LLNotification::playSound()
 { 
-    LLUI::sAudioCallback(mTemplatep->mSoundEffect);
+    make_ui_sound(mTemplatep->mSoundName.c_str());
 }
 
 LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 9434efe1b9..906b83a400 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -323,10 +323,8 @@ struct LLNotificationTemplate
     LLNotificationFormPtr mForm;
 	// default priority for notifications of this type
 	ENotificationPriority mPriority;
-	// UUID of the audio file to be played when this notification arrives
-	// this is loaded as a name, but looked up to get the UUID upon template load.
-	// If null, it wasn't specified.
-	LLUUID mSoundEffect;
+	// Stores the sound name which can then be used to play the sound using make_ui_sound
+	std::string mSoundName;
 	// List of tags that rules can match against.
 	std::list<std::string> mTags;
 
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 8b7cac9f4b..91003c7d53 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -118,22 +118,16 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 			if(channel)
 				channel->addToast(p);
 
-            bool playSound = true;
-
-            //Play notification sound for inventory offer and teleport offer based upon chat preference
-            if((notification->getName() == "UserGiveItem"
-                && gSavedSettings.getBOOL("PlaySoundInventoryOffer") == FALSE)
-                ||  notification->getName() == "TeleportOffered"
-                && gSavedSettings.getBOOL("PlaySoundTeleportOffer") == FALSE)
-            {
-                playSound = false;
-            }
+            //Will not play a notification sound for inventory and teleport offer based upon chat preference
+            bool playSound = !((notification->getName() == "UserGiveItem"
+                                    && gSavedSettings.getBOOL("PlaySoundInventoryOffer") == FALSE)
+                                ||  notification->getName() == "TeleportOffered"
+                                    && gSavedSettings.getBOOL("PlaySoundTeleportOffer") == FALSE);
 
             if(playSound)
             {
                 notification->playSound();
             }
-
 		}
 
 		if (notification->canLogToIM())
-- 
cgit v1.2.3


From 50b69c3f97c0b58791f7dd67f8b2fbdc9e8ef503 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 16 Nov 2012 12:38:40 +0200
Subject: CHUI-487, CHUI-488 W.I.P. #3 (Enable flashing FUI button behavior and
 Implement Flashing Conversations panel line item behavior): implemented
 conversation's item flashing

---
 indra/llui/llbutton.cpp                |  6 +++++-
 indra/llui/llfolderviewitem.cpp        | 16 ++++++++++++----
 indra/llui/llfolderviewitem.h          |  2 ++
 indra/newview/llflashtimer.cpp         | 14 ++++++++++++--
 indra/newview/llflashtimer.h           |  6 +++++-
 indra/newview/llfloaterimcontainer.cpp | 11 +++++++++++
 indra/newview/llfloaterimcontainer.h   |  1 +
 7 files changed, 48 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 705fe16559..3b9076ee54 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -176,7 +176,11 @@ LLButton::LLButton(const LLButton::Params& p)
 {
 	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
 	static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
-
+if (this->getName() == "chat")
+{
+bool q = false;
+q = !q;
+}
 	if (!p.label_selected.isProvided())
 	{
 		mSelectedLabel = mUnselectedLabel;
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 822534ffcf..90568f344a 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -23,9 +23,11 @@
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */
+
+#include "../newview/llflashtimer.h"
+
 #include "linden_common.h"
 #include "llfolderviewitem.h"
-
 #include "llfolderview.h"
 #include "llfolderviewmodel.h"
 #include "llpanel.h"
@@ -142,6 +144,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
     mArrowSize(p.arrow_size),
     mMaxFolderItemOverlap(p.max_folder_item_overlap)
 {
+	mFlashTimer = new LLFlashTimer();
+
 	sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
 	sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
 	sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
@@ -676,12 +680,16 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
     const S32 focus_bottom = getRect().getHeight() - mItemHeight;
     const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
     const S32 FOCUS_LEFT = 1;
+    bool flashing = mFlashTimer->isFlashing();
+
+    if (flashing? mFlashTimer->isHighlight() : mIsSelected) // always render "current" item (only render other selected items if
+    	             // mShowSingleSelection is FALSE) or flashing item
 
-    if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE
     {
         gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
         LLColor4 bg_color = bgColor;
-        if (!mIsCurSelection)
+        bool selection = flashing? mFlashTimer->isHighlight() : mIsCurSelection;
+        if (!selection)
         {
             // do time-based fade of extra objects
             F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
@@ -701,7 +709,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
             getRect().getWidth() - 2,
             focus_bottom,
             bg_color, hasKeyboardFocus);
-        if (mIsCurSelection)
+        if (selection)
         {
             gl_rect_2d(FOCUS_LEFT, 
                 focus_top, 
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 152ca242e1..c16d65206f 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -29,6 +29,7 @@
 #include "llview.h"
 #include "lluiimage.h"
 
+class LLFlashTimer;
 class LLFolderView;
 class LLFolderViewModelItem;
 class LLFolderViewFolder;
@@ -272,6 +273,7 @@ public:
 
 private:
 	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
+	LLFlashTimer* mFlashTimer;
 
 };
 
diff --git a/indra/newview/llflashtimer.cpp b/indra/newview/llflashtimer.cpp
index f44ca9f90c..2feacfa218 100644
--- a/indra/newview/llflashtimer.cpp
+++ b/indra/newview/llflashtimer.cpp
@@ -29,11 +29,13 @@
 
 #include "llflashtimer.h"
 #include "llviewercontrol.h"
+#include "lleventtimer.h"
 
 LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 		: LLEventTimer(period)
 		, mCallback(cb)
 		, mCurrentTickCount(0)
+        , mIsFlashing(false)
 {
 	mEventTimer.stop();
 
@@ -49,8 +51,11 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 
 BOOL LLFlashTimer::tick()
 {
-	bool blink = !(mCurrentTickCount % 2);
-	mCallback(blink);
+	mIsHighlight = !(mCurrentTickCount % 2);
+	if (mCallback)
+	{
+		mCallback(mIsHighlight);
+	}
 
 	if (++mCurrentTickCount >= mFlashCount)
 	{
@@ -63,10 +68,15 @@ BOOL LLFlashTimer::tick()
 void LLFlashTimer::startFlashing()
 {
 	mCurrentTickCount = 0;
+	mIsFlashing = true;
 	mEventTimer.start();
 }
 
 void LLFlashTimer::stopFlashing()
 {
+	mIsFlashing = false;
+	mIsHighlight = false;
 	mEventTimer.stop();
 }
+
+
diff --git a/indra/newview/llflashtimer.h b/indra/newview/llflashtimer.h
index 95e458dff6..c030edfc52 100644
--- a/indra/newview/llflashtimer.h
+++ b/indra/newview/llflashtimer.h
@@ -42,13 +42,15 @@ public:
 	 * @param period - how frequently callback should be called
 	 * @param cb - callback to be called each tick
 	 */
-	LLFlashTimer(callback_t cb, S32 count = 0, F32 period = 0.0);
+	LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0);
 	~LLFlashTimer() {};
 
 	/*virtual*/ BOOL tick();
 
 	void startFlashing();
 	void stopFlashing();
+	bool isFlashing() {return mIsFlashing;}
+	bool isHighlight() {return mIsHighlight;}
 
 private:
 	callback_t		mCallback;
@@ -57,6 +59,8 @@ private:
 	 */
 	S32 mFlashCount;
 	S32 mCurrentTickCount;
+	bool mIsHighlight;
+	bool mIsFlashing;
 };
 
 #endif /* LL_FLASHTIMER_H */
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index aebfdb5bce..da6f3a484d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1154,6 +1154,7 @@ void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
 	}
 }
 
+
 // Synchronous select the conversation item and the conversation floater
 BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
 {
@@ -1596,4 +1597,14 @@ void LLFloaterIMContainer::reSelectConversation()
 
 }
 
+void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id)
+{
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
+	if (widget)
+	{
+		widget->;
+	}
+
+}
+
 // EOF
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index afc8d00174..443688668b 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -164,6 +164,7 @@ public:
 	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
 	void setNearbyDistances();
 	void reSelectConversation();
+	void flashConversationItemWidget(const LLUUID& session_id);
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
-- 
cgit v1.2.3


From ed3f43aec48097c56d617a8948d2577624762a88 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 16 Nov 2012 11:14:12 -0800
Subject: CHUI-479 : WIP : Tracing of LLIMModel::processSessionInitializedReply
 (to be deleted).

---
 indra/newview/llfloaterimcontainer.cpp  | 25 +++++++++++++++++++++++--
 indra/newview/llfloaterimsessiontab.cpp |  1 +
 2 files changed, 24 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2707e3dcbb..af090338d7 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -98,6 +98,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer()
 
 void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
+	llinfos << "Merov debug : sessionAdded, uuid = " << session_id << ", name = " << name << llendl;
 	addConversationListItem(session_id);
 	LLFloaterIMSessionTab::addToHost(session_id);
 }
@@ -109,14 +110,33 @@ void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std:
 
 void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
+	llinfos << "Merov debug : sessionVoiceOrIMStarted, uuid = " << session_id << llendl;
 	addConversationListItem(session_id);
 	LLFloaterIMSessionTab::addToHost(session_id);
 }
 
 void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
 {
-	// *TODO: We should do this *without* delete and recreate
-	addConversationListItem(new_session_id, removeConversationListItem(old_session_id));
+	llinfos << "Merov debug : sessionIDUpdated, old_session_id = " << old_session_id << ", new_session_id = " << new_session_id << llendl;
+	// Retrieve the session LLFloaterIMSessionTab
+	// just close it: that should erase the mSession, close the tab and remove the list item
+	// *TODO : take the mSessions element (pointing to the tab) out of the list
+	//bool change_focus = removeConversationListItem(old_session_id);
+	// *TODO : detach the old tab from the host
+	// *TODO : delete the tab (that's one thing that's reentrant)
+	LLFloater* floaterp = get_ptr_in_map(mSessions, old_session_id);
+	if (floaterp)
+	{
+		llinfos << "Merov debug : closeFloater, start" << llendl;
+		floaterp->closeFloater();
+		llinfos << "Merov debug : closeFloater, end" << llendl;
+	}
+	bool change_focus = false;
+	llinfos << "Merov debug : addConversationListItem" << llendl;
+	addConversationListItem(new_session_id, change_focus);
+	llinfos << "Merov debug : addToHost" << llendl;
+	LLFloaterIMSessionTab::addToHost(new_session_id);
+	llinfos << "Merov debug : end sessionIDUpdated" << llendl;
 }
 
 void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id)
@@ -1300,6 +1320,7 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 
 bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
 {
+	llinfos << "Merov debug : removeConversationListItem, uuid = " << uuid << llendl;
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 6b13f5f381..6fbc713590 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -721,6 +721,7 @@ void LLFloaterIMSessionTab::onClose(bool app_quitting)
 		LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
 		if (im_box)
 		{
+			llinfos << "Merov debug : LLFloaterIMSessionTab::onClose, mKey = " << mKey << llendl;
             im_box->removeConversationListItem(mKey);
         }
     }
-- 
cgit v1.2.3


From e298c2ded8e25a28127c668cf30a74a25c139041 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 16 Nov 2012 22:36:12 +0200
Subject: CHUI-487, CHUI-488 FIXED (Enable flashing FUI button behavior and
 Implement Flashing Conversations panel line item behavior): implemented FUI
 button flashing; clean up code

---
 indra/llui/CMakeLists.txt               |  2 +
 indra/llui/llbutton.cpp                 | 46 ++++++++----------
 indra/llui/llbutton.h                   |  6 +--
 indra/llui/llflashtimer.cpp             | 80 ++++++++++++++++++++++++++++++++
 indra/llui/llflashtimer.h               | 67 +++++++++++++++++++++++++++
 indra/llui/llfolderviewitem.cpp         | 15 +++---
 indra/llui/llfolderviewitem.h           |  3 +-
 indra/llui/lltabcontainer.cpp           |  4 +-
 indra/newview/CMakeLists.txt            |  2 -
 indra/newview/llflashtimer.cpp          | 82 ---------------------------------
 indra/newview/llflashtimer.h            | 66 --------------------------
 indra/newview/llfloaterimcontainer.cpp  | 14 ++++--
 indra/newview/llfloaterimcontainer.h    |  2 +-
 indra/newview/llfloaterimsessiontab.cpp | 10 ++++
 14 files changed, 206 insertions(+), 193 deletions(-)
 create mode 100644 indra/llui/llflashtimer.cpp
 create mode 100644 indra/llui/llflashtimer.h
 delete mode 100644 indra/newview/llflashtimer.cpp
 delete mode 100644 indra/newview/llflashtimer.h

(limited to 'indra')

diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 80cec6c9f3..ccc7aa8cec 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -47,6 +47,7 @@ set(llui_SOURCE_FILES
     lleditmenuhandler.cpp
     llf32uictrl.cpp
     llfiltereditor.cpp
+    llflashtimer.cpp
     llflatlistview.cpp
     llfloater.cpp
     llfloaterreg.cpp
@@ -153,6 +154,7 @@ set(llui_HEADER_FILES
     lleditmenuhandler.h
     llf32uictrl.h
     llfiltereditor.h 
+    llflashtimer.h
     llflatlistview.h
     llfloater.h
     llfloaterreg.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 3b9076ee54..8a34e221b1 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -170,17 +170,18 @@ LLButton::LLButton(const LLButton::Params& p)
 	mMouseUpSignal(NULL),
 	mHeldDownSignal(NULL),
 	mUseDrawContextAlpha(p.use_draw_context_alpha),
-	mHandleRightMouse(p.handle_right_mouse),
-	mButtonFlashCount(p.button_flash_count),
-	mButtonFlashRate(p.button_flash_rate)
+	mHandleRightMouse(p.handle_right_mouse)
 {
+	// If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
+	// used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
+	// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod");
+	S32 flash_count = p.button_flash_count || 0;
+	F32 flash_rate = p.button_flash_rate || 0.0; //
+	mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
+
 	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
 	static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
-if (this->getName() == "chat")
-{
-bool q = false;
-q = !q;
-}
+
 	if (!p.label_selected.isProvided())
 	{
 		mSelectedLabel = mUnselectedLabel;
@@ -271,6 +272,7 @@ LLButton::~LLButton()
 	delete mMouseDownSignal;
 	delete mMouseUpSignal;
 	delete mHeldDownSignal;
+	delete mFlashingTimer;
 }
 
 // HACK: Committing a button is the same as instantly clicking it.
@@ -595,22 +597,11 @@ void LLButton::draw()
 {
 	static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
 	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
-	bool flash = FALSE;
 
-	if( mFlashing)
-	{
-		if ( sEnableButtonFlashing)
-		{
-			F32 elapsed = mFlashingTimer.getElapsedTimeF32();
-			S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
-			// flash on or off?
-			flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
-		}
-		else
-		{ // otherwise just highlight button in flash color
-			flash = true;
-		}
-	}
+	mFlashing = mFlashingTimer->isFlashing();
+
+	bool flash = mFlashing &&
+	                 (!sEnableButtonFlashing || mFlashingTimer->isHighlight());
 
 	bool pressed_by_keyboard = FALSE;
 	if (hasFocus())
@@ -955,10 +946,13 @@ void LLButton::setToggleState(BOOL b)
 
 void LLButton::setFlashing( BOOL b )	
 { 
-	if ((bool)b != mFlashing)
+	if (b)
+	{
+		mFlashingTimer->startFlashing();
+	}
+	else
 	{
-		mFlashing = b; 
-		mFlashingTimer.reset();
+		mFlashingTimer->stopFlashing();
 	}
 }
 
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index deaa0823c6..92548298f5 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -30,6 +30,7 @@
 #include "lluuid.h"
 #include "llbadgeowner.h"
 #include "llcontrol.h"
+#include "llflashtimer.h"
 #include "lluictrl.h"
 #include "v4color.h"
 #include "llframetimer.h"
@@ -201,6 +202,7 @@ public:
 	void			setHighlight(bool b);
 	void			setFlashing( BOOL b );
 	BOOL			getFlashing() const		{ return mFlashing; }
+    LLFlashTimer*   getFlashTimer() {return mFlashingTimer;}
 
 	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }
 	LLFontGL::HAlign getHAlign() const						{ return mHAlign; }
@@ -285,8 +287,6 @@ protected:
 
 	LLFrameTimer	mMouseDownTimer;
 	bool			mNeedsHighlight;
-	S32				mButtonFlashCount;
-	F32				mButtonFlashRate;
 
 	void			drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size);
 	void			resetMouseDownTimer();
@@ -373,7 +373,7 @@ protected:
 	bool						mForcePressedState;
 	bool						mDisplayPressedState;
 
-	LLFrameTimer				mFlashingTimer;
+	LLFlashTimer*				mFlashingTimer;
 
 	bool						mHandleRightMouse;
 };
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
new file mode 100644
index 0000000000..c572a83ff5
--- /dev/null
+++ b/indra/llui/llflashtimer.cpp
@@ -0,0 +1,80 @@
+/**
+ * @file llflashtimer.cpp
+ * @brief LLFlashTimer class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#include "../newview/llviewerprecompiledheaders.h"
+
+#include "llflashtimer.h"
+#include "../newview/llviewercontrol.h"
+#include "lleventtimer.h"
+
+LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
+		: LLEventTimer(period)
+		, mCallback(cb)
+		, mCurrentTickCount(0)
+        , mIsFlashing(false)
+{
+	mEventTimer.stop();
+
+	// By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
+	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
+	// in runtime. So, both settings are made as required restart.
+	mFlashCount = 2 * ((count>0)? count : gSavedSettings.getS32("FlashCount"));
+	if (mPeriod<=0)
+	{
+		mPeriod = gSavedSettings.getF32("FlashPeriod");
+	}
+}
+
+BOOL LLFlashTimer::tick()
+{
+	mIsHighlight = !(mCurrentTickCount % 2);
+	if (mCallback)
+	{
+		mCallback(mIsHighlight);
+	}
+
+	if (++mCurrentTickCount >= mFlashCount)
+	{
+		mEventTimer.stop();
+	}
+
+	return FALSE;
+}
+
+void LLFlashTimer::startFlashing()
+{
+	mCurrentTickCount = 0;
+	mIsFlashing = true;
+	mEventTimer.start();
+}
+
+void LLFlashTimer::stopFlashing()
+{
+	mIsFlashing = false;
+	mIsHighlight = false;
+	mEventTimer.stop();
+}
+
+
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
new file mode 100644
index 0000000000..2ef6ebcc8a
--- /dev/null
+++ b/indra/llui/llflashtimer.h
@@ -0,0 +1,67 @@
+/**
+ * @file llflashtimer.h
+ * @brief LLFlashTimer class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLASHTIMER_H
+#define LL_FLASHTIMER_H
+
+#include "lleventtimer.h"
+
+class LLFlashTimer : public LLEventTimer
+{
+public:
+
+	typedef boost::function<void (bool)> callback_t;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param count - how many times callback should be called (twice to not change original state)
+	 * @param period - how frequently callback should be called
+	 * @param cb - callback to be called each tick
+	 */
+	LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0);
+	~LLFlashTimer() {};
+
+	/*virtual*/ BOOL tick();
+
+	void startFlashing();
+	void stopFlashing();
+
+	bool isFlashing() {return mIsFlashing;}
+	bool isHighlight() {return mIsHighlight;}
+
+private:
+	callback_t		mCallback;
+	/**
+	 * How many times parent will blink.
+	 */
+	S32 mFlashCount;
+	S32 mCurrentTickCount;
+	bool mIsHighlight;
+	bool mIsFlashing;
+};
+
+#endif /* LL_FLASHTIMER_H */
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 90568f344a..d65f53cd4d 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -23,8 +23,9 @@
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */
+#include "../newview/llviewerprecompiledheaders.h"
 
-#include "../newview/llflashtimer.h"
+#include "llflashtimer.h"
 
 #include "linden_common.h"
 #include "llfolderviewitem.h"
@@ -164,17 +165,19 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	}
 }
 
+// Destroys the object
+LLFolderViewItem::~LLFolderViewItem()
+{
+	delete mFlashTimer;
+	mViewModelItem = NULL;
+}
+
 BOOL LLFolderViewItem::postBuild()
 {
 	refresh();
 	return TRUE;
 }
 
-// Destroys the object
-LLFolderViewItem::~LLFolderViewItem( void )
-{
-	mViewModelItem = NULL;
-}
 
 LLFolderView* LLFolderViewItem::getRoot()
 {
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index c16d65206f..c8d6c37b04 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -26,10 +26,10 @@
 #ifndef LLFOLDERVIEWITEM_H
 #define LLFOLDERVIEWITEM_H
 
+#include "llflashtimer.h"
 #include "llview.h"
 #include "lluiimage.h"
 
-class LLFlashTimer;
 class LLFolderView;
 class LLFolderViewModelItem;
 class LLFolderViewFolder;
@@ -163,6 +163,7 @@ public:
     S32 getIconPad();
     S32 getTextPad();
 
+    LLFlashTimer* getFlashTimer() {return mFlashTimer;}
 	// If 'selection' is 'this' then note that otherwise ignore.
 	// Returns TRUE if this item ends up being selected.
 	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index c24eb2ee90..d1f77830a6 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -506,8 +506,8 @@ void LLTabContainer::draw()
 		}
 	}
 
-	mPrevArrowBtn->setFlashing(FALSE);
-	mNextArrowBtn->setFlashing(FALSE);
+	mPrevArrowBtn->getFlashTimer()->stopFlashing();
+	mNextArrowBtn->getFlashTimer()->stopFlashing();
 }
 
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 574fdc495a..f652c9e50c 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -178,7 +178,6 @@ set(viewer_SOURCE_FILES
     llfilepicker.cpp
     llfilteredwearablelist.cpp
     llfirstuse.cpp
-    llflashtimer.cpp
     llflexibleobject.cpp
     llfloaterabout.cpp
     llfloaterbvhpreview.cpp
@@ -763,7 +762,6 @@ set(viewer_HEADER_FILES
     llfilepicker.h
     llfilteredwearablelist.h
     llfirstuse.h
-    llflashtimer.h
     llflexibleobject.h
     llfloaterabout.h
     llfloaterbvhpreview.h
diff --git a/indra/newview/llflashtimer.cpp b/indra/newview/llflashtimer.cpp
deleted file mode 100644
index 2feacfa218..0000000000
--- a/indra/newview/llflashtimer.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @file llflashtimer.cpp
- * @brief LLFlashTimer class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llflashtimer.h"
-#include "llviewercontrol.h"
-#include "lleventtimer.h"
-
-LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
-		: LLEventTimer(period)
-		, mCallback(cb)
-		, mCurrentTickCount(0)
-        , mIsFlashing(false)
-{
-	mEventTimer.stop();
-
-	// By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
-	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
-	// in runtime. So, both settings are made as required restart.
-	mFlashCount = 2 * ((count>0)? count : gSavedSettings.getS32("FlashCount"));
-	if (mPeriod<=0)
-	{
-		mPeriod = gSavedSettings.getF32("FlashPeriod");
-	}
-}
-
-BOOL LLFlashTimer::tick()
-{
-	mIsHighlight = !(mCurrentTickCount % 2);
-	if (mCallback)
-	{
-		mCallback(mIsHighlight);
-	}
-
-	if (++mCurrentTickCount >= mFlashCount)
-	{
-		mEventTimer.stop();
-	}
-
-	return FALSE;
-}
-
-void LLFlashTimer::startFlashing()
-{
-	mCurrentTickCount = 0;
-	mIsFlashing = true;
-	mEventTimer.start();
-}
-
-void LLFlashTimer::stopFlashing()
-{
-	mIsFlashing = false;
-	mIsHighlight = false;
-	mEventTimer.stop();
-}
-
-
diff --git a/indra/newview/llflashtimer.h b/indra/newview/llflashtimer.h
deleted file mode 100644
index c030edfc52..0000000000
--- a/indra/newview/llflashtimer.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file llflashtimer.h
- * @brief LLFlashTimer class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_FLASHTIMER_H
-#define LL_FLASHTIMER_H
-
-#include "lleventtimer.h"
-
-class LLFlashTimer : public LLEventTimer
-{
-public:
-
-	typedef boost::function<void (bool)> callback_t;
-
-	/**
-	 * Constructor.
-	 *
-	 * @param count - how many times callback should be called (twice to not change original state)
-	 * @param period - how frequently callback should be called
-	 * @param cb - callback to be called each tick
-	 */
-	LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0);
-	~LLFlashTimer() {};
-
-	/*virtual*/ BOOL tick();
-
-	void startFlashing();
-	void stopFlashing();
-	bool isFlashing() {return mIsFlashing;}
-	bool isHighlight() {return mIsHighlight;}
-
-private:
-	callback_t		mCallback;
-	/**
-	 * How many times Well will blink.
-	 */
-	S32 mFlashCount;
-	S32 mCurrentTickCount;
-	bool mIsHighlight;
-	bool mIsFlashing;
-};
-
-#endif /* LL_FLASHTIMER_H */
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index da6f3a484d..90ddeef5bb 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -41,6 +41,7 @@
 #include "llcallbacklist.h"
 #include "llgroupactions.h"
 #include "llgroupiconctrl.h"
+#include "llflashtimer.h"
 #include "llfloateravatarpicker.h"
 #include "llfloaterpreference.h"
 #include "llimview.h"
@@ -1594,17 +1595,22 @@ void LLFloaterIMContainer::reSelectConversation()
 	{
 		selectFloater(session_floater);
 	}
-
 }
 
-void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id)
+void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
 {
 	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
 	if (widget)
 	{
-		widget->;
+		if (is_flashes)
+		{
+			widget->getFlashTimer()->startFlashing();
+		}
+		else
+		{
+			widget->getFlashTimer()->stopFlashing();
+		}
 	}
-
 }
 
 // EOF
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 443688668b..9112b54018 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -164,7 +164,7 @@ public:
 	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
 	void setNearbyDistances();
 	void reSelectConversation();
-	void flashConversationItemWidget(const LLUUID& session_id);
+	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 69b42cdd6d..42e7e6cb55 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -40,6 +40,7 @@
 #include "llfloaterimsession.h"
 #include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
 #include "lllayoutstack.h"
+#include "lltoolbarview.h"
 #include "llfloaterimnearbychat.h"
 
 const F32 REFRESH_INTERVAL = 0.2f;
@@ -328,11 +329,20 @@ std::string LLFloaterIMSessionTab::appendTime()
 
 void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)
 {
+
 	// Update the participant activity time
 	LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
 	if (im_box)
 	{
 		im_box->setTimeNow(mSessionID,chat.mFromID);
+
+		// TODO: Warning! The next two lines of code are included below only temporarily
+		// to demonstrate the correct format call the appropriate functions.
+		// They should be moved to the right places when working on CHUI-486. ~Alex ProductEngine.
+		// ---- start demo ----
+            im_box->flashConversationItemWidget(mSessionID, true); // flashing of the conversation's item
+            gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat"
+        // ---- end demo -----
 	}
 	
 
-- 
cgit v1.2.3


From c6a0f0ae1dec5ef2f7657d8c1ca07d85c1fef55d Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 16 Nov 2012 16:17:11 -0800
Subject: CHUI-518: FIX Removing the LLIMMgr::getInstance() as the containing
 method is already a non-static member method of the same class.

---
 indra/newview/llimview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a38153c315..e2b678626b 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2814,7 +2814,7 @@ void LLIMMgr::inviteToSession(
 			if (isRejectDoNotDisturb && !isRejectGroupCall && !isRejectNonFriendCall)
 			{
 				LLSD args;
-				LLIMMgr::getInstance()->addSystemMessage(session_id, "you_auto_rejected_call", args);
+				addSystemMessage(session_id, "you_auto_rejected_call", args);
 				send_do_not_disturb_message(gMessageSystem, caller_id, session_id);
 			}
 			// silently decline the call
-- 
cgit v1.2.3


From 2d9285cddb4a48fb766b21fac2705c8873e15f93 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 16 Nov 2012 18:53:05 -0800
Subject: CHUI-529: Now the conversations floater will appear when the chat
 preference is set for friend, non-friend, conference, group and nearby chat.

---
 indra/newview/llfloaterimnearbychathandler.cpp     |  50 ++++++----
 indra/newview/llimview.cpp                         | 104 +++++++++++++--------
 .../default/xui/en/panel_preferences_chat.xml      |  20 ++++
 3 files changed, 116 insertions(+), 58 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index ab81b85d04..2d8a6d46fe 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -41,6 +41,7 @@
 #include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
 #include "llviewerwindow.h"//for screen channel position
 #include "llfloaterimnearbychat.h"
+#include "llfloaterimcontainer.h"
 #include "llrootview.h"
 #include "lllayoutstack.h"
 
@@ -283,12 +284,6 @@ bool	LLFloaterIMNearbyChatScreenChannel::createPoolToast()
 
 void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat)
 {
-    //Ignore Nearby Toasts
-    if(gSavedSettings.getString("NotificationNearbyChatOptions") != "toast")
-    {
-        return;
-    }
-
 	//look in pool. if there is any message
 	if(mStopProcessing)
 		return;
@@ -606,19 +601,36 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
 			toast_msg = chat_msg.mText;
 		}
 
-		// Add a nearby chat toast.
-		LLUUID id;
-		id.generate();
-		chat["id"] = id;
-		std::string r_color_name = "White";
-		F32 r_color_alpha = 1.0f; 
-		LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
-		
-		chat["text_color"] = r_color_name;
-		chat["color_alpha"] = r_color_alpha;
-		chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
-		chat["message"] = toast_msg;
-		channel->addChat(chat);	
+
+        //Will show toast when chat preference is set        
+        if(gSavedSettings.getString("NotificationNearbyChatOptions") == "toast")
+        {
+            // Add a nearby chat toast.
+            LLUUID id;
+            id.generate();
+            chat["id"] = id;
+            std::string r_color_name = "White";
+            F32 r_color_alpha = 1.0f; 
+            LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
+
+            chat["text_color"] = r_color_name;
+            chat["color_alpha"] = r_color_alpha;
+            chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
+            chat["message"] = toast_msg;
+            channel->addChat(chat);	
+        }
+        //Will show Conversations floater when chat preference is set
+        else if(gSavedSettings.getString("NotificationNearbyChatOptions") == "openconversations")
+        {
+            LLFloaterIMContainer * floaterIMContainer = LLFloaterIMContainer::getInstance();
+
+            if(floaterIMContainer)
+            {
+                floaterIMContainer->setVisible(TRUE);
+                floaterIMContainer->setFrontmost(TRUE);
+            }
+        }
+
 	}
 }
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 818de4eaf4..106811b7e0 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -112,6 +112,55 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
+//Will return true if the preference is allowed (user configures these preferences via 'Chat Preference' Dialog
+bool ignoreNotification(const LLSD& msg, const char * preferenceString)
+{
+    //Get the session so we can find out the type of session
+    LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
+        msg["session_id"]);
+
+    const LLRelationship * relationship;
+
+    // Skip system messages
+    if (msg["from_id"].asUUID() == LLUUID::null)
+    {
+        return true;
+    }
+
+    //Ignore P2P Friend/Non-Friend Notification
+    if(session->isP2PSessionType())
+    {
+        relationship = LLAvatarTracker::instance().getBuddyInfo(msg["from_id"]);
+
+        //Ignores non-friends
+        if(relationship == NULL
+            && (gSavedSettings.getString("NotificationNonFriendIMOptions") != preferenceString))
+        {
+            return true;
+        }
+        //Ignores friends
+        else if(relationship 
+            && gSavedSettings.getString("NotificationFriendIMOptions") != preferenceString)
+        {
+            return true;
+        }
+    }
+    //Ignore Ad Hoc Notification
+    else if(session->isAdHocSessionType() 
+        && (gSavedSettings.getString("NotificationConferenceIMOptions") != preferenceString))
+    {
+        return true;
+    }
+    //Ignore Group Notification
+    else if(session->isGroupSessionType() 
+        && (gSavedSettings.getString("NotificationGroupChatOptions") != preferenceString))
+    {
+        return true;
+    }
+
+    return false;
+}
+
 void toast_callback(const LLSD& msg){
 	// do not show toast in do not disturb mode or it goes from agent
 	if (gAgent.isDoNotDisturb() || gAgent.getID() == msg["from_id"])
@@ -133,55 +182,32 @@ void toast_callback(const LLSD& msg){
         return;
     }
 
-	// Skip toasting for system messages
-	if (msg["from_id"].asUUID() == LLUUID::null)
-	{
-		return;
-	}
-
-    // *NOTE Skip toasting if the user disable it in preferences/debug settings ~Alexandrea
-    LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-        msg["session_id"]);
-
-
-    //Ignore P2P Friend/Non-Friend toasts
-    if(session->isP2PSessionType())
-    {
-        //Ignores non-friends
-        if((LLAvatarTracker::instance().getBuddyInfo(msg["from_id"]) == NULL) 
-            && (gSavedSettings.getString("NotificationNonFriendIMOptions") != "toast"))
-        {
-            return;
-        }
-        //Ignores friends
-        else if(gSavedSettings.getString("NotificationFriendIMOptions") != "toast")
-        {
-            return;
-        }
-    }
-    //Ignore Ad Hoc Toasts
-    else if(session->isAdHocSessionType() 
-            && (gSavedSettings.getString("NotificationConferenceIMOptions") != "toast"))
+    //Show toast
+    if(ignoreNotification(msg, "toast") == false)
     {
-        return;
+        LLAvatarNameCache::get(msg["from_id"].asUUID(),
+            boost::bind(&on_avatar_name_cache_toast,
+            _1, _2, msg));
     }
-    //Ignore Group Toasts
-    else if(session->isGroupSessionType() 
-            && (gSavedSettings.getString("NotificationGroupChatOptions") != "toast"))
+}
+
+void open_conversations_callback(const LLSD& msg)
+{
+    LLFloaterIMContainer * floaterIMContainer = LLFloaterIMContainer::getInstance();
+
+    if(floaterIMContainer
+        && ignoreNotification(msg, "openconversations") == false)
     {
-        return;
+        floaterIMContainer->setVisible(TRUE);
+        floaterIMContainer->setFrontmost(TRUE);
     }
-
-    //Show toast
-	LLAvatarNameCache::get(msg["from_id"].asUUID(),
-		boost::bind(&on_avatar_name_cache_toast,
-			_1, _2, msg));
 }
 
 LLIMModel::LLIMModel() 
 {
 	addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
 	addNewMsgCallback(boost::bind(&toast_callback, _1));
+    addNewMsgCallback(boost::bind(&open_conversations_callback, _1));
 }
 
 LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 712e8bff7f..0c94b6b223 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -134,6 +134,10 @@
         top_delta="-6"
         name="FriendIMOptions"
         width="223">
+      <combo_box.item
+          label="Open Conversations window"
+          name="OpenConversationsWindow"
+          value="openconversations"/>      
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
@@ -165,6 +169,10 @@
         top_delta="-6"
         name="NonFriendIMOptions"
         width="223">
+      <combo_box.item
+          label="Open Conversations window"
+          name="OpenConversationsWindow"
+          value="openconversations"/>
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
@@ -196,6 +204,10 @@
         top_delta="-6"
         name="ConferenceIMOptions"
         width="223">
+      <combo_box.item
+          label="Open Conversations window"
+          name="OpenConversationsWindow"
+          value="openconversations"/>
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
@@ -227,6 +239,10 @@
         top_delta="-6"
         name="GroupChatOptions"
         width="223">
+      <combo_box.item
+          label="Open Conversations window"
+          name="OpenConversationsWindow"
+          value="openconversations"/>
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
@@ -258,6 +274,10 @@
         top_delta="-6"
         name="NearbyChatOptions"
         width="223">
+      <combo_box.item
+          label="Open Conversations window"
+          name="OpenConversationsWindow"
+          value="openconversations"/>
       <combo_box.item
           label="Pop up the message"
           name="PopUpMessage"
-- 
cgit v1.2.3


From 249b44d01ced4ba5bb8b8b9147d7836a7d492d5b Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 16 Nov 2012 21:01:57 -0800
Subject: CHUI-479 : Fixed : Rebuild the root on the LLFloaterIMSession when
 modifying the session ID

---
 indra/newview/llfloaterimcontainer.cpp  | 42 ++++++++-----------
 indra/newview/llfloaterimsessiontab.cpp | 72 +++++++++++++++++----------------
 indra/newview/llfloaterimsessiontab.h   |  1 +
 3 files changed, 55 insertions(+), 60 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index af090338d7..bd692aa850 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -117,26 +117,20 @@ void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 
 void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
 {
-	llinfos << "Merov debug : sessionIDUpdated, old_session_id = " << old_session_id << ", new_session_id = " << new_session_id << llendl;
-	// Retrieve the session LLFloaterIMSessionTab
-	// just close it: that should erase the mSession, close the tab and remove the list item
-	// *TODO : take the mSessions element (pointing to the tab) out of the list
-	//bool change_focus = removeConversationListItem(old_session_id);
-	// *TODO : detach the old tab from the host
-	// *TODO : delete the tab (that's one thing that's reentrant)
-	LLFloater* floaterp = get_ptr_in_map(mSessions, old_session_id);
-	if (floaterp)
-	{
-		llinfos << "Merov debug : closeFloater, start" << llendl;
-		floaterp->closeFloater();
-		llinfos << "Merov debug : closeFloater, end" << llendl;
-	}
-	bool change_focus = false;
-	llinfos << "Merov debug : addConversationListItem" << llendl;
+	// The general strategy when a session id is modified is to delete all related objects and create them anew.
+	
+	// Note however that the LLFloaterIMSession has its session id updated through a call to sessionInitReplyReceived() 
+	// and do not need to be deleted and recreated (trying this creates loads of problems). We do need however to suppress 
+	// its related mSessions record as it's indexed with the wrong id.
+	// Grabbing the updated LLFloaterIMSession and readding it in mSessions will eventually be done by addConversationListItem().
+	mSessions.erase(old_session_id);
+
+	// Delete the model and participants related to the old session
+	bool change_focus = removeConversationListItem(old_session_id);
+
+	// Create a new conversation with the new id
 	addConversationListItem(new_session_id, change_focus);
-	llinfos << "Merov debug : addToHost" << llendl;
 	LLFloaterIMSessionTab::addToHost(new_session_id);
-	llinfos << "Merov debug : end sessionIDUpdated" << llendl;
 }
 
 void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id)
@@ -483,14 +477,14 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 	else if (type == "update_session")
 	{
 		session_view->refresh();
-		if (conversation_floater)
-		{
-			conversation_floater->refreshConversation();
-		}
 	}
 	
 	mConversationViewModel.requestSortAll();
 	mConversationsRoot->arrangeAll();
+	if (conversation_floater)
+	{
+		conversation_floater->refreshConversation();
+	}
 	
 	return false;
 }
@@ -1253,10 +1247,6 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 		return item_it->second;
 	}
 
-	// Remove the conversation item that might exist already: it'll be recreated anew further down anyway
-	// and nothing wrong will happen removing it if it doesn't exist
-	removeConversationListItem(uuid,false);
-
 	// Create a conversation session model
 	LLConversationItemSession* item = NULL;
 	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 6fbc713590..22131eac49 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -52,6 +52,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
   ,  mCloseBtn(NULL)
   ,  mSessionID(session_id.asUUID())
   , mConversationsRoot(NULL)
+  , mScroller(NULL)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
@@ -68,10 +69,6 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck,   this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable,  this, _2));
-
-	// Zero expiry time is set only once to allow initial update.
-	mRefreshTimer->setTimerExpirySec(0);
-	mRefreshTimer->start();
 }
 
 LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
@@ -195,33 +192,16 @@ BOOL LLFloaterIMSessionTab::postBuild()
 
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
 	
-	// Create a root view folder for all participants
-	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
-    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
-    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
-    p.parent_panel = mParticipantListPanel;
-    p.listener = base_item;
-    p.view_model = &mConversationViewModel;
-    p.root = NULL;
-    p.use_ellipses = true;
-	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
-    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
-	
 	// Add a scroller for the folder (participant) view
 	LLRect scroller_view_rect = mParticipantListPanel->getRect();
 	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
 	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
 	scroller_params.rect(scroller_view_rect);
-	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
-	scroller->setFollowsAll();
-	
-	// Insert that scroller into the panel widgets hierarchy and folder view
-	mParticipantListPanel->addChild(scroller);
-	scroller->addChild(mConversationsRoot);
-	mConversationsRoot->setScrollContainer(scroller);
-	mConversationsRoot->setFollowsAll();
-	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+	mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+	mScroller->setFollowsAll();
 	
+	// Insert that scroller into the panel widgets hierarchy
+	mParticipantListPanel->addChild(mScroller);	
 	
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
@@ -235,8 +215,6 @@ BOOL LLFloaterIMSessionTab::postBuild()
 
 	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 
-	buildConversationViewParticipant();
-
 	mSaveRect = isTornOff();
 	initRectControl();
 
@@ -249,8 +227,14 @@ BOOL LLFloaterIMSessionTab::postBuild()
 		result = LLDockableFloater::postBuild();
 	}
 
+	// Now ready to build the conversation and participants list
+	buildConversationViewParticipant();
 	refreshConversation();
-	
+		
+	// Zero expiry time is set only once to allow initial update.
+	mRefreshTimer->setTimerExpirySec(0);
+	mRefreshTimer->start();
+
 	return result;
 }
 
@@ -276,9 +260,8 @@ void LLFloaterIMSessionTab::draw()
 			{
 				buildConversationViewParticipant();
 			}
+			refreshConversation();
 		}
-		
-		refreshConversation();
 
 		// Restart the refresh timer
 		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
@@ -390,7 +373,31 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
 		// Nothing to do if the model list is inexistent
 		return;
 	}
-
+	
+	// Create or recreate the root folder: this is a dummy folder (not shown) but required by the LLFolderView architecture 
+	// We need to redo this when rebuilding as the session id (mSessionID) *may* have changed
+	if (mConversationsRoot)
+	{
+		// Remove the old root if any
+		mScroller->removeChild(mConversationsRoot);
+	}
+	// Create the root using an ad-hoc base item
+	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mParticipantListPanel;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
+    p.use_ellipses = true;
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+	// Attach that root to the scroller
+	mScroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(mScroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+	
 	// Create the participants widgets now
 	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
 	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
@@ -420,7 +427,6 @@ void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* p
 		participant_view->addToFolder(mConversationsRoot);
 		participant_view->addToSession(mSessionID);
 		participant_view->setVisible(TRUE);
-		refreshConversation();
 	}
 }
 
@@ -432,7 +438,6 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
 		mConversationsRoot->extractItem(widget);
 		delete widget;
 		mConversationsWidgets.erase(participant_id);
-		refreshConversation();
 	}
 }
 
@@ -443,7 +448,6 @@ void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& part
 	{
 		widget->refresh();
 	}
-	refreshConversation();
 }
 
 void LLFloaterIMSessionTab::refreshConversation()
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 8f5a8c2c1b..b765d121de 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -146,6 +146,7 @@ protected:
 	conversations_widgets_map mConversationsWidgets;
 	LLConversationViewModel mConversationViewModel;
 	LLFolderView* mConversationsRoot;
+	LLScrollContainer* mScroller;
 
 	LLChatHistory* mChatHistory;
 	LLChatEntry* mInputEditor;
-- 
cgit v1.2.3


From 2d25eb18adc0c2c97c63a8e02f2274362672137c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Sat, 17 Nov 2012 13:24:41 -0800
Subject: CHUI-479 : Clean up unecessary tracking code

---
 indra/newview/llconversationview.cpp         |  8 --------
 indra/newview/llfloaterimcontainer.cpp       |  2 --
 indra/newview/llfloaterimsessiontab.cpp      |  1 -
 indra/newview/lloutputmonitorctrl.cpp        | 27 ++-------------------------
 indra/newview/llspeakingindicatormanager.cpp |  8 --------
 indra/newview/llspeakingindicatormanager.h   |  2 +-
 6 files changed, 3 insertions(+), 45 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index d971c943f0..64618fabba 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -308,7 +308,6 @@ void LLConversationViewSession::refresh()
 	}
 
 	// Update all speaking indicators
-	llinfos << "Merov debug : LLConversationViewSession::refresh, updateSpeakingIndicators" << llendl;
 	LLSpeakingIndicatorManager::updateSpeakingIndicators();
 	
 	// Do the regular upstream refresh
@@ -455,7 +454,6 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
 
 void LLConversationViewParticipant::onCurrentVoiceSessionChanged(const LLUUID& session_id)
 {
-	llinfos << "Merov debug : onCurrentVoiceSessionChanged begin, uuid = " << mUUID << ", session_id = " << session_id << llendl;
 	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
 	
 	if (participant_model)
@@ -477,12 +475,6 @@ void LLConversationViewParticipant::refresh()
 	
 	// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
 	mSpeakingIndicator->setIsMuted(participant_model->isMuted());
-	//LLConversationItemSession* parent_session = participant_model->getParentSession();
-	//if (parent_session)
-	//{
-	//	bool is_active = (parent_session->getUUID() == session_id);
-	//	mSpeakingIndicator->switchIndicator(is_active);
-	//}
 	
 	// Do the regular upstream refresh
 	LLFolderViewItem::refresh();
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index bd692aa850..78b930984f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -110,7 +110,6 @@ void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std:
 
 void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
 {
-	llinfos << "Merov debug : sessionVoiceOrIMStarted, uuid = " << session_id << llendl;
 	addConversationListItem(session_id);
 	LLFloaterIMSessionTab::addToHost(session_id);
 }
@@ -1310,7 +1309,6 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 
 bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
 {
-	llinfos << "Merov debug : removeConversationListItem, uuid = " << uuid << llendl;
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 22131eac49..c2c6e739e9 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -725,7 +725,6 @@ void LLFloaterIMSessionTab::onClose(bool app_quitting)
 		LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
 		if (im_box)
 		{
-			llinfos << "Merov debug : LLFloaterIMSessionTab::onClose, mKey = " << mKey << llendl;
             im_box->removeConversationListItem(mKey);
         }
     }
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 536f1fbd73..e4621a7fc3 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -48,8 +48,6 @@ LLColor4	LLOutputMonitorCtrl::sColorBound;
 //F32			LLOutputMonitorCtrl::sRectWidthRatio	= 0.f;
 //F32			LLOutputMonitorCtrl::sRectHeightRatio	= 0.f;
 
-static LLUUID test_uuid("c684ce33-89fb-4544-8f7b-dae243c8b214");
-
 LLOutputMonitorCtrl::Params::Params()
 :	draw_border("draw_border"),
 	image_mute("image_mute"),
@@ -280,44 +278,24 @@ BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 
 void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */)
 {
-	bool test_on = (speaker_id == test_uuid);
-	if (test_on)
-	{
-		llinfos << "Merov debug : setSpeakerId, this = " << this << ", session_id = " << session_id << llendl;
-	}
 	if (speaker_id.isNull() && mSpeakerId.notNull())
 	{
 		LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
 	}
 
-	if (speaker_id.isNull() || speaker_id == mSpeakerId) 
+	if (speaker_id.isNull() || (speaker_id == mSpeakerId))
 	{
-		if (test_on)
-		{
-			llinfos << "Merov debug : setSpeakerId, nothing done because mSpeakerId == speaker_id" << llendl;
-		}
 		return;
 	}
 
 	if (mSpeakerId.notNull())
 	{
-		if (test_on)
-		{
-			llinfos << "Merov debug : setSpeakerId, unregisterSpeakingIndicator" << llendl;
-		}
 		// Unregister previous registration to avoid crash. EXT-4782.
-		if (getTargetSessionID() == session_id)
-		{
-			LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
-		}
+		LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
 	}
 
 	mShowParticipantsSpeaking = show_other_participants_speaking;
 	mSpeakerId = speaker_id;
-	if (test_on)
-	{
-		llinfos << "Merov debug : setSpeakerId, registerSpeakingIndicator" << llendl;
-	}
 	LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this, session_id);
 
 	//mute management
@@ -345,7 +323,6 @@ void LLOutputMonitorCtrl::onChange()
 // virtual
 void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
 {
-	llinfos << "Merov debug : switchIndicator, mSpeakerId = " << mSpeakerId << ", switch_on = " << switch_on << llendl;
 	// ensure indicator is visible in case it is not in visible chain
 	// to be called when parent became visible next time to notify parent that visibility is changed.
 	setVisible(TRUE);
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index d9f9ed5966..76da7d1aee 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -155,7 +155,6 @@ void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_i
 	BOOL is_in_same_voice = LLVoiceClient::getInstance()->isParticipant(speaker_id);
 
 	speakers_uuids.insert(speaker_id);
-	llinfos << "Merov debug : registerSpeakingIndicator call switchSpeakerIndicators, switch = " << is_in_same_voice << llendl;	
 	switchSpeakerIndicators(speakers_uuids, is_in_same_voice);
 }
 
@@ -196,7 +195,6 @@ SpeakingIndicatorManager::~SpeakingIndicatorManager()
 
 void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
 {
-	llinfos << "Merov debug : sOnCurrentChannelChanged call switchSpeakerIndicators, FALSE" << llendl;	
 	switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
 	mSwitchedIndicatorsOn.clear();
 }
@@ -210,16 +208,12 @@ void SpeakingIndicatorManager::onParticipantsChanged()
 
 	LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL;
 	// switch all indicators off
-	llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, FALSE" << llendl;	
 	switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
-	llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, end FALSE switch" << llendl;	
 	mSwitchedIndicatorsOn.clear();
 
 	LL_DEBUGS("SpeakingIndicator") << "Switching all ON, count: " << speakers_uuids.size() << LL_ENDL;
 	// then switch current voice participants indicators on
-	llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, TRUE" << llendl;	
 	switchSpeakerIndicators(speakers_uuids, TRUE);
-	llinfos << "Merov debug : onParticipantsChanged call switchSpeakerIndicators, end TRUE switch" << llendl;	
 }
 
 void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on)
@@ -230,7 +224,6 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea
 	{
 		session_id = voice_channel->getSessionID();
 	}
-	llinfos << "Merov debug : switchSpeakerIndicators, switch_on = " << switch_on << ", voice channel = " << session_id << llendl;
 
 	speaker_ids_t::const_iterator it_uuid = speakers_uuids.begin(); 
 	for (; it_uuid != speakers_uuids.end(); ++it_uuid)
@@ -255,7 +248,6 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea
 			}
 			was_switched_on = was_switched_on || switch_current_on;
 
-			llinfos << "Merov debug : indicator for " << *it_uuid << ", switch_current_on = " << switch_current_on << ", session = " << indicator->getTargetSessionID() << llendl;
 			indicator->switchIndicator(switch_current_on);
 		}
 
diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h
index 8ee368e258..e5afcd1cb7 100644
--- a/indra/newview/llspeakingindicatormanager.h
+++ b/indra/newview/llspeakingindicatormanager.h
@@ -37,7 +37,7 @@ public:
 	virtual ~LLSpeakingIndicator(){}
 	virtual void switchIndicator(bool switch_on) = 0;
 
-//private:
+private:
 	friend class SpeakingIndicatorManager;
 	// Accessors for target voice session UUID.
 	// They are intended to be used only from SpeakingIndicatorManager to ensure target session is 
-- 
cgit v1.2.3


From 0cb67ec3762c1f1671fd01e331fe64a210098fd2 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 19 Nov 2012 07:42:39 +0200
Subject:  CHUI-423 (User typing /me something in chat does not show correctly
 in italics on outgoing or incoming chat)

---
 indra/newview/llchathistory.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 605e3ece51..a33bd88273 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -809,7 +809,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC)
 	{
 		delimiter = LLStringUtil::null;
-		name_params.font.style = "ITALIC";
+		body_message_params.font.style = "ITALIC";
 	}
 
 	bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
-- 
cgit v1.2.3


From f043bc32fd202de88d6823bb938128147ab4a04c Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 19 Nov 2012 09:08:02 +0200
Subject: CHUI-434 (Don't display phone icon and disable phone button when
 voice isn't enabled)

---
 indra/newview/llconversationview.cpp | 20 +++++++-------------
 indra/newview/llconversationview.h   |  2 +-
 2 files changed, 8 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 4c52794e4c..b9d62e85c4 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -57,14 +57,11 @@ public:
 
 	virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal)
 	{
-		if (conversation
-		   && status != STATUS_JOINING
-		   && status != STATUS_LEFT_CHANNEL
-		   && LLVoiceClient::getInstance()->voiceEnabled()
-		   && LLVoiceClient::getInstance()->isVoiceWorking())
-		{
-			conversation->showVoiceIndicator();
-		}
+		conversation->showVoiceIndicator(conversation
+			&& status != STATUS_JOINING
+			&& status != STATUS_LEFT_CHANNEL
+			&& LLVoiceClient::getInstance()->voiceEnabled()
+			&& LLVoiceClient::getInstance()->isVoiceWorking());
 	}
 
 private:
@@ -288,12 +285,9 @@ LLConversationViewParticipant* LLConversationViewSession::findParticipant(const
 	return (iter == getItemsEnd() ? NULL : participant);
 }
 
-void LLConversationViewSession::showVoiceIndicator()
+void LLConversationViewSession::showVoiceIndicator(bool visible)
 {
-	if (LLVoiceChannel::getCurrentVoiceChannel()->getSessionID().isNull())
-	{
-		mCallIconLayoutPanel->setVisible(true);
-	}
+	mCallIconLayoutPanel->setVisible(visible && LLVoiceChannel::getCurrentVoiceChannel()->getSessionID().isNull());
 }
 
 void LLConversationViewSession::refresh()
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 1baa8bb5ec..8156b746b2 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -78,7 +78,7 @@ public:
 	void setVisibleIfDetached(BOOL visible);
 	LLConversationViewParticipant* findParticipant(const LLUUID& participant_id);
 
-	void showVoiceIndicator();
+	void showVoiceIndicator(bool visible);
 
 	virtual void refresh();
 
-- 
cgit v1.2.3


From c48f8c2b28253786ada02d0a57d3a8e005fe9101 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 19 Nov 2012 16:47:40 +0200
Subject: CHUI-487 ADD. FIX (Revised comments)

---
 indra/newview/app_settings/settings.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 14117ee47b..be793a344c 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13145,7 +13145,7 @@
     <key>FlashCount</key>
     <map>
       <key>Comment</key>
-      <string>Number of flashes of IM Well and Notification Well icons after which flashing buttons stay lit up. Requires restart.</string>
+      <string>Number of flashes of item. Requires restart.</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -13156,7 +13156,7 @@
     <key>FlashPeriod</key>
     <map>
       <key>Comment</key>
-      <string>Period at which IM Well and Notification Well icons flash (seconds). Requires restart.</string>
+      <string>Period at which item flash (seconds). Requires restart.</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
-- 
cgit v1.2.3


From 48a683af70fe359f4b4b6fdf6486208fc34dc2a9 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 19 Nov 2012 17:40:46 +0200
Subject: CHUI-488 ADD. fIX Clean up code

---
 indra/llui/llbutton.cpp                                | 7 ++++---
 indra/newview/skins/default/xui/en/widgets/toolbar.xml | 4 ++--
 2 files changed, 6 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 8a34e221b1..8ac55b2eb4 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -174,9 +174,10 @@ LLButton::LLButton(const LLButton::Params& p)
 {
 	// If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
 	// used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
-	// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod");
-	S32 flash_count = p.button_flash_count || 0;
-	F32 flash_rate = p.button_flash_rate || 0.0; //
+	// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
+	// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
+	S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
+	F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
 	mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
 
 	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 0aa478ace9..55ae158c00 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -30,8 +30,8 @@
                         image_overlay_alignment="left"
                         use_ellipses="true"
                         auto_resize="true"
-                        button_flash_count="99999"
-                        button_flash_rate="1.0"
+                        button_flash_count="3"
+                        button_flash_rate="0.25"
                         flash_color="EmphasisColor"/>
   <button_icon pad_left="10"
                pad_right="10"
-- 
cgit v1.2.3


From aba409f24f7ec7d74d545b0309340c98854b7217 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Mon, 19 Nov 2012 17:14:18 -0800
Subject: CHUI-495: Ensuring that a user in do-not-disturb mode can receive
 voice calls from current conversations.

---
 indra/newview/llimview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e2b678626b..b5dc4a7967 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2808,7 +2808,7 @@ void LLIMMgr::inviteToSession(
 	{
 		bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup"));
 		bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL));
-		bool isRejectDoNotDisturb = gAgent.isDoNotDisturb();
+		bool isRejectDoNotDisturb = (gAgent.isDoNotDisturb() && !hasSession(session_id));
 		if	(isRejectGroupCall || isRejectNonFriendCall || isRejectDoNotDisturb)
 		{
 			if (isRejectDoNotDisturb && !isRejectGroupCall && !isRejectNonFriendCall)
-- 
cgit v1.2.3


From 2c2e8b83d02efcdec9ccd3216e64073b4e8e1d57 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 19 Nov 2012 19:26:00 +0200
Subject: CHUI-362 ADD. FIX (When the "Bring back" panel is there, it is not
 possible to collapse the right side of the conversation dialog: the toolbar
 is completely missing and the "<<" chevrons are not there): This was because
 the button "<<" belonged session's floater and not the container. Therefore,
 when all the floaters in the stack becomes invisible, their buttons also
 become invisible. Solution: Added additional button "<<" in the stub_panel of
 the container.

---
 indra/newview/llfloaterimcontainer.cpp                  |  7 +++++++
 indra/newview/llfloaterimcontainer.h                    |  2 ++
 .../skins/default/xui/en/floater_im_container.xml       | 17 +++++++++++++++--
 3 files changed, 24 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 90ddeef5bb..39cd16acfa 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -205,6 +205,8 @@ BOOL LLFloaterIMContainer::postBuild()
 
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onExpandCollapseButtonClicked, this));
+	mStubCollapseBtn = getChild<LLButton>("stub_collapse_btn");
+	mStubCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onStubCollapseButtonClicked, this));
 
 	childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this));
 
@@ -335,6 +337,11 @@ void LLFloaterIMContainer::onNewMessageReceived(const LLSD& data)
 	}
 }
 
+void LLFloaterIMContainer::onStubCollapseButtonClicked()
+{
+	collapseMessagesPane(true);
+}
+
 void LLFloaterIMContainer::onExpandCollapseButtonClicked()
 {
 	if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 9112b54018..9cd6b9bc5d 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -109,6 +109,7 @@ private:
 	void onNewMessageReceived(const LLSD& data);
 
 	void onExpandCollapseButtonClicked();
+	void onStubCollapseButtonClicked();
 	void processParticipantsStyleUpdate();
 
 	void collapseConversationsPane(bool collapse);
@@ -147,6 +148,7 @@ private:
 	void openNearbyChat();
 
 	LLButton* mExpandCollapseBtn;
+	LLButton* mStubCollapseBtn;
 	LLPanel* mStubPanel;
 	LLTextBox* mStubTextBox;
 	LLLayoutPanel* mMessagesPane;
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 1388b9e474..4aa7c88312 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -134,6 +134,19 @@
                left="0"
                height="430"
                width="412">
+                 <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_collapse"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 right="-10"
+                 name="stub_collapse_btn"
+                 tool_tip="Collapse this pane"
+                 width="31" />
                  <text
                    type="string"
                    clip_partial="false"
@@ -142,7 +155,7 @@
                    left="20"
                    right="-20"
                    name="stub_textbox_1"
-                   top="10"
+                   top="30"
                    height="20"
                    valign="center"
                    wrap="true">
@@ -156,7 +169,7 @@
                    left="20"
                    right="-20"
                    name="stub_textbox_2"
-                   top="40"
+                   top="60"
                    height="20"
                    valign="center"
                    parse_urls="true"
-- 
cgit v1.2.3


From 834ded33ae4926b59074f00c13fa3dbf228a3ba0 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 19 Nov 2012 18:41:52 -0800
Subject: CHUI-470 : Fixed : Enable contextual menu in torn off conversations

---
 indra/llui/llfolderview.h               |  1 -
 indra/newview/llfloaterimcontainer.cpp  |  3 +++
 indra/newview/llfloaterimcontainer.h    | 11 ++++++----
 indra/newview/llfloaterimsessiontab.cpp | 39 +++++++++++++++++++++++++++++++++
 indra/newview/llfloaterimsessiontab.h   |  4 ++++
 indra/newview/llinventoryfunctions.cpp  |  2 +-
 6 files changed, 54 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 487391a477..525efe425a 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -148,7 +148,6 @@ public:
 	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
 
 	virtual std::set<LLFolderViewItem*> getSelectionList() const;
-	S32 getNumSelectedItems() { return mSelectedItems.size(); }
 
 	// Make sure if ancestor is selected, descendants are not
 	void sanitizeSelection();
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index aebfdb5bce..65a8aee4ce 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -869,6 +869,7 @@ void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
 
 void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
 {
+	// *TODO : This is where we need to handle a *list* of participant correctly
 	if(selectedIDS.size() > 0)
 	{
 		const LLUUID& userID = selectedIDS.front();
@@ -981,6 +982,8 @@ void LLFloaterIMContainer::doToSelected(const LLSD& userdata)
     if(conversationItem != NULL)
     {
     	getParticipantUUIDs(selected_uuids);
+		
+		llinfos << "Merov debug : doToSelected, command = " << command << ", name = " << conversationItem->getName() << ", uuid size = " << selected_uuids.size() << llendl;
 
     	if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
     	{
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index afc8d00174..78c312629d 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -99,6 +99,13 @@ public:
 
 	void onNearbyChatClosed();
 
+	// Handling of lists of participants is public so to be common with llfloatersessiontab
+	// *TODO : Find a better place for this.
+    void doToSelected(const LLSD& userdata);
+    bool checkContextMenuItem(const LLSD& userdata);
+    bool enableContextMenuItem(const LLSD& userdata);
+    void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
+
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
 	avatarID_panel_map_t mSessions;
@@ -127,12 +134,8 @@ private:
     void getSelectedUUIDs(uuid_vec_t& selected_uuids);
     const LLConversationItem * getCurSelectedViewModelItem();
     void getParticipantUUIDs(uuid_vec_t& selected_uuids);
-    void doToSelected(const LLSD& userdata);
     void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS);
-    void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
     void doToSelectedGroup(const LLSD& userdata);
-    bool checkContextMenuItem(const LLSD& userdata);
-    bool enableContextMenuItem(const LLSD& userdata);
 
 	static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
 	bool enableModerateContextMenuItem(const std::string& userdata);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 69b42cdd6d..ef36a485a8 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -69,6 +69,12 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck,   this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable,  this, _2));
+
+	// Right click menu handling
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+    mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMContainer::checkContextMenuItem,	floater_container, _2));
+    mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem,	floater_container, _2));
+    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2));
 }
 
 LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
@@ -395,6 +401,7 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
     p.view_model = &mConversationViewModel;
     p.root = NULL;
     p.use_ellipses = true;
+    p.options_menu = "menu_conversation.xml";
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
     mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 	// Attach that root to the scroller
@@ -763,3 +770,35 @@ bool LLFloaterIMSessionTab::checkIfTornOff()
 
 	return isTorn;
 }
+
+void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata)
+{
+	// Get the list of selected items in the tab
+	// Note: By construction, those can only be participants so we do not check if they are sessions or something else
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+	getSelectedUUIDs(selected_uuids);
+		
+	llinfos << "Merov debug : doToSelected, command = " << command << ", uuid size = " << selected_uuids.size() << llendl;
+		
+	// Perform the command (IM, profile, etc...) on the list using the general conversation container method
+	// *TODO : Move this method to LLAvatarActions
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	floater_container->doToParticipants(command, selected_uuids);
+}
+
+void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
+{
+    const std::set<LLFolderViewItem*> selected_items = mConversationsRoot->getSelectionList();
+	
+    std::set<LLFolderViewItem*>::const_iterator it = selected_items.begin();
+    const std::set<LLFolderViewItem*>::const_iterator it_end = selected_items.end();
+	
+    for (; it != it_end; ++it)
+    {
+        LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem());
+        selected_uuids.push_back(conversation_item->getUUID());
+    }
+}
+
+
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index b765d121de..5980416dff 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -157,6 +157,10 @@ protected:
 	LLButton* mCloseBtn;
 
 private:
+	// Handling selection and contextual menu
+    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
+    void doToSelected(const LLSD& userdata);
+	
 	/// Refreshes the floater at a constant rate.
 	virtual void refresh() = 0;
 
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 1ae6fd91ce..1426567196 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1068,7 +1068,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
 	if ("delete" == action)
 	{
 		LLSD args;
-		args["QUESTION"] = LLTrans::getString(root->getNumSelectedItems() > 1 ? "DeleteItems" :  "DeleteItem");
+		args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" :  "DeleteItem");
 		LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root));
 		return;
 	}
-- 
cgit v1.2.3


From 380b82c7ee562877d25b9b67c1ebf5b79b126fad Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 20 Nov 2012 12:55:38 +0200
Subject: CHUI-487, CHUI-488 Commented out demo

---
 indra/newview/llfloaterimsessiontab.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 42e7e6cb55..9795df78ae 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -340,8 +340,8 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)
 		// to demonstrate the correct format call the appropriate functions.
 		// They should be moved to the right places when working on CHUI-486. ~Alex ProductEngine.
 		// ---- start demo ----
-            im_box->flashConversationItemWidget(mSessionID, true); // flashing of the conversation's item
-            gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat"
+        //    im_box->flashConversationItemWidget(mSessionID, true); // flashing of the conversation's item
+        //    gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat"
         // ---- end demo -----
 	}
 	
-- 
cgit v1.2.3


From 668761e1196517913688bab6763bd9d2e11359b0 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 20 Nov 2012 13:39:09 +0200
Subject: CHUI-539 FIXED Chat FUI button flashes indefinitely if Icons Only
 setting is selected for the button display

---
 indra/newview/skins/default/xui/en/widgets/toolbar.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 55ae158c00..053b213ef4 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -51,7 +51,7 @@
                chrome="true"
                use_ellipses="true"
                auto_resize="true"
-               button_flash_count="99999"
-               button_flash_rate="1.0"
+               button_flash_count="3"
+               button_flash_rate="0.25"
                flash_color="EmphasisColor"/>
 </toolbar>
-- 
cgit v1.2.3


From b87974df51c4caf12c47009dec03b7dc8afe543d Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 20 Nov 2012 15:18:19 +0200
Subject: CHUI-447 Additional fix(Show only display name for user that starts
 conversation )

---
 indra/newview/llavataractions.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 4f57498506..f5d8998ce5 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -180,7 +180,7 @@ void LLAvatarActions::offerTeleport(const uuid_vec_t& ids)
 static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
 										  const LLAvatarName& av_name)
 {
-	std::string name = av_name.getCompleteName();
+	std::string name = av_name.mDisplayName;
 	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id);
 	if (session_id != LLUUID::null)
 	{
-- 
cgit v1.2.3


From e52c0218c718fe96a7927f0524c4616022be510e Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 20 Nov 2012 18:40:53 +0200
Subject: CHUI-523 FIXED Set visibility of warning message depending on
 combobox state.

---
 indra/newview/llfloaterpreference.cpp | 30 ++++++++++++++++++++++++++++++
 indra/newview/llfloaterpreference.h   |  4 ++++
 2 files changed, 34 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index ffd59ba8b6..d08a1d0034 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -443,12 +443,25 @@ BOOL LLFloaterPreference::postBuild()
 
 	getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
 
+	getChild<LLComboBox>("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions"));
+	getChild<LLComboBox>("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions"));
+	getChild<LLComboBox>("ConferenceIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"ConferenceIMOptions"));
+	getChild<LLComboBox>("GroupChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"GroupChatOptions"));
+	getChild<LLComboBox>("NearbyChatOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NearbyChatOptions"));
+
 	// if floater is opened before login set default localized do not disturb message
 	if (LLStartUp::getStartupState() < STATE_STARTED)
 	{
 		gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
 	}
 
+	//get the options that were checked
+	onNotificationsChange("FriendIMOptions");
+	onNotificationsChange("NonFriendIMOptions");
+	onNotificationsChange("ConferenceIMOptions");
+	onNotificationsChange("GroupChatOptions");
+	onNotificationsChange("NearbyChatOptions");
+
 	return TRUE;
 }
 
@@ -863,6 +876,23 @@ void LLFloaterPreference::onLanguageChange()
 	}
 }
 
+void LLFloaterPreference::onNotificationsChange(const std::string& OptionName)
+{
+	mNotificationOptions[OptionName] = getChild<LLComboBox>(OptionName)->getSelectedItemLabel();
+
+	bool show_notifications_alert = true;
+	for (notifications_map::iterator it_notification = mNotificationOptions.begin(); it_notification != mNotificationOptions.end(); it_notification++)
+	{
+		if(it_notification->second != "None")
+		{
+			show_notifications_alert = false;
+			break;
+		}
+	}
+
+	getChild<LLTextBox>("notifications_alert")->setVisible(show_notifications_alert);
+}
+
 void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue)
 {
 	LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("background");
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 4c1c122fb1..37a531e99e 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -45,6 +45,8 @@ class LLSliderCtrl;
 class LLSD;
 class LLTextBox;
 
+typedef std::map<std::string, std::string> notifications_map;
+
 typedef enum
 	{
 		GS_LOW_GRAPHICS,
@@ -93,6 +95,7 @@ protected:
 	void		onClickClearCache();			// Clear viewer texture cache, vfs, and VO cache on next startup
 	void		onClickBrowserClearCache();		// Clear web history and caches as well as viewer caches above
 	void		onLanguageChange();
+	void		onNotificationsChange(const std::string& OptionName);
 	void		onNameTagOpacityChange(const LLSD& newvalue);
 
 	// set value of "DoNotDisturbResponseChanged" in account settings depending on whether do not disturb response
@@ -170,6 +173,7 @@ public:
 
 private:
 	static std::string sSkin;
+	notifications_map mNotificationOptions;
 	bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
 	bool mGotPersonalInfo;
 	bool mOriginalIMViaEmail;
-- 
cgit v1.2.3


From 81478d6c4475f4650a23ad0e87496e3d425d5709 Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Tue, 20 Nov 2012 18:57:29 +0200
Subject: CHUI-490 FIXED Small ui changes. Changed sound that is playing when
 floater is opened. Call startIM() when user clicks on "Open IM instead"
 button.

---
 indra/newview/llimview.cpp                         | 23 +++------
 .../skins/default/xui/en/floater_incoming_call.xml | 58 +++++++++++-----------
 2 files changed, 36 insertions(+), 45 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b5dc4a7967..a4e356f6a9 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -29,6 +29,7 @@
 #include "llimview.h"
 
 #include "llavatarnamecache.h"	// IDEVO
+#include "llavataractions.h"
 #include "llfloaterreg.h"
 #include "llfontgl.h"
 #include "llgl.h"
@@ -1713,7 +1714,7 @@ BOOL LLCallDialog::postBuild()
 		return FALSE;
 	
 	dockToToolbarButton("speak");
-	
+
 	return TRUE;
 }
 
@@ -2110,7 +2111,6 @@ BOOL LLIncomingCallDialog::postBuild()
 	getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup");
 
 	setCanDrag(FALSE);
-
 	return TRUE;
 }
 
@@ -2118,7 +2118,6 @@ void LLIncomingCallDialog::setCallerName(const std::string& ui_title,
 										 const std::string& ui_label,
 										 const std::string& call_type)
 {
-	setTitle(ui_title);
 
 	// call_type may be a string like " is calling."
 	LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name");
@@ -2136,7 +2135,7 @@ void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id,
 void LLIncomingCallDialog::onOpen(const LLSD& key)
 {
 	LLCallDialog::onOpen(key);
-
+	make_ui_sound("UISndStartIM");
 	LLStringUtil::format_map_t args;
 	LLGroupData data;
 	// if it's a group call, retrieve group name to use it in question
@@ -2144,18 +2143,6 @@ void LLIncomingCallDialog::onOpen(const LLSD& key)
 	{
 		args["[GROUP]"] = data.mName;
 	}
-	// tell the user which voice channel they would be leaving
-	LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel();
-	if (voice && !voice->getSessionName().empty())
-	{
-		args["[CURRENT_CHAT]"] = voice->getSessionName();
-		getChild<LLUICtrl>("question")->setValue(getString(key["question_type"].asString(), args));
-	}
-	else
-	{
-		args["[CURRENT_CHAT]"] = getString("localchat");
-		getChild<LLUICtrl>("question")->setValue(getString(key["question_type"].asString(), args));
-	}
 }
 
 //static
@@ -2216,6 +2203,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 			{
 				gIMMgr->startCall(session_id, LLVoiceChannel::INCOMING_CALL);
 			}
+			else
+			{
+				LLAvatarActions::startIM(caller_id);
+			}
 
 			gIMMgr->clearPendingAgentListUpdates(session_id);
 			gIMMgr->clearPendingInvitation(session_id);
diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
index 81194f61cf..a7864381a9 100644
--- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
@@ -8,8 +8,8 @@
  layout="topleft"
  name="incoming call"
  help_topic="incoming_call"
- title="Incoming call"
- width="410">
+ sound_flags="0"
+ width="550">
     <floater.string
      name="lifetime">
         5
@@ -24,7 +24,7 @@
     </floater.string>
     <floater.string
      name="VoiceInviteP2P">
-        is calling.
+        is calling you.
     </floater.string>
     <floater.string
      name="VoiceInviteAdHoc">
@@ -49,14 +49,14 @@
      image_name="icon_avatar_online.tga"
      layout="topleft"
      left_delta="19"
-     top="35"
+     top="20"
      width="36" />
     <group_icon
      enabled="false"
      follows="left|top"
      height="36"
      layout="topleft"
-     top="35"
+     top="20"
      width="36" />
     <text
      clip_partial="true"
@@ -67,43 +67,43 @@
      name="caller name"
      top="20"
      use_ellipses="true"
-     width="315"
+     width="475"
      word_wrap="true" />
-    <text
-     clip_partial="true"
-     font="SansSerif"
-     height="30"
-     layout="topleft"
-     left="77"
-     name="question"
-     top_pad="5"
-     use_ellipses="true"
-     width="315"
-     word_wrap="true">
-     Do you want to leave [CURRENT_CHAT] and join this voice chat?
-    </text>
-    <button
+     <button
      height="24"
-     label="Accept"
-     label_selected="Accept"
+     label="Answer"
+     label_selected="Answer"
      layout="topleft"
      left="70"
      name="Accept"
-     top="92"
-     width="100" />
+     top_pad="5"
+     width="120" />
     <button
      height="24"
-     label="Reject"
-     label_selected="Reject"
+     label="Ignore"
+     label_selected="Ignore"
      layout="topleft"
      name="Reject"
      left_pad="10"
-     width="100" />
+     width="120" />
     <button
      height="24"
-     label="Start IM"
+     label="Open IM instead"
      layout="topleft"
      name="Start IM"
      left_pad="10"
-     width="100" />
+     width="120" />
+    <text
+     clip_partial="true"
+     font="SansSerif"
+     height="30"
+     layout="topleft"
+     left="77"
+     name="question"
+     top_pad="5"
+     use_ellipses="true"
+     width="475"
+     word_wrap="true">
+     If you answer, you will be disconnected from your current voice conversation.
+    </text>
 </floater>
-- 
cgit v1.2.3


From 3361c9b911447cf30355d1491ce8dd8962676685 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 20 Nov 2012 19:47:56 +0200
Subject: CHUI-522 FIXED Implement check box item 'Keep a conversation log and
 transcript'

---
 indra/newview/llfloaterimcontainer.cpp             | 23 +++++++++++++---------
 .../skins/default/xui/en/menu_participant_view.xml |  5 ++++-
 2 files changed, 18 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 39cd16acfa..c1a5c9ceeb 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1022,16 +1022,21 @@ void LLFloaterIMContainer::doToSelectedGroup(const LLSD& userdata)
 
 bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 {
-    std::string item = userdata.asString();
+    const std::string& item = userdata.asString();
 	uuid_vec_t uuids;
 	getParticipantUUIDs(uuids);
 
-    if(item == std::string("can_activate_group"))
+    if("can_activate_group" == item)
     {
     	LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
     	return gAgent.getGroupID() != selected_group_id;
     }
 
+	if("conversation_log" == item)
+	{
+		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+	}
+
 	if(uuids.size() <= 0)
     {
         return false;
@@ -1040,12 +1045,12 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
     // Note: can_block and can_delete is used only for one person selected menu
     // so we don't need to go over all uuids.
 
-    if (item == std::string("can_block"))
+    if ("can_block" == item)
     {
 		const LLUUID& id = uuids.front();
         return LLAvatarActions::canBlock(id);
     }
-    else if (item == std::string("can_add"))
+    else if ("can_add" == item)
     {
         // We can add friends if:
         // - there are selected people
@@ -1074,7 +1079,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 
         return result;
     }
-    else if (item == std::string("can_delete"))
+    else if ("can_delete" == item)
     {
         // We can remove friends if:
         // - there are selected people
@@ -1097,18 +1102,18 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 
         return result;
     }
-    else if (item == std::string("can_call"))
+    else if ("can_call" == item)
     {
         return LLAvatarActions::canCall();
     }
-    else if (item == std::string("can_show_on_map"))
+    else if ("can_show_on_map" == item)
     {
 		const LLUUID& id = uuids.front();
 
         return (LLAvatarTracker::instance().isBuddyOnline(id) && is_agent_mappable(id))
             || gAgent.isGodlike();
     }
-    else if(item == std::string("can_offer_teleport"))
+    else if("can_offer_teleport" == item)
     {
 		return LLAvatarActions::canOfferTeleport(uuids);
     }
@@ -1117,7 +1122,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 		return enableModerateContextMenuItem(item);
 	}
 
-    return false;
+	return false;
 }
 
 bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata)
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index 523ce7b35b..33d7bd7c01 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -85,5 +85,8 @@
         <menu_item_check.on_click
          function="Floater.Toggle"
          parameter="conversation" />
-      </menu_item_check>
+        <menu_item_check.on_enable
+         function="Avatar.EnableItem"
+         parameter="conversation_log" />
+    </menu_item_check>
 </toggleable_menu>
-- 
cgit v1.2.3


From 1ece38912188650c9bc5a1cf906ca4a88acc21c4 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 20 Nov 2012 19:17:25 +0200
Subject: CHUI-528, CHUI-536, CHUI-538, CHUI-540 Built single processor of
 different types of notifications

---
 indra/newview/llfloaterimsessiontab.cpp |   8 ---
 indra/newview/llimview.cpp              | 110 +++++++++++++++++---------------
 2 files changed, 59 insertions(+), 59 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 9795df78ae..a21ee07d47 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -335,14 +335,6 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)
 	if (im_box)
 	{
 		im_box->setTimeNow(mSessionID,chat.mFromID);
-
-		// TODO: Warning! The next two lines of code are included below only temporarily
-		// to demonstrate the correct format call the appropriate functions.
-		// They should be moved to the right places when working on CHUI-486. ~Alex ProductEngine.
-		// ---- start demo ----
-        //    im_box->flashConversationItemWidget(mSessionID, true); // flashing of the conversation's item
-        //    gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat"
-        // ---- end demo -----
 	}
 	
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a4e356f6a9..f0e2f45db3 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -114,76 +114,84 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
-void toast_callback(const LLSD& msg){
-	// do not show toast in do not disturb mode or it goes from agent
-	if (gAgent.isDoNotDisturb() || gAgent.getID() == msg["from_id"])
-	{
-		return;
-	}
+void on_new_message(const LLSD& msg)
+{
+	std::string action;
+	LLUUID participant_id = msg["from_id"].asUUID();
+	LLUUID session_id = msg["session_id"];
+    LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 
-    // Skip toasting if we have open window of IM with this session id
-    LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(msg["session_id"]);
-    if (
-           open_im_floater
-           && open_im_floater->isInVisibleChain()
-           && open_im_floater->hasFocus()
-           && !open_im_floater->isMinimized()
-           && !(open_im_floater->getHost()
-                   && open_im_floater->getHost()->isMinimized())
-       )
+    // determine action for this session
+    if (session_id.isNull())
     {
-        return;
+    	action = gSavedSettings.getString("NotificationNearbyChatOptions");
     }
-
-	// Skip toasting for system messages
-	if (msg["from_id"].asUUID() == LLUUID::null)
-	{
-		return;
-	}
-
-    // *NOTE Skip toasting if the user disable it in preferences/debug settings ~Alexandrea
-    LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-        msg["session_id"]);
-
-
-    //Ignore P2P Friend/Non-Friend toasts
-    if(session->isP2PSessionType())
+    else if(session->isP2PSessionType())
     {
-        //Ignores non-friends
-        if((LLAvatarTracker::instance().getBuddyInfo(msg["from_id"]) == NULL) 
-            && (gSavedSettings.getString("NotificationNonFriendIMOptions") != "toast"))
+        if (LLAvatarTracker::instance().isBuddy(msg["from_id"].asUUID()))
         {
-            return;
+        	action = gSavedSettings.getString("NotificationFriendIMOptions");
         }
-        //Ignores friends
-        else if(gSavedSettings.getString("NotificationFriendIMOptions") != "toast")
+        else
         {
-            return;
+        	action = gSavedSettings.getString("NotificationNonFriendIMOptions");
         }
     }
-    //Ignore Ad Hoc Toasts
-    else if(session->isAdHocSessionType() 
-            && (gSavedSettings.getString("NotificationConferenceIMOptions") != "toast"))
+    else if(session->isAdHocSessionType())
     {
-        return;
+    	action = gSavedSettings.getString("NotificationConferenceIMOptions");
     }
-    //Ignore Group Toasts
-    else if(session->isGroupSessionType() 
-            && (gSavedSettings.getString("NotificationGroupChatOptions") != "toast"))
+    else if(session->isGroupSessionType())
     {
-        return;
+    	action = gSavedSettings.getString("NotificationGroupChatOptions");
     }
 
-    //Show toast
-	LLAvatarNameCache::get(msg["from_id"].asUUID(),
-		boost::bind(&on_avatar_name_cache_toast,
-			_1, _2, msg));
+	// do not show notification in "do not disturb" mode or it goes from agent
+	if (gAgent.isDoNotDisturb() || gAgent.getID() == participant_id)
+	{
+		return;
+	}
+
+	if ("toast" == action)
+	{
+	    // Skip toasting if we have open window of IM with this session id
+        LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(msg["session_id"]);
+        if (
+             open_im_floater
+             && open_im_floater->isInVisibleChain()
+             && open_im_floater->hasFocus()
+             && !open_im_floater->isMinimized()
+             && !(open_im_floater->getHost()
+                   && open_im_floater->getHost()->isMinimized())
+           )
+        {
+            return;
+        }
+
+	    // Skip toasting for system messages
+	    if (participant_id.isNull())
+	    {
+		    return;
+	    }
+
+        //Show toast
+	    LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+	}
+	else if ("flash" == action)
+	{
+		LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+		if (im_box)
+        {
+			im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
+        }
+        gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat"
+	}
 }
 
 LLIMModel::LLIMModel() 
 {
 	addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
-	addNewMsgCallback(boost::bind(&toast_callback, _1));
+	addNewMsgCallback(boost::bind(&on_new_message, _1));
 }
 
 LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
-- 
cgit v1.2.3


From edeeed95416be2679e1ad3d29bab5396dbcccaa2 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 21 Nov 2012 01:41:49 +0200
Subject: CHUI-531 FIXED Poor fps in CHUI viewer

---
 indra/llui/llbutton.cpp                 | 78 +++++++++++++++++++++++++--------
 indra/llui/llbutton.h                   |  8 +++-
 indra/llui/llcommandmanager.cpp         |  2 +
 indra/llui/llcommandmanager.h           |  6 +++
 indra/llui/llflashtimer.cpp             | 20 +++++----
 indra/llui/llflashtimer.h               |  8 ++--
 indra/llui/llfolderviewitem.cpp         | 24 +++++-----
 indra/llui/llfolderviewitem.h           |  5 +--
 indra/llui/lltabcontainer.cpp           |  4 +-
 indra/llui/lltoolbar.cpp                |  1 +
 indra/newview/app_settings/commands.xml |  1 +
 indra/newview/llconversationview.cpp    | 13 ++++++
 indra/newview/llconversationview.h      |  8 +++-
 indra/newview/llfloaterimcontainer.cpp  |  2 +-
 14 files changed, 129 insertions(+), 51 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 8ac55b2eb4..97547208ec 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -105,6 +105,7 @@ LLButton::Params::Params()
 	badge("badge"),
 	handle_right_mouse("handle_right_mouse"),
 	held_down_delay("held_down_delay"),
+	button_flash_enable("button_flash_enable", false),
 	button_flash_count("button_flash_count"),
 	button_flash_rate("button_flash_rate")
 {
@@ -170,15 +171,24 @@ LLButton::LLButton(const LLButton::Params& p)
 	mMouseUpSignal(NULL),
 	mHeldDownSignal(NULL),
 	mUseDrawContextAlpha(p.use_draw_context_alpha),
-	mHandleRightMouse(p.handle_right_mouse)
+	mHandleRightMouse(p.handle_right_mouse),
+	mFlashingTimer(NULL)
 {
-	// If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
-	// used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
-	// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
-	// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
-	S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
-	F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
-	mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
+	if (p.button_flash_enable)
+	{
+		// If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
+		// used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
+		// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
+		// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
+		S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
+		F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
+		mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
+	}
+	else
+	{
+		mButtonFlashCount = p.button_flash_count;
+		mButtonFlashRate = p.button_flash_rate;
+	}
 
 	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
 	static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
@@ -273,7 +283,11 @@ LLButton::~LLButton()
 	delete mMouseDownSignal;
 	delete mMouseUpSignal;
 	delete mHeldDownSignal;
-	delete mFlashingTimer;
+
+	if (mFlashingTimer)
+	{
+		delete mFlashingTimer;
+	}
 }
 
 // HACK: Committing a button is the same as instantly clicking it.
@@ -599,10 +613,29 @@ void LLButton::draw()
 	static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
 	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
 
-	mFlashing = mFlashingTimer->isFlashing();
-
-	bool flash = mFlashing &&
-	                 (!sEnableButtonFlashing || mFlashingTimer->isHighlight());
+	bool flash = false;
+	if (mFlashingTimer)
+	{
+		mFlashing = mFlashingTimer->isFlashingInProgress();
+		flash = mFlashing && (!sEnableButtonFlashing || mFlashingTimer->isCurrentlyHighlighted());
+	}
+	else 
+	{
+		if(mFlashing)
+		{
+			if ( sEnableButtonFlashing)
+			{
+				F32 elapsed = mFrameTimer.getElapsedTimeF32();
+				S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
+				// flash on or off?
+				flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
+			}
+			else
+			{ // otherwise just highlight button in flash color
+				flash = true;
+			}
+		}
+	}
 
 	bool pressed_by_keyboard = FALSE;
 	if (hasFocus())
@@ -945,19 +978,26 @@ void LLButton::setToggleState(BOOL b)
 	}
 }
 
-void LLButton::setFlashing( BOOL b )	
+void LLButton::setFlashing( bool b )	
 { 
-	if (b)
+	if (mFlashingTimer)
 	{
-		mFlashingTimer->startFlashing();
+		if (b)
+		{
+			mFlashingTimer->startFlashing();
+		}
+		else
+		{
+			mFlashingTimer->stopFlashing();
+		}
 	}
-	else
+	else if (b != mFlashing)
 	{
-		mFlashingTimer->stopFlashing();
+		mFlashing = b; 
+		mFrameTimer.reset();
 	}
 }
 
-
 BOOL LLButton::toggleState()			
 {
     bool flipped = ! getToggleState();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 92548298f5..060db59a8a 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -134,6 +134,7 @@ public:
 
 		Optional<bool>				handle_right_mouse;
 
+		Optional<bool>				button_flash_enable;
 		Optional<S32>				button_flash_count;
 		Optional<F32>				button_flash_rate;
 
@@ -200,7 +201,7 @@ public:
 	void			setToggleState(BOOL b);
 
 	void			setHighlight(bool b);
-	void			setFlashing( BOOL b );
+	void			setFlashing( bool b );
 	BOOL			getFlashing() const		{ return mFlashing; }
     LLFlashTimer*   getFlashTimer() {return mFlashingTimer;}
 
@@ -287,6 +288,8 @@ protected:
 
 	LLFrameTimer	mMouseDownTimer;
 	bool			mNeedsHighlight;
+	S32				mButtonFlashCount;
+	F32				mButtonFlashRate;
 
 	void			drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size);
 	void			resetMouseDownTimer();
@@ -373,7 +376,8 @@ protected:
 	bool						mForcePressedState;
 	bool						mDisplayPressedState;
 
-	LLFlashTimer*				mFlashingTimer;
+	LLFrameTimer				mFrameTimer;
+	LLFlashTimer *				mFlashingTimer;
 
 	bool						mHandleRightMouse;
 };
diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp
index 0e2f3f1961..625fb8e870 100644
--- a/indra/llui/llcommandmanager.cpp
+++ b/indra/llui/llcommandmanager.cpp
@@ -63,6 +63,7 @@ LLCommand::Params::Params()
 	, is_running_parameters("is_running_parameters")
 	, is_starting_function("is_starting_function")
 	, is_starting_parameters("is_starting_parameters")
+	, is_flashing_allowed("is_flashing_allowed", false)
 {
 }
 
@@ -83,6 +84,7 @@ LLCommand::LLCommand(const LLCommand::Params& p)
 	, mIsRunningParameters(p.is_running_parameters)
 	, mIsStartingFunction(p.is_starting_function)
 	, mIsStartingParameters(p.is_starting_parameters)
+	, mIsFlashingAllowed(p.is_flashing_allowed)
 {
 }
 
diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h
index a7276a48aa..ff5a8a3257 100644
--- a/indra/llui/llcommandmanager.h
+++ b/indra/llui/llcommandmanager.h
@@ -111,6 +111,8 @@ public:
 		Optional<std::string>	is_starting_function;
 		Optional<LLSD>			is_starting_parameters;
 
+		Optional<bool>			is_flashing_allowed;
+
 		Params();
 	};
 
@@ -138,6 +140,8 @@ public:
 	const std::string& isStartingFunctionName() const { return mIsStartingFunction; }
 	const LLSD& isStartingParameters() const { return mIsStartingParameters; }
 
+	bool isFlashingAllowed() const { return mIsFlashingAllowed; }
+
 private:
 	LLCommandId mIdentifier;
 
@@ -161,6 +165,8 @@ private:
 
 	std::string mIsStartingFunction;
 	LLSD        mIsStartingParameters;
+
+	bool		mIsFlashingAllowed;
 };
 
 
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
index c572a83ff5..2ad86b5751 100644
--- a/indra/llui/llflashtimer.cpp
+++ b/indra/llui/llflashtimer.cpp
@@ -33,15 +33,15 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 		: LLEventTimer(period)
 		, mCallback(cb)
 		, mCurrentTickCount(0)
-        , mIsFlashing(false)
+        , mIsFlashingInProgress(false)
 {
 	mEventTimer.stop();
 
 	// By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
 	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
 	// in runtime. So, both settings are made as required restart.
-	mFlashCount = 2 * ((count>0)? count : gSavedSettings.getS32("FlashCount"));
-	if (mPeriod<=0)
+	mFlashCount = 2 * ((count > 0) ? count : gSavedSettings.getS32("FlashCount"));
+	if (mPeriod <= 0)
 	{
 		mPeriod = gSavedSettings.getF32("FlashPeriod");
 	}
@@ -49,15 +49,18 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 
 BOOL LLFlashTimer::tick()
 {
-	mIsHighlight = !(mCurrentTickCount % 2);
+	mIsCurrentlyHighlighted = !mIsCurrentlyHighlighted;
+
 	if (mCallback)
 	{
-		mCallback(mIsHighlight);
+		mCallback(mIsCurrentlyHighlighted);
 	}
 
 	if (++mCurrentTickCount >= mFlashCount)
 	{
 		mEventTimer.stop();
+		mCurrentTickCount = 0;
+		mIsFlashingInProgress = false;
 	}
 
 	return FALSE;
@@ -65,15 +68,14 @@ BOOL LLFlashTimer::tick()
 
 void LLFlashTimer::startFlashing()
 {
-	mCurrentTickCount = 0;
-	mIsFlashing = true;
+	mIsFlashingInProgress = true;
 	mEventTimer.start();
 }
 
 void LLFlashTimer::stopFlashing()
 {
-	mIsFlashing = false;
-	mIsHighlight = false;
+	mIsFlashingInProgress = false;
+	mIsCurrentlyHighlighted = false;
 	mEventTimer.stop();
 }
 
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
index 2ef6ebcc8a..538ee0fcca 100644
--- a/indra/llui/llflashtimer.h
+++ b/indra/llui/llflashtimer.h
@@ -50,8 +50,8 @@ public:
 	void startFlashing();
 	void stopFlashing();
 
-	bool isFlashing() {return mIsFlashing;}
-	bool isHighlight() {return mIsHighlight;}
+	bool isFlashingInProgress() {return mIsFlashingInProgress;}
+	bool isCurrentlyHighlighted() {return mIsCurrentlyHighlighted;}
 
 private:
 	callback_t		mCallback;
@@ -60,8 +60,8 @@ private:
 	 */
 	S32 mFlashCount;
 	S32 mCurrentTickCount;
-	bool mIsHighlight;
-	bool mIsFlashing;
+	bool mIsCurrentlyHighlighted;
+	bool mIsFlashingInProgress;
 };
 
 #endif /* LL_FLASHTIMER_H */
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index d65f53cd4d..95407d2364 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -145,8 +145,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
     mArrowSize(p.arrow_size),
     mMaxFolderItemOverlap(p.max_folder_item_overlap)
 {
-	mFlashTimer = new LLFlashTimer();
-
 	sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
 	sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
 	sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
@@ -168,7 +166,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 // Destroys the object
 LLFolderViewItem::~LLFolderViewItem()
 {
-	delete mFlashTimer;
 	mViewModelItem = NULL;
 }
 
@@ -671,6 +668,16 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
 	}
 }
 
+/*virtual*/ bool LLFolderViewItem::isHighlightAllowed()
+{
+	return mIsSelected;
+}
+
+/*virtual*/ bool LLFolderViewItem::isHighlightActive()
+{
+	return mIsCurSelection;
+}
+
 void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, 
                                                         const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
 {
@@ -683,16 +690,13 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
     const S32 focus_bottom = getRect().getHeight() - mItemHeight;
     const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
     const S32 FOCUS_LEFT = 1;
-    bool flashing = mFlashTimer->isFlashing();
-
-    if (flashing? mFlashTimer->isHighlight() : mIsSelected) // always render "current" item (only render other selected items if
-    	             // mShowSingleSelection is FALSE) or flashing item
 
+    if (isHighlightAllowed())	// always render "current" item (only render other selected items if
+    							// mShowSingleSelection is FALSE) or flashing item
     {
         gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
         LLColor4 bg_color = bgColor;
-        bool selection = flashing? mFlashTimer->isHighlight() : mIsCurSelection;
-        if (!selection)
+        if (!isHighlightActive())
         {
             // do time-based fade of extra objects
             F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
@@ -712,7 +716,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
             getRect().getWidth() - 2,
             focus_bottom,
             bg_color, hasKeyboardFocus);
-        if (selection)
+        if (isHighlightActive())
         {
             gl_rect_2d(FOCUS_LEFT, 
                 focus_top, 
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index c8d6c37b04..c5d6d26e84 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -135,6 +135,8 @@ protected:
 	// no-op at this level, but reimplemented in derived classes.
 	virtual void addItem(LLFolderViewItem*) { }
 	virtual void addFolder(LLFolderViewFolder*) { }
+	virtual bool isHighlightAllowed();
+	virtual bool isHighlightActive();
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
@@ -163,7 +165,6 @@ public:
     S32 getIconPad();
     S32 getTextPad();
 
-    LLFlashTimer* getFlashTimer() {return mFlashTimer;}
 	// If 'selection' is 'this' then note that otherwise ignore.
 	// Returns TRUE if this item ends up being selected.
 	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
@@ -274,8 +275,6 @@ public:
 
 private:
 	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
-	LLFlashTimer* mFlashTimer;
-
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index d1f77830a6..3c1dfc1184 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -506,8 +506,8 @@ void LLTabContainer::draw()
 		}
 	}
 
-	mPrevArrowBtn->getFlashTimer()->stopFlashing();
-	mNextArrowBtn->getFlashTimer()->stopFlashing();
+	mPrevArrowBtn->setFlashing(false);
+	mNextArrowBtn->setFlashing(false);
 }
 
 
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 81ea0ebf0c..1aa46806c3 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -914,6 +914,7 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 	button_p.label = LLTrans::getString(commandp->labelRef());
 	button_p.tool_tip = LLTrans::getString(commandp->tooltipRef());
 	button_p.image_overlay = LLUI::getUIImage(commandp->icon());
+	button_p.button_flash_enable = commandp->isFlashingAllowed();
 	button_p.overwriteFrom(mButtonParams[mButtonType]);
 	LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p);
 
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index d4bbd84d0f..4659673333 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -44,6 +44,7 @@
            />
   <command name="chat"
            available_in_toybox="true"
+		   is_flashing_allowed="true"
            icon="Command_Chat_Icon"
            label_ref="Command_Chat_Label"
            tooltip_ref="Command_Conversations_Tooltip"
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index b9d62e85c4..e40d57c318 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -82,6 +82,7 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mVoiceClientObserver(NULL),
 	mMinimizedMode(false)
 {
+	mFlashTimer = new LLFlashTimer();
 }
 
 LLConversationViewSession::~LLConversationViewSession()
@@ -92,6 +93,18 @@ LLConversationViewSession::~LLConversationViewSession()
 	{
 		LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
 	}
+
+	delete mFlashTimer;
+}
+
+bool LLConversationViewSession::isHighlightAllowed()
+{
+	return mFlashTimer->isFlashingInProgress() || mIsSelected;
+}
+
+bool LLConversationViewSession::isHighlightActive()
+{
+	return mFlashTimer->isFlashingInProgress() ? mFlashTimer->isCurrentlyHighlighted() : mIsCurSelection;
 }
 
 BOOL LLConversationViewSession::postBuild()
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 8156b746b2..acd7128b7d 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -55,7 +55,10 @@ public:
 protected:
 	friend class LLUICtrlFactory;
 	LLConversationViewSession( const Params& p );
-	
+
+	/*virtual*/ bool isHighlightAllowed();
+	/*virtual*/ bool isHighlightActive();
+
 	LLFloaterIMContainer* mContainer;
 	
 public:
@@ -82,6 +85,8 @@ public:
 
 	virtual void refresh();
 
+	LLFlashTimer * getFlashTimer() { return mFlashTimer; }
+
 private:
 
 	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
@@ -90,6 +95,7 @@ private:
 	LLPanel*				mCallIconLayoutPanel;
 	LLTextBox*				mSessionTitle;
 	LLOutputMonitorCtrl*	mSpeakingIndicator;
+	LLFlashTimer*			mFlashTimer;
 
 	bool					mMinimizedMode;
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index bcc7e77116..304fb78260 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1611,7 +1611,7 @@ void LLFloaterIMContainer::reSelectConversation()
 
 void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
 {
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
+	LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id));
 	if (widget)
 	{
 		if (is_flashes)
-- 
cgit v1.2.3


From 2dea7a52f616665040d4faff2339e78596a31b90 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Wed, 21 Nov 2012 12:30:12 +0200
Subject: CHUI-535 (Starting a conversation with a user that you have an
 existing conversation with can cause the conversation list and message panel
 to be out of synch) fixed

---
 indra/newview/llfloaterimcontainer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 39cd16acfa..f93f741b3f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -106,7 +106,7 @@ void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::str
 
 void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-    selectConversation(session_id);
+	selectConversationPair(session_id, true);
 }
 
 void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
-- 
cgit v1.2.3


From da5792fcecd1e0a3d84634c0a81bd16d4c04488f Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 21 Nov 2012 15:14:47 +0200
Subject: CHUI-533 FIXED Check that mConversationsRoot is not null

---
 indra/newview/llfloaterimsessiontab.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index a21ee07d47..0057ed3231 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -496,8 +496,11 @@ void LLFloaterIMSessionTab::refreshConversation()
 	}
 	
 	mConversationViewModel.requestSortAll();
-	mConversationsRoot->arrangeAll();
-	mConversationsRoot->update();
+	if(mConversationsRoot != NULL)
+	{
+		mConversationsRoot->arrangeAll();
+		mConversationsRoot->update();
+	}
 	updateHeaderAndToolbar();
 	refresh();
 }
-- 
cgit v1.2.3


From a4a6e5a17d2ae715d8f225d90598a079f8adb17d Mon Sep 17 00:00:00 2001
From: maxim_productengine <mnikolenko@productengine.com>
Date: Wed, 21 Nov 2012 15:26:56 +0200
Subject: CHUI-523 Additional fix

---
 indra/newview/llfloaterpreference.cpp | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index d08a1d0034..2c3f460701 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -455,13 +455,6 @@ BOOL LLFloaterPreference::postBuild()
 		gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
 	}
 
-	//get the options that were checked
-	onNotificationsChange("FriendIMOptions");
-	onNotificationsChange("NonFriendIMOptions");
-	onNotificationsChange("ConferenceIMOptions");
-	onNotificationsChange("GroupChatOptions");
-	onNotificationsChange("NearbyChatOptions");
-
 	return TRUE;
 }
 
@@ -703,6 +696,14 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	// while preferences floater was closed.
 	buildPopupLists();
 
+
+	//get the options that were checked
+	onNotificationsChange("FriendIMOptions");
+	onNotificationsChange("NonFriendIMOptions");
+	onNotificationsChange("ConferenceIMOptions");
+	onNotificationsChange("GroupChatOptions");
+	onNotificationsChange("NearbyChatOptions");
+
 	LLPanelLogin::setAlwaysRefresh(true);
 	refresh();
 	
-- 
cgit v1.2.3


From a12464b9cbc40d4584d6968db2092a56fa3f4bc6 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 21 Nov 2012 11:46:38 -0800
Subject: CHUI-429, CHUI-511, CHUI-388 : Multiselection and menus in torn off
 dialogs

---
 indra/newview/llconversationmodel.cpp              |   7 +-
 indra/newview/llfloaterimcontainer.cpp             | 225 ++++++++++-----------
 indra/newview/llfloaterimcontainer.h               |   1 +
 indra/newview/llfloaterimsessiontab.cpp            |  18 +-
 indra/newview/llfloaterimsessiontab.h              |   1 +
 .../skins/default/xui/en/menu_conversation.xml     |  12 +-
 6 files changed, 142 insertions(+), 122 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 1c56bd672d..0837a49095 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -27,7 +27,6 @@
 
 #include "llviewerprecompiledheaders.h"
 
-#include "llagent.h"
 #include "llavatarnamecache.h"
 #include "llavataractions.h"
 #include "llevents.h"
@@ -422,10 +421,8 @@ void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
     menuentry_vec_t items;
     menuentry_vec_t disabled_items;
 
-    if(gAgent.getID() != mUUID)
-    {
-    	buildParticipantMenuOptions(items);
-    }
+	buildParticipantMenuOptions(items);
+	
     hide_context_entries(menu, items, disabled_items);
 }
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 65a8aee4ce..079cd71039 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -869,68 +869,83 @@ void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
 
 void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
 {
-	// *TODO : This is where we need to handle a *list* of participant correctly
-	if(selectedIDS.size() > 0)
+	if (selectedIDS.size() == 1)
 	{
 		const LLUUID& userID = selectedIDS.front();
-		if(gAgent.getID() != userID)
+		if ("view_profile" == command)
 		{
-			if ("view_profile" == command)
-			{
-				LLAvatarActions::showProfile(userID);
-			}
-			else if("im" == command)
-			{
-				LLAvatarActions::startIM(userID);
-			}
-			else if("offer_teleport" == command)
-			{
-				LLAvatarActions::offerTeleport(selectedIDS);
-			}
-			else if("voice_call" == command)
-			{
-				LLAvatarActions::startCall(userID);
-			}
-			else if("chat_history" == command)
-			{
-				LLAvatarActions::viewChatHistory(userID);
-			}
-			else if("add_friend" == command)
-			{
-				LLAvatarActions::requestFriendshipDialog(userID);
-			}
-			else if("remove_friend" == command)
-			{
-				LLAvatarActions::removeFriendDialog(userID);
-			}
-			else if("invite_to_group" == command)
-			{
-				LLAvatarActions::inviteToGroup(userID);
-			}
-			else if("map" == command)
-			{
-				LLAvatarActions::showOnMap(userID);
-			}
-			else if("share" == command)
-			{
-				LLAvatarActions::share(userID);
-			}
-			else if("pay" == command)
-			{
-				LLAvatarActions::pay(userID);
-			}
-			else if("block_unblock" == command)
-			{
-				LLAvatarActions::toggleBlock(userID);
-			}
-			else if("selected" == command || "mute_all" == command || "unmute_all" == command)
-			{
-				moderateVoice(command, userID);
-			}
-			else if ("toggle_allow_text_chat" == command)
-			{
-				toggleAllowTextChat(userID);
-			}
+			LLAvatarActions::showProfile(userID);
+		}
+		else if ("im" == command)
+		{
+			LLAvatarActions::startIM(userID);
+		}
+		else if ("offer_teleport" == command)
+		{
+			LLAvatarActions::offerTeleport(selectedIDS);
+		}
+		else if ("voice_call" == command)
+		{
+			LLAvatarActions::startCall(userID);
+		}
+		else if ("chat_history" == command)
+		{
+			LLAvatarActions::viewChatHistory(userID);
+		}
+		else if ("add_friend" == command)
+		{
+			LLAvatarActions::requestFriendshipDialog(userID);
+		}
+		else if ("remove_friend" == command)
+		{
+			LLAvatarActions::removeFriendDialog(userID);
+		}
+		else if ("invite_to_group" == command)
+		{
+			LLAvatarActions::inviteToGroup(userID);
+		}
+		else if ("map" == command)
+		{
+			LLAvatarActions::showOnMap(userID);
+		}
+		else if ("share" == command)
+		{
+			LLAvatarActions::share(userID);
+		}
+		else if ("pay" == command)
+		{
+			LLAvatarActions::pay(userID);
+		}
+		else if ("block_unblock" == command)
+		{
+			LLAvatarActions::toggleBlock(userID);
+		}
+		else if ("selected" == command || "mute_all" == command || "unmute_all" == command)
+		{
+			moderateVoice(command, userID);
+		}
+		else if ("toggle_allow_text_chat" == command)
+		{
+			toggleAllowTextChat(userID);
+		}
+	}
+	else if (selectedIDS.size() > 1)
+	{
+		if ("im" == command)
+		{
+			LLAvatarActions::startConference(selectedIDS);
+		}
+		else if ("offer_teleport" == command)
+		{
+			LLAvatarActions::offerTeleport(selectedIDS);
+		}
+		else if ("voice_call" == command)
+		{
+			LLAvatarActions::startAdhocCall(selectedIDS);
+		}
+		else if ("remove_friend" == command)
+		{
+			LLAvatarActions::removeFriendsDialog(selectedIDS);
 		}
 	}
 }
@@ -1021,75 +1036,61 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 	uuid_vec_t uuids;
 	getParticipantUUIDs(uuids);
 
-    if(item == std::string("can_activate_group"))
+    if (item == std::string("can_activate_group"))
     {
     	LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
     	return gAgent.getGroupID() != selected_group_id;
     }
+	
+	return enableContextMenuItem(item, uuids);
+}
 
-	if(uuids.size() <= 0)
+bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_vec_t& uuids)
+{
+	// If nothing is selected, everything needs to be disabled
+	if (uuids.size() <= 0)
     {
         return false;
     }
+	
+	// Extract the single select info
+	bool is_single_select = (uuids.size() == 1);
+	const LLUUID& single_id = uuids.front();
+	
+	// Handle options that are applicable to all including the user agent
+    if ("can_view_profile" == item)
+    {
+		return is_single_select;
+	}
+	
+	// Beyond that point, if only the user agent is selected, everything is disabled
+	if (is_single_select && (single_id == gAgentID))
+	{
+		return false;
+	}
 
-    // Note: can_block and can_delete is used only for one person selected menu
-    // so we don't need to go over all uuids.
-
+	// Handle all other options
     if (item == std::string("can_block"))
     {
-		const LLUUID& id = uuids.front();
-        return LLAvatarActions::canBlock(id);
+        return (is_single_select ? LLAvatarActions::canBlock(single_id) : false);
     }
     else if (item == std::string("can_add"))
     {
         // We can add friends if:
-        // - there are selected people
-        // - and there are no friends among selection yet.
-
-        //EXT-7389 - disable for more than 1
-		if(uuids.size() > 1)
-        {
-            return false;
-        }
-
-        bool result = true;
-
-        uuid_vec_t::const_iterator
-			id = uuids.begin(),
-			uuids_end = uuids.end();
-
-        for (;id != uuids_end; ++id)
-        {
-            if ( LLAvatarActions::isFriend(*id) )
-            {
-                result = false;
-                break;
-            }
-        }
-
-        return result;
+        // - there is only 1 selected avatar (EXT-7389)
+        // - this avatar is not a friend yet
+        return (is_single_select ? !LLAvatarActions::isFriend(single_id) : false);
     }
     else if (item == std::string("can_delete"))
     {
         // We can remove friends if:
         // - there are selected people
-        // - and there are only friends among selection.
-
-        bool result = (uuids.size() > 0);
-
-        uuid_vec_t::const_iterator
-			id = uuids.begin(),
-			uuids_end = uuids.end();
-
-        for (;id != uuids_end; ++id)
+        // - and there are only friends among the selection
+        bool result = true;
+        for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
         {
-            if ( !LLAvatarActions::isFriend(*id) )
-            {
-                result = false;
-                break;
-            }
+			result &= LLAvatarActions::isFriend(*id);
         }
-
         return result;
     }
     else if (item == std::string("can_call"))
@@ -1098,21 +1099,19 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
     }
     else if (item == std::string("can_show_on_map"))
     {
-		const LLUUID& id = uuids.front();
-
-        return (LLAvatarTracker::instance().isBuddyOnline(id) && is_agent_mappable(id))
-            || gAgent.isGodlike();
+        return (is_single_select ? (LLAvatarTracker::instance().isBuddyOnline(single_id) && is_agent_mappable(single_id)) || gAgent.isGodlike() : false);
     }
-    else if(item == std::string("can_offer_teleport"))
+    else if (item == std::string("can_offer_teleport"))
     {
 		return LLAvatarActions::canOfferTeleport(uuids);
     }
-	else if("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item)
+	else if ("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item)
 	{
 		return enableModerateContextMenuItem(item);
 	}
 
-    return false;
+	// By default, options that not explicitely disabled are enabled
+    return true;
 }
 
 bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata)
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 78c312629d..3d82ccfc21 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -104,6 +104,7 @@ public:
     void doToSelected(const LLSD& userdata);
     bool checkContextMenuItem(const LLSD& userdata);
     bool enableContextMenuItem(const LLSD& userdata);
+    bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
     void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
 
 private:
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index ef36a485a8..751b3c9db8 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -73,7 +73,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 	// Right click menu handling
 	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
     mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMContainer::checkContextMenuItem,	floater_container, _2));
-    mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem,	floater_container, _2));
+    mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2));
     mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2));
 }
 
@@ -787,6 +787,22 @@ void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata)
 	floater_container->doToParticipants(command, selected_uuids);
 }
 
+bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata)
+{
+	// Get the list of selected items in the tab
+	// Note: By construction, those can only be participants so we do not check if they are sessions or something else
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+	getSelectedUUIDs(selected_uuids);
+	
+	llinfos << "Merov debug : enableContextMenuItem, command = " << command << ", uuid size = " << selected_uuids.size() << llendl;
+	
+	// Perform the command (IM, profile, etc...) on the list using the general conversation container method
+	// *TODO : Move this method to LLAvatarActions
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->enableContextMenuItem(command, selected_uuids);
+}
+
 void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
 {
     const std::set<LLFolderViewItem*> selected_items = mConversationsRoot->getSelectionList();
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 5980416dff..0154839287 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -160,6 +160,7 @@ private:
 	// Handling selection and contextual menu
     void getSelectedUUIDs(uuid_vec_t& selected_uuids);
     void doToSelected(const LLSD& userdata);
+    bool enableContextMenuItem(const LLSD& userdata);
 	
 	/// Refreshes the floater at a constant rate.
 	virtual void refresh() = 0;
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 2e9bda5804..908b2c174f 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -30,12 +30,14 @@
      layout="topleft"
      name="view_profile">
         <on_click function="Avatar.DoToSelected" parameter="view_profile"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_view_profile"/>
     </menu_item_call>
     <menu_item_call
      label="IM"
      layout="topleft"
      name="im">
         <on_click function="Avatar.DoToSelected" parameter="im"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_im"/>
     </menu_item_call>
     <menu_item_call
      label="Offer teleport"
@@ -56,6 +58,7 @@
      layout="topleft"
      name="chat_history">
         <on_click function="Avatar.DoToSelected" parameter="chat_history"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_chat_history"/>
     </menu_item_call>	
     <menu_item_separator layout="topleft" name="separator_chat_history"/>	
     <menu_item_call
@@ -77,6 +80,7 @@
      layout="topleft"
      name="invite_to_group">
         <on_click function="Avatar.DoToSelected" parameter="invite_to_group" />
+        <on_enable function="Avatar.EnableItem" parameter="can_invite" />
     </menu_item_call>
     <menu_item_separator layout="topleft" name="separator_invite_to_group"/>		
     <menu_item_call
@@ -91,12 +95,14 @@
      layout="topleft"
      name="share">
         <on_click function="Avatar.DoToSelected" parameter="share" />
+        <on_enable function="Avatar.EnableItem" parameter="can_share" />
     </menu_item_call>
     <menu_item_call
      label="Pay"
      layout="topleft"
      name="pay">
         <on_click function="Avatar.DoToSelected" parameter="pay" />
+        <on_enable function="Avatar.EnableItem" parameter="can_pay" />
     </menu_item_call>
     <menu_item_check
      label="Block / unblock"
@@ -111,6 +117,7 @@
      layout="topleft"
      name="group_profile">
         <on_click function="Group.DoToSelected" parameter="group_profile"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_group_profile" />
     </menu_item_call>	
     <menu_item_call
      label="Activate Group"
@@ -124,10 +131,9 @@
      layout="topleft"
      name="leave_group">
         <on_click function="Group.DoToSelected" parameter="leave_group"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_leave_group" />
     </menu_item_call>
-	<menu_item_separator
-	 layout="topleft"
-	 name="Moderator Options Separator"/>
+	<menu_item_separator layout="topleft" name="Moderator Options Separator"/>
 	<context_menu
 	 label="Moderator Options"
 	 layout="topleft"
-- 
cgit v1.2.3


From 7ca2508cc2adcdc5201bd53e814246e156bc6013 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 21 Nov 2012 18:15:24 -0800
Subject: CHUI-429 : Completed this though it still doesn't work on Nearby
 Chat.

---
 indra/newview/llfloaterimcontainer.cpp  | 42 +++++++++++++++++++--------------
 indra/newview/llfloaterimcontainer.h    |  7 +++---
 indra/newview/llfloaterimnearbychat.cpp | 21 +++++++++--------
 indra/newview/llfloaterimnearbychat.h   |  2 +-
 indra/newview/llfloaterimsessiontab.cpp | 26 +++++++++++---------
 indra/newview/llfloaterimsessiontab.h   |  4 +++-
 6 files changed, 58 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 079cd71039..a56705d969 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -98,7 +98,6 @@ LLFloaterIMContainer::~LLFloaterIMContainer()
 
 void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
 {
-	llinfos << "Merov debug : sessionAdded, uuid = " << session_id << ", name = " << name << llendl;
 	addConversationListItem(session_id);
 	LLFloaterIMSessionTab::addToHost(session_id);
 }
@@ -998,8 +997,6 @@ void LLFloaterIMContainer::doToSelected(const LLSD& userdata)
     {
     	getParticipantUUIDs(selected_uuids);
 		
-		llinfos << "Merov debug : doToSelected, command = " << command << ", name = " << conversationItem->getName() << ", uuid size = " << selected_uuids.size() << llendl;
-
     	if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
     	{
     		doToParticipants(command, selected_uuids);
@@ -1070,22 +1067,25 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
 	}
 
 	// Handle all other options
-    if (item == std::string("can_block"))
+	if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+	{
+		// Those menu items are enable only if a single avatar is selected
+		return is_single_select;
+	}
+    else if ("can_block" == item)
     {
         return (is_single_select ? LLAvatarActions::canBlock(single_id) : false);
     }
-    else if (item == std::string("can_add"))
+    else if ("can_add" == item)
     {
         // We can add friends if:
         // - there is only 1 selected avatar (EXT-7389)
-        // - this avatar is not a friend yet
+        // - this avatar is not already a friend
         return (is_single_select ? !LLAvatarActions::isFriend(single_id) : false);
     }
-    else if (item == std::string("can_delete"))
+    else if ("can_delete" == item)
     {
-        // We can remove friends if:
-        // - there are selected people
-        // - and there are only friends among the selection
+        // We can remove friends if there are only friends among the selection
         bool result = true;
         for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
         {
@@ -1093,20 +1093,21 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
         }
         return result;
     }
-    else if (item == std::string("can_call"))
+    else if ("can_call" == item)
     {
         return LLAvatarActions::canCall();
     }
-    else if (item == std::string("can_show_on_map"))
+    else if ("can_show_on_map" == item)
     {
         return (is_single_select ? (LLAvatarTracker::instance().isBuddyOnline(single_id) && is_agent_mappable(single_id)) || gAgent.isGodlike() : false);
     }
-    else if (item == std::string("can_offer_teleport"))
+    else if ("can_offer_teleport" == item)
     {
 		return LLAvatarActions::canOfferTeleport(uuids);
     }
-	else if ("can_moderate_voice" == item || "can_allow_text_chat" == item || "can_mute" == item || "can_unmute" == item)
+	else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item))
 	{
+		// *TODO : get that out of here...
 		return enableModerateContextMenuItem(item);
 	}
 
@@ -1117,14 +1118,19 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
 bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata)
 {
     std::string item = userdata.asString();
-    uuid_vec_t mUUIDs;
-    getParticipantUUIDs(mUUIDs);
+	uuid_vec_t uuids;
+	getParticipantUUIDs(uuids);
+	
+	return checkContextMenuItem(item, uuids);
+}
 
-    if(mUUIDs.size() > 0 )
+bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_vec_t& uuids)
+{
+    if (uuids.size() == 1)
     {
 		if ("is_blocked" == item)
 		{
-			return LLAvatarActions::isBlocked(mUUIDs.front());
+			return LLAvatarActions::isBlocked(uuids.front());
 		}
 		else if ("is_allowed_text_chat" == item)
 		{
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 3d82ccfc21..bec0c3ef14 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -101,9 +101,7 @@ public:
 
 	// Handling of lists of participants is public so to be common with llfloatersessiontab
 	// *TODO : Find a better place for this.
-    void doToSelected(const LLSD& userdata);
-    bool checkContextMenuItem(const LLSD& userdata);
-    bool enableContextMenuItem(const LLSD& userdata);
+    bool checkContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
     bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
     void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
 
@@ -135,6 +133,9 @@ private:
     void getSelectedUUIDs(uuid_vec_t& selected_uuids);
     const LLConversationItem * getCurSelectedViewModelItem();
     void getParticipantUUIDs(uuid_vec_t& selected_uuids);
+    void doToSelected(const LLSD& userdata);
+    bool checkContextMenuItem(const LLSD& userdata);
+    bool enableContextMenuItem(const LLSD& userdata);
     void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS);
     void doToSelectedGroup(const LLSD& userdata);
 
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 5867eb3e84..7002342c0b 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -112,6 +112,7 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 {
     setIsSingleInstance(TRUE);
     BOOL result = LLFloaterIMSessionTab::postBuild();
+	
 	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
 	mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
 	mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
@@ -122,24 +123,24 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 //	mOutputMonitor->setVisible(FALSE);
 
 	// Register for font change notifications
-	LLViewerChat::setFontChangedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatFontChange, this, _1));
+//	LLViewerChat::setFontChangedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatFontChange, this, _1));
 
 	// title must be defined BEFORE call addConversationListItem() because
 	// it is used for show the item's name in the conversations list
 	setTitle(LLTrans::getString("NearbyChatTitle"));
 
 	//for menu
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+//	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+//	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
 
-	enable_registrar.add("NearbyChat.Check", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
-	registrar.add("NearbyChat.Action", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
+//	enable_registrar.add("NearbyChat.Check", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
+//	registrar.add("NearbyChat.Action", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
 
-	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(menu)
-	{
-		mPopupMenuHandle = menu->getHandle();
-	}
+//	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+//	if(menu)
+//	{
+//		mPopupMenuHandle = menu->getHandle();
+//	}
 
 	// obsolete, but may be needed for backward compatibility?
 	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index 1479746fbd..5ed639136b 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -117,7 +117,7 @@ private:
 
 	/*virtual*/ void refresh();
 
-	LLHandle<LLView>	mPopupMenuHandle;
+//	LLHandle<LLView>	mPopupMenuHandle;
 	std::vector<LLChat> mMessageArchive;
 
 };
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 751b3c9db8..3fb24f52c4 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -71,8 +71,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable,  this, _2));
 
 	// Right click menu handling
-	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
-    mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMContainer::checkContextMenuItem,	floater_container, _2));
+    mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem,	this, _2));
     mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2));
     mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2));
 }
@@ -774,35 +773,40 @@ bool LLFloaterIMSessionTab::checkIfTornOff()
 void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata)
 {
 	// Get the list of selected items in the tab
-	// Note: By construction, those can only be participants so we do not check if they are sessions or something else
     std::string command = userdata.asString();
     uuid_vec_t selected_uuids;
 	getSelectedUUIDs(selected_uuids);
 		
-	llinfos << "Merov debug : doToSelected, command = " << command << ", uuid size = " << selected_uuids.size() << llendl;
-		
 	// Perform the command (IM, profile, etc...) on the list using the general conversation container method
-	// *TODO : Move this method to LLAvatarActions
 	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	// Note: By construction, those can only be participants so we can call doToParticipants() directly
 	floater_container->doToParticipants(command, selected_uuids);
 }
 
 bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata)
 {
 	// Get the list of selected items in the tab
-	// Note: By construction, those can only be participants so we do not check if they are sessions or something else
     std::string command = userdata.asString();
     uuid_vec_t selected_uuids;
 	getSelectedUUIDs(selected_uuids);
 	
-	llinfos << "Merov debug : enableContextMenuItem, command = " << command << ", uuid size = " << selected_uuids.size() << llendl;
-	
-	// Perform the command (IM, profile, etc...) on the list using the general conversation container method
-	// *TODO : Move this method to LLAvatarActions
+	// Perform the item enable test on the list using the general conversation container method
 	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
 	return floater_container->enableContextMenuItem(command, selected_uuids);
 }
 
+bool LLFloaterIMSessionTab::checkContextMenuItem(const LLSD& userdata)
+{
+	// Get the list of selected items in the tab
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+	getSelectedUUIDs(selected_uuids);
+	
+	// Perform the item check on the list using the general conversation container method
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->checkContextMenuItem(command, selected_uuids);
+}
+
 void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
 {
     const std::set<LLFolderViewItem*> selected_items = mConversationsRoot->getSelectionList();
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 0154839287..8efa0955fc 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -158,9 +158,11 @@ protected:
 
 private:
 	// Handling selection and contextual menu
-    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
     void doToSelected(const LLSD& userdata);
     bool enableContextMenuItem(const LLSD& userdata);
+    bool checkContextMenuItem(const LLSD& userdata);
+	
+    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
 	
 	/// Refreshes the floater at a constant rate.
 	virtual void refresh() = 0;
-- 
cgit v1.2.3


From cbe90ebc9cbda965b03db2757cdb356d5f831d44 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 23 Nov 2012 19:05:28 +0200
Subject: Additional fix for CHUI-490 (Show "Display Name (user.name)" for the
 user that is calling)

---
 indra/newview/llimview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index f0e2f45db3..5aceb6c66b 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2137,7 +2137,7 @@ void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id,
 											 const std::string& call_type)
 {
 	std::string title = av_name.getCompleteName();
-	setCallerName(title, av_name.mDisplayName, call_type);
+	setCallerName(title, av_name.getCompleteName(), call_type);
 }
 
 void LLIncomingCallDialog::onOpen(const LLSD& key)
-- 
cgit v1.2.3


From a83676e1ab6ae6c12e28c5f568ac933c2e97408c Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 23 Nov 2012 19:56:59 +0200
Subject: CHUI-530 FIXED Don't switch to new conversation automatically

---
 indra/newview/llfloaterimsessiontab.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 0057ed3231..dcf1b52118 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -162,7 +162,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 			if (!conversp->isNearbyChat()
 					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
-				floater_container->addFloater(conversp, TRUE, LLTabContainer::END);
+				floater_container->addFloater(conversp, FALSE, LLTabContainer::END);
 
 				if (!floater_container->getVisible())
 				{
-- 
cgit v1.2.3


From f37645554ce97026869563aedea8f8c6133d8044 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 23 Nov 2012 13:39:53 +0200
Subject: CHUI-528, CHUI-536, CHUI-538, CHUI-540 ADD. FIX (Built single
 processor of different types of notifications): repaired LLFlashTimer

---
 indra/llui/llflashtimer.cpp | 19 +++++++++++++++----
 indra/llui/llflashtimer.h   |  4 ++--
 2 files changed, 17 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
index 2ad86b5751..de7a4ab265 100644
--- a/indra/llui/llflashtimer.cpp
+++ b/indra/llui/llflashtimer.cpp
@@ -34,6 +34,7 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 		, mCallback(cb)
 		, mCurrentTickCount(0)
         , mIsFlashingInProgress(false)
+        , mIsCurrentlyHighlighted(false)
 {
 	mEventTimer.stop();
 
@@ -58,9 +59,7 @@ BOOL LLFlashTimer::tick()
 
 	if (++mCurrentTickCount >= mFlashCount)
 	{
-		mEventTimer.stop();
-		mCurrentTickCount = 0;
-		mIsFlashingInProgress = false;
+		stopFlashing();
 	}
 
 	return FALSE;
@@ -69,14 +68,26 @@ BOOL LLFlashTimer::tick()
 void LLFlashTimer::startFlashing()
 {
 	mIsFlashingInProgress = true;
+	mIsCurrentlyHighlighted = true;
 	mEventTimer.start();
 }
 
 void LLFlashTimer::stopFlashing()
 {
+	mEventTimer.stop();
 	mIsFlashingInProgress = false;
 	mIsCurrentlyHighlighted = false;
-	mEventTimer.stop();
+	mCurrentTickCount = 0;
+}
+
+bool LLFlashTimer::isFlashingInProgress()
+{
+	return mIsFlashingInProgress;
+}
+
+bool LLFlashTimer::isCurrentlyHighlighted()
+{
+	return mIsCurrentlyHighlighted;
 }
 
 
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
index 538ee0fcca..5c8860b097 100644
--- a/indra/llui/llflashtimer.h
+++ b/indra/llui/llflashtimer.h
@@ -50,8 +50,8 @@ public:
 	void startFlashing();
 	void stopFlashing();
 
-	bool isFlashingInProgress() {return mIsFlashingInProgress;}
-	bool isCurrentlyHighlighted() {return mIsCurrentlyHighlighted;}
+	bool isFlashingInProgress();
+	bool isCurrentlyHighlighted();
 
 private:
 	callback_t		mCallback;
-- 
cgit v1.2.3


From 01a43d0a04bdbd286ef61985c356029f3d12e324 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 23 Nov 2012 15:10:28 +0200
Subject: CHUI-528, CHUI-536, CHUI-538, CHUI-540 ADD. FIX (Built single
 processor of different types of notifications): changed item's highlighting

---
 indra/llui/llfolderviewitem.cpp | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 95407d2364..89c7e0d14a 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -711,12 +711,17 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
                 bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
             }
         }
-        gl_rect_2d(FOCUS_LEFT,
-            focus_top, 
-            getRect().getWidth() - 2,
-            focus_bottom,
-            bg_color, hasKeyboardFocus);
-        if (isHighlightActive())
+
+        if (!isHighlightAllowed() || isHighlightActive())
+        {
+        	gl_rect_2d(FOCUS_LEFT,
+                focus_top,
+                getRect().getWidth() - 2,
+                focus_bottom,
+                bg_color, hasKeyboardFocus);
+        }
+
+        if (mIsCurSelection)
         {
             gl_rect_2d(FOCUS_LEFT, 
                 focus_top, 
-- 
cgit v1.2.3


From 2ce98c8b14d86bb5c8078c762bfc32b6fc4d8346 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 23 Nov 2012 15:13:28 +0200
Subject: CHUI-528, CHUI-536, CHUI-538, CHUI-540 ADD. FIX (Built single
 processor of different types of notifications): include flashing for the
 nearby chat

---
 indra/newview/llviewermessage.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index e21db146db..dc8192105f 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -65,6 +65,7 @@
 #include "llfloatersnapshot.h"
 #include "llhudeffecttrail.h"
 #include "llhudmanager.h"
+#include "llimview.h"
 #include "llinventoryfunctions.h"
 #include "llinventoryobserver.h"
 #include "llinventorypanel.h"
@@ -120,6 +121,8 @@
 #pragma warning (disable:4702)
 #endif
 
+extern void on_new_message(const LLSD& msg);
+
 //
 // Constants
 //
@@ -3641,6 +3644,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		{
 			LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
 		}
+
+		LLSD msg_notify = LLSD(LLSD::emptyMap());
+		msg_notify["session_id"] = LLUUID();
+        msg_notify["from_id"] = chat.mFromID;
+        on_new_message(msg_notify);
 	}
 }
 
-- 
cgit v1.2.3


From 890965faf5baa5f6f832e086991d59bb8d33b7bc Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 23 Nov 2012 15:14:17 +0200
Subject: CHUI-528, CHUI-536, CHUI-538, CHUI-540 ADD. FIX (Built single
 processor of different types of notifications): clean up code

---
 indra/newview/llimview.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5aceb6c66b..db52a50aa1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -118,17 +118,18 @@ void on_new_message(const LLSD& msg)
 {
 	std::string action;
 	LLUUID participant_id = msg["from_id"].asUUID();
-	LLUUID session_id = msg["session_id"];
+	LLUUID session_id = msg["session_id"].asUUID();
     LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 
     // determine action for this session
+
     if (session_id.isNull())
     {
     	action = gSavedSettings.getString("NotificationNearbyChatOptions");
     }
     else if(session->isP2PSessionType())
     {
-        if (LLAvatarTracker::instance().isBuddy(msg["from_id"].asUUID()))
+        if (LLAvatarTracker::instance().isBuddy(participant_id))
         {
         	action = gSavedSettings.getString("NotificationFriendIMOptions");
         }
@@ -152,10 +153,12 @@ void on_new_message(const LLSD& msg)
 		return;
 	}
 
+	// execution of the action
+
 	if ("toast" == action)
 	{
 	    // Skip toasting if we have open window of IM with this session id
-        LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(msg["session_id"]);
+        LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(session_id);
         if (
              open_im_floater
              && open_im_floater->isInVisibleChain()
-- 
cgit v1.2.3


From a243a0475e9bc87ec4acf31700443461ebc58a54 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 26 Nov 2012 12:24:11 +0200
Subject: CHUI-542 (Torn off message in conversation panel is not cleared when
 torn off conversation is closed)

---
 indra/newview/llfloaterimcontainer.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 304fb78260..d4b552deae 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1353,10 +1353,12 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 		setFocus(TRUE);
 		if(new_selection != NULL)
 		{
+			if (mConversationsWidgets.size() == 1)
+				new_selection = new_selection->getParentFolder();
 			LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
 			if(vmi != NULL)
 			{
-				selectConversation(vmi->getUUID());
+				selectConversationPair(vmi->getUUID(), true);
 			}
 		}
 	}
-- 
cgit v1.2.3


From 1a3c5e574bb262f4b334b1c00c671db346c1c658 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 26 Nov 2012 17:49:16 -0800
Subject: CHUI-528, CHUI-536, CHUI-538, CHUI-540: Fixed the changed item's
 highlighting that broke multiselection in inventory and in conversations.

---
 indra/llui/llfolderviewitem.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 89c7e0d14a..261f53d6b6 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -712,7 +712,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
             }
         }
 
-        if (!isHighlightAllowed() || isHighlightActive())
+        if (isHighlightAllowed() || isHighlightActive())
         {
         	gl_rect_2d(FOCUS_LEFT,
                 focus_top,
@@ -721,7 +721,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
                 bg_color, hasKeyboardFocus);
         }
 
-        if (mIsCurSelection)
+        if (isHighlightActive())
         {
             gl_rect_2d(FOCUS_LEFT, 
                 focus_top, 
-- 
cgit v1.2.3


From 4105ae946707947e469793364e07adde7993cffe Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 26 Nov 2012 19:12:04 -0800
Subject: CHUI-529: Post code review changes. When showing a floater using
 LLFloater::showInstance() instead of setVisibleAndFrontmost(). Also made
 setVisibleAndFrontmost() public since both setVisible and setFrontmost are
 public functions.

---
 indra/llui/llfloater.h                         | 2 +-
 indra/newview/llfloaterimnearbychathandler.cpp | 8 +-------
 indra/newview/llimview.cpp                     | 8 +-------
 3 files changed, 3 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index a657538eb7..9ad566a1a1 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -302,6 +302,7 @@ public:
 	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override
 	
 	void			setFrontmost(BOOL take_focus = TRUE);
+    virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE);    
 	
 	// Defaults to false.
 	virtual BOOL	canSaveAs() const { return FALSE; }
@@ -373,7 +374,6 @@ protected:
 	void		 	setInstanceName(const std::string& name);
 	
 	virtual void	bringToFront(S32 x, S32 y);
-	virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE);    
 	
 	void			setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
 	const LLRect&	getExpandedRect() const { return mExpandedRect; }
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 2d8a6d46fe..d9c461e836 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -622,13 +622,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
         //Will show Conversations floater when chat preference is set
         else if(gSavedSettings.getString("NotificationNearbyChatOptions") == "openconversations")
         {
-            LLFloaterIMContainer * floaterIMContainer = LLFloaterIMContainer::getInstance();
-
-            if(floaterIMContainer)
-            {
-                floaterIMContainer->setVisible(TRUE);
-                floaterIMContainer->setFrontmost(TRUE);
-            }
+            LLFloaterReg::showInstance("im_container");
         }
 
 	}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index fc6be2cd97..581043a3d0 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -191,13 +191,7 @@ void on_new_message(const LLSD& msg)
     }
     else if("openconversations" == action)
     {
-        LLFloaterIMContainer * floaterIMContainer = LLFloaterIMContainer::getInstance();
-
-        if(floaterIMContainer)
-        {
-            floaterIMContainer->setVisible(TRUE);
-            floaterIMContainer->setFrontmost(TRUE);
-        }
+        LLFloaterReg::showInstance("im_container");
     }
 }
 
-- 
cgit v1.2.3


From d9ad20055330e0911a553af284359a5cf5711b7b Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Tue, 27 Nov 2012 17:55:50 +0200
Subject: CHUI-544 (Legacy name shows in conversation list for user that
 answers a voice call)

---
 indra/newview/llavataractions.cpp | 2 +-
 indra/newview/llvoicevivox.cpp    | 6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index f5d8998ce5..1969a0bc5f 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -215,7 +215,7 @@ void LLAvatarActions::endIM(const LLUUID& id)
 static void on_avatar_name_cache_start_call(const LLUUID& agent_id,
 											const LLAvatarName& av_name)
 {
-	std::string name = av_name.getCompleteName();
+	std::string name = av_name.mDisplayName;
 	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id, true);
 	if (session_id != LLUUID::null)
 	{
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 3a26f14772..37491e5b58 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -6200,10 +6200,8 @@ void LLVivoxVoiceClient::lookupName(const LLUUID &id)
 void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id,
 										   const LLAvatarName& av_name)
 {
-	// For Vivox, we use the legacy name because I'm uncertain whether or
-	// not their service can tolerate switching to Username or Display Name
-	std::string legacy_name = av_name.getLegacyName();
-	avatarNameResolved(agent_id, legacy_name);	
+	std::string display_name = av_name.mDisplayName;
+	avatarNameResolved(agent_id, display_name);
 }
 
 void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name)
-- 
cgit v1.2.3


From 3792a6aab8d8cf32fa82353fb7be1b895223e41b Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 28 Nov 2012 19:39:27 +0200
Subject: CHUI-546 FIXED Blank IM toast shown when a nearby chat toast is
 shown: Prosessing of the nearby chat was exluded from on_new_message()

---
 indra/newview/llimview.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 581043a3d0..e5dda7e8d8 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -171,8 +171,8 @@ void on_new_message(const LLSD& msg)
             return;
         }
 
-        // Skip toasting for system messages
-        if (participant_id.isNull())
+	    // Skip toasting for system messages and for nearby chat
+	    if (participant_id.isNull() || session_id.isNull())
         {
             return;
         }
-- 
cgit v1.2.3


From 80f8a465eb2885246b0a1daca66077ecd1dcc61d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 28 Nov 2012 11:35:59 -0800
Subject: CHUI-548: Now a p2p conversation is aligned with the nearby chat
 arrow. Just had to check for a p2p conversation type and then adjust then
 decrease the indentation. Also made LLFolderViewItem::drawOpenFolderArrow() a
 non-virtual function and adjusted code accordingly.

---
 indra/llui/llfolderviewitem.h          |  2 +-
 indra/newview/llconversationview.cpp   | 27 ++++++++++++---------------
 indra/newview/llconversationview.h     |  3 +--
 indra/newview/llfloaterimcontainer.cpp |  6 ++++++
 4 files changed, 20 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index c5d6d26e84..2e633a39e5 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -264,7 +264,7 @@ public:
 
 	//	virtual void handleDropped();
 	virtual void draw();
-	virtual void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
+	void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
     void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
     void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index e40d57c318..3aadc2986f 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -80,7 +80,8 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mSessionTitle(NULL),
 	mSpeakingIndicator(NULL),
 	mVoiceClientObserver(NULL),
-	mMinimizedMode(false)
+	mMinimizedMode(false),
+    mHasArrow(true)
 {
 	mFlashTimer = new LLFlashTimer();
 }
@@ -135,6 +136,7 @@ BOOL LLConversationViewSession::postBuild()
 				icon->setVisible(true);
 				icon->setValue(session->mOtherParticipantID);
 				mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID, true);
+                mHasArrow = false;
 			}
 			break;
 		}
@@ -183,11 +185,10 @@ void LLConversationViewSession::draw()
 	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
 
 	// we don't draw the open folder arrow in minimized mode
-	if (!mMinimizedMode)
+	if (mHasArrow && !mMinimizedMode)
 	{
 		// update the rotation angle of open folder arrow
 		updateLabelRotation();
-
 		drawOpenFolderArrow(default_params, sFgColor);
 	}
 
@@ -227,14 +228,18 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
 // virtual
 S32 LLConversationViewSession::arrange(S32* width, S32* height)
 {
-	S32 h_pad = getIndentation() + mArrowSize;
+    //LLFolderViewFolder::arrange computes value for getIndentation() function below
+    S32 arranged = LLFolderViewFolder::arrange(width, height);
+
+    S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation();
+	
 	LLRect rect(mMinimizedMode ? getLocalRect().mLeft : h_pad,
 				getLocalRect().mTop,
 				getLocalRect().mRight,
 				getLocalRect().mTop - getItemHeight());
 	mItemPanel->setShape(rect);
 
-	return LLFolderViewFolder::arrange(width, height);
+	return arranged;
 }
 
 // virtual
@@ -262,7 +267,8 @@ void LLConversationViewSession::toggleMinimizedMode(bool is_minimized)
 	// except for the icon which we display in minimized mode
 	getChild<LLView>("conversation_item_stack")->setVisible(!mMinimizedMode);
 
-	S32 h_pad = getIndentation() + mArrowSize;
+    S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation();
+
 	mItemPanel->translate(mMinimizedMode ? -h_pad : h_pad, 0);
 }
 
@@ -340,15 +346,6 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
 	}
 }
 
-void LLConversationViewSession::drawOpenFolderArrow(const LLFolderViewItem::Params& default_params, const LLUIColor& fg_color)
-{
-	LLConversationItem * itemp = dynamic_cast<LLConversationItem*>(getViewModelItem());
-	if (itemp && itemp->getType() != LLConversationItem::CONV_SESSION_1_ON_1)
-	{
-		LLFolderViewFolder::drawOpenFolderArrow(default_params, fg_color);
-	}
-}
-
 //
 // Implementation of conversations list participant (avatar) widgets
 //
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index acd7128b7d..c6cb502355 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -74,8 +74,6 @@ public:
 
 	/*virtual*/	bool isMinimized() { return mMinimizedMode; }
 
-	/*virtual*/ void drawOpenFolderArrow(const LLFolderViewItem::Params& default_params, const LLUIColor& fg_color);
-
 	void toggleMinimizedMode(bool is_minimized);
 
 	void setVisibleIfDetached(BOOL visible);
@@ -98,6 +96,7 @@ private:
 	LLFlashTimer*			mFlashTimer;
 
 	bool					mMinimizedMode;
+    bool                    mHasArrow;
 
 	LLVoiceClientStatusObserver* mVoiceClientObserver;
 	
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 016a7723b6..5fbbfd1283 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1383,6 +1383,12 @@ LLConversationViewSession* LLFloaterIMContainer::createConversationItemWidget(LL
 	params.tool_tip = params.name;
 	params.container = this;
 	
+    //Indentation for aligning the p2p converstation image with the nearby chat arrow
+    if(item->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+    {
+        params.folder_indentation = 3;
+    }
+
 	return LLUICtrlFactory::create<LLConversationViewSession>(params);
 }
 
-- 
cgit v1.2.3


From 45e8926f138a2b42c5054149d3a9f6f39df29247 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 28 Nov 2012 13:48:55 -0800
Subject: code cleanup: variables and functions were using the word 'minimized'
 to refer 'collapsed'. Renamed variables and functions to use the word
 'collapsed' instead of 'minimized'.

---
 indra/newview/llconversationview.cpp   | 16 ++++++++--------
 indra/newview/llconversationview.h     |  6 +++---
 indra/newview/llfloaterimcontainer.cpp |  4 ++--
 3 files changed, 13 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 3aadc2986f..1b1d61e6d6 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -80,7 +80,7 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mSessionTitle(NULL),
 	mSpeakingIndicator(NULL),
 	mVoiceClientObserver(NULL),
-	mMinimizedMode(false),
+	mCollapsedMode(false),
     mHasArrow(true)
 {
 	mFlashTimer = new LLFlashTimer();
@@ -185,7 +185,7 @@ void LLConversationViewSession::draw()
 	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
 
 	// we don't draw the open folder arrow in minimized mode
-	if (mHasArrow && !mMinimizedMode)
+	if (mHasArrow && !mCollapsedMode)
 	{
 		// update the rotation angle of open folder arrow
 		updateLabelRotation();
@@ -233,7 +233,7 @@ S32 LLConversationViewSession::arrange(S32* width, S32* height)
 
     S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation();
 	
-	LLRect rect(mMinimizedMode ? getLocalRect().mLeft : h_pad,
+	LLRect rect(mCollapsedMode ? getLocalRect().mLeft : h_pad,
 				getLocalRect().mTop,
 				getLocalRect().mRight,
 				getLocalRect().mTop - getItemHeight());
@@ -246,7 +246,7 @@ S32 LLConversationViewSession::arrange(S32* width, S32* height)
 void LLConversationViewSession::toggleOpen()
 {
 	// conversations should not be opened while in minimized mode
-	if (!mMinimizedMode)
+	if (!mCollapsedMode)
 	{
 		LLFolderViewFolder::toggleOpen();
 
@@ -259,17 +259,17 @@ void LLConversationViewSession::toggleOpen()
 	}
 }
 
-void LLConversationViewSession::toggleMinimizedMode(bool is_minimized)
+void LLConversationViewSession::toggleCollapsedMode(bool is_collapsed)
 {
-	mMinimizedMode = is_minimized;
+	mCollapsedMode = is_collapsed;
 
 	// hide the layout stack which contains all item's child widgets
 	// except for the icon which we display in minimized mode
-	getChild<LLView>("conversation_item_stack")->setVisible(!mMinimizedMode);
+	getChild<LLView>("conversation_item_stack")->setVisible(!mCollapsedMode);
 
     S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation();
 
-	mItemPanel->translate(mMinimizedMode ? -h_pad : h_pad, 0);
+	mItemPanel->translate(mCollapsedMode ? -h_pad : h_pad, 0);
 }
 
 void LLConversationViewSession::setVisibleIfDetached(BOOL visible)
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index c6cb502355..a6f408403b 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -72,9 +72,9 @@ public:
 
 	/*virtual*/ void toggleOpen();
 
-	/*virtual*/	bool isMinimized() { return mMinimizedMode; }
+	/*virtual*/	bool isCollapsed() { return mCollapsedMode; }
 
-	void toggleMinimizedMode(bool is_minimized);
+	void toggleCollapsedMode(bool is_collapsed);
 
 	void setVisibleIfDetached(BOOL visible);
 	LLConversationViewParticipant* findParticipant(const LLUUID& participant_id);
@@ -95,7 +95,7 @@ private:
 	LLOutputMonitorCtrl*	mSpeakingIndicator;
 	LLFlashTimer*			mFlashTimer;
 
-	bool					mMinimizedMode;
+	bool					mCollapsedMode;
     bool                    mHasArrow;
 
 	LLVoiceClientStatusObserver* mVoiceClientObserver;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 5fbbfd1283..a04b8d79d6 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -640,7 +640,7 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
 		if (widget)
 		{
-		    widget->toggleMinimizedMode(collapse);
+		    widget->toggleCollapsedMode(collapse);
 
 		    // force closing all open conversations when collapsing to minimized state
 		    if (collapse)
@@ -1320,7 +1320,7 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 	}
 
 	// set the widget to minimized mode if conversations pane is collapsed
-	widget->toggleMinimizedMode(mConversationsPane->isCollapsed());
+	widget->toggleCollapsedMode(mConversationsPane->isCollapsed());
 
     if (isWidgetSelected)
     {
-- 
cgit v1.2.3


From c8fceb426da13b2a5a47ee8d7b319ff3b15a1bb8 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 28 Nov 2012 14:51:39 -0800
Subject: CHUI-552 : Big clean up in nearby chat making it more consistent with
 LLFloaterIMSessionTab

---
 indra/newview/llfloaterimnearbychat.cpp | 71 +--------------------------------
 indra/newview/llfloaterimnearbychat.h   |  9 -----
 2 files changed, 2 insertions(+), 78 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 7002342c0b..7b97295703 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -95,7 +95,6 @@ LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd)
 {
     mIsP2PChat = false;
 	mIsNearbyChat = true;
-	setIsChrome(TRUE);
 	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
 	mSessionID = LLUUID();
 }
@@ -119,29 +118,10 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 	mInputEditor->setFocusReceivedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusReceived, this));
 	mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle"));
 
-//	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
-//	mOutputMonitor->setVisible(FALSE);
-
-	// Register for font change notifications
-//	LLViewerChat::setFontChangedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatFontChange, this, _1));
-
-	// title must be defined BEFORE call addConversationListItem() because
-	// it is used for show the item's name in the conversations list
+	// Title must be defined BEFORE call to addConversationListItem() because
+	// it is used to show the item's name in the conversations list
 	setTitle(LLTrans::getString("NearbyChatTitle"));
 
-	//for menu
-//	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-//	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
-//	enable_registrar.add("NearbyChat.Check", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
-//	registrar.add("NearbyChat.Action", boost::bind(&LLFloaterIMNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
-
-//	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-//	if(menu)
-//	{
-//		mPopupMenuHandle = menu->getHandle();
-//	}
-
 	// obsolete, but may be needed for backward compatibility?
 	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
 
@@ -168,43 +148,6 @@ void LLFloaterIMNearbyChat::refresh()
 	}
 }
 
-void LLFloaterIMNearbyChat::onNearbySpeakers()
-{
-	LLSD param;
-	param["people_panel_tab_name"] = "nearby_panel";
-	LLFloaterSidePanelContainer::showPanel("people", "panel_people", param);
-}
-
-void	LLFloaterIMNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
-{
-}
-
-bool	LLFloaterIMNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
-{
-	std::string str = userdata.asString();
-	if(str == "nearby_people")
-		onNearbySpeakers();
-	return false;
-}
-
-
-BOOL	LLFloaterIMNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	//fix for EXT-6625
-	//highlight NearbyChat history whenever mouseclick happen in NearbyChat
-	//setting focus to eidtor will force onFocusLost() call that in its turn will change
-	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
-
-	if(mChatHistory)
-	{
-		mChatHistory->setFocus(TRUE);
-	}
-
-	BOOL handled = LLPanel::handleMouseDown(x, y, mask);
-	setFocus(handled);
-	return handled;
-}
-
 void LLFloaterIMNearbyChat::reloadMessages()
 {
 	mChatHistory->clear();
@@ -641,16 +584,6 @@ void LLFloaterIMNearbyChat::displaySpeakingIndicator()
 			break;
 		}
 	}
-
-	if (!id.isNull())
-	{
-		//mOutputMonitor->setVisible(TRUE);
-		//mOutputMonitor->setSpeakerId(id);
-	}
-	else
-	{
-		//mOutputMonitor->setVisible(FALSE);
-	}
 }
 
 void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index 5ed639136b..a38824dc78 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -59,21 +59,17 @@ public:
     void reloadMessages();
 	void removeScreenChat();
 
-	void addToHost();
 	void show();
 	bool isChatVisible() const;
 
 	/** @param archive true - to save a message to the chat history log */
 	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());
-	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);
-	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
 
 	LLChatEntry* getChatBox() { return mInputEditor; }
 
 	std::string getCurrentChat();
 
 	virtual BOOL handleKeyHere( KEY key, MASK mask );
-	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 
 	static void startChat(const char* line);
 	static void stopChat();
@@ -112,14 +108,9 @@ protected:
 	S32 mExpandedHeight;
 
 private:
-
-	void	onNearbySpeakers	();
-
 	/*virtual*/ void refresh();
 
-//	LLHandle<LLView>	mPopupMenuHandle;
 	std::vector<LLChat> mMessageArchive;
-
 };
 
 #endif // LL_LLFLOATERIMNEARBYCHAT_H
-- 
cgit v1.2.3


From 15157ecb095838f402edb750b87ea0bdb9fb56f7 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 29 Nov 2012 03:27:45 +0200
Subject: CHUI-553 FIXED Remove the conversation chiclet

---
 indra/newview/llchiclet.cpp                        |  98 ---------------------
 indra/newview/llchiclet.h                          |  48 ----------
 indra/newview/llchicletbar.cpp                     |   1 -
 indra/newview/llsyswellwindow.cpp                  |  38 +++-----
 .../default/textures/bottomtray/Unread_IM.png      | Bin 458 -> 0 bytes
 indra/newview/skins/default/textures/textures.xml  |   1 -
 .../skins/default/xui/en/menu_im_well_button.xml   |  16 ----
 .../skins/default/xui/en/panel_chiclet_bar.xml     |  48 ----------
 8 files changed, 12 insertions(+), 238 deletions(-)
 delete mode 100644 indra/newview/skins/default/textures/bottomtray/Unread_IM.png
 delete mode 100644 indra/newview/skins/default/xui/en/menu_im_well_button.xml

(limited to 'indra')

diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index d6860640b7..a665aeb6bd 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -52,7 +52,6 @@
 #include "llsyswellwindow.h"
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
-static LLDefaultChildRegistry::Register<LLIMWellChiclet> t2_0("chiclet_im_well");
 static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
 static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
 static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
@@ -176,103 +175,6 @@ BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
-/************************************************************************/
-/*               LLIMWellChiclet implementation                         */
-/************************************************************************/
-LLIMWellChiclet::LLIMWellChiclet(const Params& p)
-: LLSysWellChiclet(p)
-{
-	LLIMModel::instance().addNewMsgCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1));
-	LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1));
-
-	LLIMMgr::getInstance()->addSessionObserver(this);
-
-	LLIMWellWindow::getInstance()->setSysWellChiclet(this);
-}
-
-LLIMWellChiclet::~LLIMWellChiclet()
-{
-	LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
-	if (im_well_window)
-	{
-		im_well_window->setSysWellChiclet(NULL);
-	}
-
-	LLIMMgr::getInstance()->removeSessionObserver(this);
-}
-
-void LLIMWellChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string action = user_data.asString();
-	if("close all" == action)
-	{
-		LLIMWellWindow::getInstance()->closeAll();
-	}
-}
-
-bool LLIMWellChiclet::enableMenuItem(const LLSD& user_data)
-{
-	std::string item = user_data.asString();
-	if (item == "can close all")
-	{
-		return !LLIMWellWindow::getInstance()->isWindowEmpty();
-	}
-	return true;
-}
-
-void LLIMWellChiclet::createMenu()
-{
-	if(mContextMenu)
-	{
-		llwarns << "Menu already exists" << llendl;
-		return;
-	}
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMWellChicletMenu.Action",
-		boost::bind(&LLIMWellChiclet::onMenuItemClicked, this, _2));
-
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-	enable_registrar.add("IMWellChicletMenu.EnableItem",
-		boost::bind(&LLIMWellChiclet::enableMenuItem, this, _2));
-
-	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
-		("menu_im_well_button.xml",
-		 LLMenuGL::sMenuContainer,
-		 LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
-{
-	// The singleton class LLChicletBar instance might be already deleted
-	// so don't create a new one.
-	if (!LLChicletBar::instanceExists())
-	{
-		return;
-	}
-
-	const LLUUID& session_id = session_data["session_id"];
-	const S32 counter = LLChicletBar::getInstance()->getTotalUnreadIMCount();
-	const bool im_not_visible = !LLFloaterReg::instanceVisible("im_container")
-		&& !LLFloaterReg::instanceVisible("impanel", session_id);
-
-	setNewMessagesState(counter > mCounter	&& im_not_visible);
-
-	// we have to flash to 'Lit' state each time new unread message is coming.
-	if (counter > mCounter && im_not_visible)
-	{
-		mFlashToLitTimer->startFlashing();
-	}
-	else if (counter == 0)
-	{
-		// if notification is resolved while well is flashing it can leave in the 'Lit' state
-		// when flashing finishes itself. Let break flashing here.
-		mFlashToLitTimer->stopFlashing();
-	}
-
-	setCounter(counter);
-}
-
 /************************************************************************/
 /*               LLNotificationChiclet implementation                   */
 /************************************************************************/
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 79ffad92ef..7f72c7f9e2 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -865,54 +865,6 @@ protected:
 	LLContextMenu* mContextMenu;
 };
 
-/**
- * Class represented a chiclet for IM Well Icon.
- *
- * It displays a count of unread messages from other participants in all IM sessions.
- */
-class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
-{
-	friend class LLUICtrlFactory;
-public:
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) {}
-    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
-	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
-	/*virtual*/ void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
-	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
-
-	~LLIMWellChiclet();
-protected:
-	LLIMWellChiclet(const Params& p);
-
-	/**
-	 * Processes clicks on chiclet popup menu.
-	 */
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/**
-	 * Enables chiclet menu items.
-	 */
-	bool enableMenuItem(const LLSD& user_data);
-
-	/**
-	 * Creates menu.
-	 */
-	/*virtual*/ void createMenu();
-
-	/**
-	 * Handles changes in a session (message was added, messages were read, etc.)
-	 *
-	 * It get total count of unread messages from a LLIMMgr in all opened sessions and display it.
-	 *
-	 * @param[in] session_data contains session related data, is not used now
-	 *		["session_id"] - id of an appropriate session
-	 *		["participant_unread"] - count of unread messages from "real" participants.
-	 *
-	 * @see LLIMMgr::getNumberOfUnreadParticipantMessages()
-	 */
-	void messageCountChanged(const LLSD& session_data);
-};
-
 class LLNotificationChiclet : public LLSysWellChiclet
 {
 	LOG_CLASS(LLNotificationChiclet);
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index c66ae1cdd0..cfcde64e7b 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -158,7 +158,6 @@ BOOL LLChicletBar::postBuild()
 	mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
 	mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
 
-	showWellButton("im_well", !LLIMWellWindow::getInstance()->isWindowEmpty());
 	showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
 
 	LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 7c000f2dd0..3605129d48 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -98,8 +98,10 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
 void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet) 
 { 
 	mSysWellChiclet = chiclet;
-	if(mSysWellChiclet)
-		mSysWellChiclet->updateWidget(isWindowEmpty()); 
+	if(NULL != mSysWellChiclet)
+	{
+		mSysWellChiclet->updateWidget(isWindowEmpty());
+	}
 }
 //---------------------------------------------------------------------------------
 LLSysWellWindow::~LLSysWellWindow()
@@ -111,7 +113,10 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
 {
 	if(mMessageList->removeItemByValue(id))
 	{
-		mSysWellChiclet->updateWidget(isWindowEmpty());
+		if (NULL != mSysWellChiclet)
+		{
+			mSysWellChiclet->updateWidget(isWindowEmpty());
+		}
 		reshapeWindow();
 	}
 	else
@@ -685,11 +690,7 @@ void LLIMWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
 							   const std::string& name, const LLUUID& otherParticipantId)
 {
 	RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId);
-	if (mMessageList->addItem(item, sessionId))
-	{
-		mSysWellChiclet->updateWidget(isWindowEmpty());
-	}
-	else
+	if (!mMessageList->addItem(item, sessionId))
 	{
 		llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId
 			<< ", name: " << name
@@ -710,11 +711,7 @@ void LLIMWellWindow::delIMRow(const LLUUID& sessionId)
 	//But I didn't find why this happen..
 	gFocusMgr.clearLastFocusForGroup(this);
 
-	if (mMessageList->removeItemByValue(sessionId))
-	{
-		mSysWellChiclet->updateWidget(isWindowEmpty());
-	}
-	else
+	if (!mMessageList->removeItemByValue(sessionId))
 	{
 		llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId
 			<< llendl;
@@ -740,11 +737,7 @@ void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_messag
 	if (mMessageList->getItemByValue(notification_id) == NULL)
 	{
 		ObjectRowPanel* item = new ObjectRowPanel(notification_id, new_message);
-		if (mMessageList->addItem(item, notification_id))
-		{
-			mSysWellChiclet->updateWidget(isWindowEmpty());
-		}
-		else
+		if (!mMessageList->addItem(item, notification_id))
 		{
 			llwarns << "Unable to add Object Row into the list, notificationID: " << notification_id << llendl;
 			item->die();
@@ -755,14 +748,7 @@ void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_messag
 
 void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
 {
-	if (mMessageList->removeItemByValue(notification_id))
-	{
-		if (mSysWellChiclet)
-		{
-			mSysWellChiclet->updateWidget(isWindowEmpty());
-		}
-	}
-	else
+	if (!mMessageList->removeItemByValue(notification_id))
 	{
 		llwarns << "Unable to remove Object Row from the list, notificationID: " << notification_id << llendl;
 	}
diff --git a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png b/indra/newview/skins/default/textures/bottomtray/Unread_IM.png
deleted file mode 100644
index 5c0c85b864..0000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a124041565..8d9fa52309 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -642,7 +642,6 @@ with the same filename but different name
   <texture name="TrashItem_Press" file_name="icons/TrashItem_Press.png" preload="false" />
 
   <texture name="Unread_Chiclet" file_name="bottomtray/Unread_Chiclet.png" preload="false" />
-  <texture name="Unread_IM" file_name="bottomtray/Unread_IM.png" preload="false" />
 
   <texture name="UpArrow_Off" file_name="icons/UpArrow_Off.png" preload="false" />
 
diff --git a/indra/newview/skins/default/xui/en/menu_im_well_button.xml b/indra/newview/skins/default/xui/en/menu_im_well_button.xml
deleted file mode 100644
index f8dfba91ff..0000000000
--- a/indra/newview/skins/default/xui/en/menu_im_well_button.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<context_menu
- layout="topleft"
- name="IM Well Button Context Menu">
-    <menu_item_call
-     label="Close All"
-     layout="topleft"
-     name="Close All">
-        <menu_item_call.on_click
-         function="IMWellChicletMenu.Action"
-         parameter="close all" />
-        <menu_item_call.on_enable
-         function="IMWellChicletMenu.EnableItem"
-         parameter="can close all" />
-    </menu_item_call>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
index ff0146490b..fc321fdd23 100644
--- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
@@ -80,54 +80,6 @@
     <layout_panel auto_resize="false"
                       width="4"
                       min_width="4"/>
-    <layout_panel
-         auto_resize="false"
-         follows="right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         min_width="37"
-         name="im_well_panel"
-         top="0"
-         width="37">
-      <chiclet_im_well
-             follows="right"
-             height="28"
-             layout="topleft"
-             left="0"
-             max_displayed_count="99"
-             name="im_well"
-             top="0"
-             width="35">
-        <!--
-Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button
-xml attribute           Description
-image_unselected        "Unlit" - there are no new messages
-image_selected          "Unlit" + "Selected" - there are no new messages and the Well is open
-image_pressed           "Lit" - there are new messages
-image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well is open
-             -->
-        <button
-                 auto_resize="false"
-                 follows="right"
-                 halign="center"
-                 height="23"
-                 image_overlay="Unread_IM"
-                 image_overlay_alignment="center"
-                 image_pressed="WellButton_Lit"
-                 image_pressed_selected="WellButton_Lit_Selected"
-                 image_selected="PushButton_Press"
-                 label_color="Black"
-                 left="0"
-                 name="Unread IM messages"
-                 tool_tip="Conversations"
-                 width="34">
-          <init_callback
-                     function="Button.SetDockableFloaterToggle"
-                     parameter="im_well_window" />
-        </button>
-      </chiclet_im_well>
-    </layout_panel>
     <layout_panel
          auto_resize="false"
          follows="right"
-- 
cgit v1.2.3


From 4da50b21d5dc49cf6b39f7c29b44c1bb869a13cd Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 28 Nov 2012 19:40:06 -0800
Subject: CHUI-552 : Fixed : Do not update the avatars sorting when updating
 the speaking indicator, let the conversation list do that.

---
 indra/newview/llfloaterimnearbychat.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 7b97295703..a20fce876c 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -572,7 +572,7 @@ void LLFloaterIMNearbyChat::displaySpeakingIndicator()
 	LLUUID id;
 
 	id.setNull();
-	mSpeakerMgr->update(TRUE);
+	mSpeakerMgr->update(FALSE);
 	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
 
 	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
-- 
cgit v1.2.3


From 611797543a917f1596be73e9e79974578748086e Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 29 Nov 2012 15:03:35 -0800
Subject: CHUI-489: Removed the 'Group Messages' checkbox. This was a design
 change in the spec.

---
 indra/newview/app_settings/settings.xml                       | 11 -----------
 indra/newview/skins/default/xui/en/panel_preferences_chat.xml | 11 +----------
 2 files changed, 1 insertion(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 253ac3b836..ece711a128 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6867,17 +6867,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>PlaySoundGroupChatMessages</key>
-    <map>
-      <key>Comment</key>
-      <string>Plays a sound when have a group chat message.</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>  
     <key>PlaySoundIncomingVoiceCall</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 0c94b6b223..37bfbae991 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -341,22 +341,13 @@
         top_pad="6"
         name="incoming_voice_call"
         width="150" />
-    <check_box
-        enabled="false"
-        control_name="PlaySoundGroupChatMessages"
-        height="16"
-        label="Group chat messages"
-        layout="topleft"
-        top_pad="6"
-        name="group_chat_messages"
-        width="150" />
     <check_box
         control_name="PlaySoundTeleportOffer"
         height="16"
         label="Teleport offer"
         layout="topleft"
         left_pad="35"
-        top_pad="-59"
+        top_pad="-38"
         name="teleport_offer"
         width="150" />
     <check_box
-- 
cgit v1.2.3


From 5238a39b5458a34b727ca842c456db47ef13d1b7 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 29 Nov 2012 20:33:17 -0800
Subject: CHUI-552 : Fixed : Filter out participant creation with the same id
 than the session id

---
 indra/newview/llparticipantlist.cpp | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 9f89b5f809..6c838f8a45 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -366,8 +366,11 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
 
 void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 {
-	// Do not add if already in there or excluded for some reason
-	if (findParticipant(avatar_id)) return;
+	// Do not add if already in there, is the session id (hence not an avatar) or excluded for some reason
+	if (findParticipant(avatar_id) || (avatar_id == mUUID))
+	{
+		return;
+	}
 
 	bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id);
 
@@ -391,7 +394,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 
 	// *TODO : Need to update the online/offline status of the participant
 	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
-
+	
 	// Add the participant model to the session's children list
 	addParticipant(participant);
 
@@ -413,12 +416,12 @@ void LLParticipantList::adjustParticipant(const LLUUID& speaker_id)
 bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
 {
 	/**
-	 * We need to filter speaking objects. These objects shouldn't appear in the list
+	 * We need to filter speaking objects. These objects shouldn't appear in the list.
 	 * @see LLFloaterChat::addChat() in llviewermessage.cpp to get detailed call hierarchy
 	 */
 	const LLUUID& speaker_id = event->getValue().asUUID();
 	LLPointer<LLSpeaker> speaker = mParent.mSpeakerMgr->findSpeaker(speaker_id);
-	if(speaker.isNull() || speaker->mType == LLSpeaker::SPEAKER_OBJECT)
+	if (speaker.isNull() || (speaker->mType == LLSpeaker::SPEAKER_OBJECT))
 	{
 		return false;
 	}
-- 
cgit v1.2.3


From 47a1a0468156153155f5e9b6c720b9b6cb62c263 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 30 Nov 2012 14:12:46 -0800
Subject: CHUI-570 : Fixed : Take the typing state when updating the title,
 also make refresh update less frequent (perf).

---
 indra/newview/llfloaterimsession.cpp    | 26 +++++++++++---------------
 indra/newview/llfloaterimsession.h      |  1 -
 indra/newview/llfloaterimsessiontab.cpp |  2 +-
 3 files changed, 12 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index e1dc5b91d0..0162b0ecd0 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -66,7 +66,6 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
   : LLFloaterIMSessionTab(session_id),
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
-	mSavedTitle(),
 	mTypingStart(),
 	mShouldSendTypingState(false),
 	mMeTyping(false),
@@ -504,9 +503,13 @@ void LLFloaterIMSession::onVoiceChannelStateChanged(
 
 void LLFloaterIMSession::updateSessionName(const std::string& name)
 {
-	LLFloaterIMSessionTab::updateSessionName(name);
-	setTitle(name);	
-	mTypingStart.setArg("[NAME]", name);
+	if (!name.empty())
+	{
+		LLFloaterIMSessionTab::updateSessionName(name);
+		mTypingStart.setArg("[NAME]", name);
+		setTitle (mOtherTyping ? mTypingStart.getString() : name);
+	}
+	llinfos << "Merov debug : updateSessionName, title = " << name << ", typing title = " << mTypingStart.getString() << llendl;
 }
 
 //static
@@ -1095,14 +1098,10 @@ BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
 void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info)
 {
 	// We may have lost a "stop-typing" packet, don't add it twice
-	if ( im_info && !mOtherTyping )
+	if (im_info && !mOtherTyping)
 	{
 		mOtherTyping = true;
 
-		// Save and set new title
-		mSavedTitle = getTitle();
-		setTitle (mTypingStart);
-
 		// Update speaker
 		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
 		if ( speaker_mgr )
@@ -1114,18 +1113,15 @@ void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info)
 
 void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info)
 {
-	if ( mOtherTyping )
+	if (mOtherTyping)
 	{
 		mOtherTyping = false;
 
-		// Revert the title to saved one
-		setTitle(mSavedTitle);
-
-		if ( im_info )
+		if (im_info)
 		{
 			// Update speaker
 			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-			if ( speaker_mgr )
+			if (speaker_mgr)
 			{
 				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
 			}
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index f4ec2d457d..72a320041f 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -174,7 +174,6 @@ private:
 	LLUUID mOtherParticipantUUID;
 	bool mPositioned;
 
-	std::string mSavedTitle;
 	LLUIString mTypingStart;
 	bool mMeTyping;
 	bool mOtherTyping;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 6e58a66bcd..d43381041b 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -43,7 +43,7 @@
 #include "lltoolbarview.h"
 #include "llfloaterimnearbychat.h"
 
-const F32 REFRESH_INTERVAL = 0.2f;
+const F32 REFRESH_INTERVAL = 1.0f;
 
 LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
   : LLTransientDockableFloater(NULL, true, session_id)
-- 
cgit v1.2.3


From eab0ec402e7ea1eb151408b913c6f4e14c9c8cbe Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 30 Nov 2012 14:34:23 -0800
Subject: CHUI-570 : Delete a stray debug comment log.

---
 indra/newview/llfloaterimsession.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 0162b0ecd0..212b0df712 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -509,7 +509,6 @@ void LLFloaterIMSession::updateSessionName(const std::string& name)
 		mTypingStart.setArg("[NAME]", name);
 		setTitle (mOtherTyping ? mTypingStart.getString() : name);
 	}
-	llinfos << "Merov debug : updateSessionName, title = " << name << ", typing title = " << mTypingStart.getString() << llendl;
 }
 
 //static
-- 
cgit v1.2.3


From e53577c32db1a8d5e7e15cb33357c68da87acc44 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 30 Nov 2012 17:12:52 -0800
Subject: CHUI-404, CHUI-406 : Fixed : update ad-hoc conversation when
 participant logs off, update title of ad-hoc and P2P to be consistent with
 torn off and input field

---
 indra/newview/llconversationmodel.cpp | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 0837a49095..ba92022673 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -27,6 +27,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llagent.h"
 #include "llavatarnamecache.h"
 #include "llavataractions.h"
 #include "llevents.h"
@@ -161,8 +162,8 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
 
 void LLConversationItemSession::updateParticipantName(LLConversationItemParticipant* participant)
 {
-	// We modify the session name only in the case of an ad-hoc session, exit otherwise (nothing to do)
-	if (getType() != CONV_SESSION_AD_HOC)
+	// We modify the session name only in the case of an ad-hoc session or P2P session, exit otherwise (nothing to do)
+	if ((getType() != CONV_SESSION_AD_HOC) && (getType() != CONV_SESSION_1_ON_1))
 	{
 		return;
 	}
@@ -171,26 +172,26 @@ void LLConversationItemSession::updateParticipantName(LLConversationItemParticip
 	{
 		return;
 	}
-	// Build a string containing the participants names and check if ready for display (we don't want "(waiting)" in there)
-	bool all_names_resolved = true;
+	// Build a string containing the participants names (minus own agent) and check if ready for display (we don't want "(waiting)" in there)
+	// Note: we don't bind ourselves to the LLAvatarNameCache event as updateParticipantName() is called by
+	// onAvatarNameCache() which is itself attached to the same event.
 	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
 	child_list_t::iterator iter = mChildren.begin();
 	while (iter != mChildren.end())
 	{
 		LLConversationItemParticipant* current_participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
-		temp_uuids.push_back(current_participant->getUUID());
-		LLAvatarName av_name;
-        if (!LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
-        {
-			// If the name is not in the cache yet, bail out
-			// Note: we don't bind ourselves to the LLAvatarNameCache event as we are called by
-			// onAvatarNameCache() which is itself attached to the same event.
-			all_names_resolved = false;
-			break;
+		// Add the avatar uuid to the list (except if it's the own agent uuid)
+		if (current_participant->getUUID() != gAgentID)
+		{
+			LLAvatarName av_name;
+			if (LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
+			{
+				temp_uuids.push_back(current_participant->getUUID());
+			}
 		}
 		iter++;
 	}
-	if (all_names_resolved)
+	if (temp_uuids.size() != 0)
 	{
 		std::string new_session_name;
 		LLAvatarActions::buildResidentsString(temp_uuids, new_session_name);
@@ -203,6 +204,7 @@ void LLConversationItemSession::removeParticipant(LLConversationItemParticipant*
 {
 	removeChild(participant);
 	mNeedsRefresh = true;
+	updateParticipantName(participant);
 	postEvent("remove_participant", this, participant);
 }
 
-- 
cgit v1.2.3


From d48357f54765f84a35b73bbf28e88b978bcb5013 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 30 Nov 2012 19:07:58 -0800
Subject: CHUI-406 : Fixed again : Update of the P2P session name when not
 initiating a session was wrong. Add getting the participant name from the
 session.

---
 indra/newview/llconversationmodel.cpp | 39 +++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index ba92022673..728b1a3f4c 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -31,6 +31,7 @@
 #include "llavatarnamecache.h"
 #include "llavataractions.h"
 #include "llevents.h"
+#include "llfloaterimsession.h"
 #include "llsdutil.h"
 #include "llconversationmodel.h"
 #include "llimview.h" //For LLIMModel
@@ -162,8 +163,9 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
 
 void LLConversationItemSession::updateParticipantName(LLConversationItemParticipant* participant)
 {
+	EConversationType conversation_type = getType();
 	// We modify the session name only in the case of an ad-hoc session or P2P session, exit otherwise (nothing to do)
-	if ((getType() != CONV_SESSION_AD_HOC) && (getType() != CONV_SESSION_1_ON_1))
+	if ((conversation_type != CONV_SESSION_AD_HOC) && (conversation_type != CONV_SESSION_1_ON_1))
 	{
 		return;
 	}
@@ -172,24 +174,35 @@ void LLConversationItemSession::updateParticipantName(LLConversationItemParticip
 	{
 		return;
 	}
-	// Build a string containing the participants names (minus own agent) and check if ready for display (we don't want "(waiting)" in there)
-	// Note: we don't bind ourselves to the LLAvatarNameCache event as updateParticipantName() is called by
-	// onAvatarNameCache() which is itself attached to the same event.
 	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
-	child_list_t::iterator iter = mChildren.begin();
-	while (iter != mChildren.end())
+	if (conversation_type == CONV_SESSION_AD_HOC)
 	{
-		LLConversationItemParticipant* current_participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
-		// Add the avatar uuid to the list (except if it's the own agent uuid)
-		if (current_participant->getUUID() != gAgentID)
+		// Build a string containing the participants UUIDs (minus own agent) and check if ready for display (we don't want "(waiting)" in there)
+		// Note: we don't bind ourselves to the LLAvatarNameCache event as updateParticipantName() is called by
+		// onAvatarNameCache() which is itself attached to the same event.
+		child_list_t::iterator iter = mChildren.begin();
+		while (iter != mChildren.end())
 		{
-			LLAvatarName av_name;
-			if (LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
+			LLConversationItemParticipant* current_participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+			// Add the avatar uuid to the list (except if it's the own agent uuid)
+			if (current_participant->getUUID() != gAgentID)
 			{
-				temp_uuids.push_back(current_participant->getUUID());
+				LLAvatarName av_name;
+				if (LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
+				{
+					temp_uuids.push_back(current_participant->getUUID());
+				}
 			}
+			iter++;
 		}
-		iter++;
+	}
+	else if (conversation_type == CONV_SESSION_1_ON_1)
+	{
+		// In the case of a P2P conversersation, we need to grab the name of the other participant in the session instance itself
+		// as we do not create participants for such a session.
+        LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(mUUID);
+        LLUUID participantID = conversationFloater->getOtherParticipantUUID();
+        temp_uuids.push_back(participantID);
 	}
 	if (temp_uuids.size() != 0)
 	{
-- 
cgit v1.2.3


From 168c1d5a85e8f4f4975ee4501e3dbb8f10d85334 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 3 Dec 2012 15:37:11 +0200
Subject: CHUI-432 (User that is muted in group call does not show as muted to
 other users in conversation list)

---
 indra/newview/llconversationview.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 1b1d61e6d6..7988cd1a03 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -448,6 +448,7 @@ void LLConversationViewParticipant::draw()
 
     drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
     drawLabel(font, text_left, y, color, right_x);
+	refresh();
 
     LLView::draw();
 }
-- 
cgit v1.2.3


From f888a3fd00ca32275ab2da6437cb011b3ab78f89 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 3 Dec 2012 16:21:48 +0200
Subject: CHUI-556 (Tooltip on call button incorrect when call is active)

---
 indra/newview/llfloaterimsessiontab.cpp                   | 7 ++++++-
 indra/newview/skins/default/xui/en/floater_im_session.xml | 6 ++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index d43381041b..08c2b951df 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -691,8 +691,13 @@ void LLFloaterIMSessionTab::processChatHistoryStyleUpdate()
 
 void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)
 {
-	getChild<LLButton>("voice_call_btn")->setImageOverlay(
+	LLButton* voiceButton = getChild<LLButton>("voice_call_btn");
+	voiceButton->setImageOverlay(
 			callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
+
+	voiceButton->setToolTip(
+			callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip"));
+
     enableDisableCallBtn();
 
 }
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 1d74f1bc25..faf54774f6 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -43,6 +43,12 @@
      <floater.string
      name="tooltip_to_main_window"
      value="Move this conversation back to main window"/>
+  <floater.string
+     name="start_call_button_tooltip"
+     value="Open voice connection"/>
+  <floater.string
+     name="end_call_button_tooltip"
+     value="Close voice connection"/>
     <view
         follows="all"
         layout="topleft"
-- 
cgit v1.2.3


From 1ce49f764fa00406088f7bcd7623603baedd5fe8 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 3 Dec 2012 19:20:11 +0200
Subject: CHUI-532 FIXED (Viewer crash when user in conversation is removed
 from participant list because they logged out or teleported away) delayed
 destroy of the timer

---
 indra/llui/llbutton.cpp              | 2 +-
 indra/llui/llflashtimer.cpp          | 9 ++++++++-
 indra/llui/llflashtimer.h            | 6 ++++++
 indra/newview/llconversationview.cpp | 2 +-
 4 files changed, 16 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 97547208ec..f82cdc64a9 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -286,7 +286,7 @@ LLButton::~LLButton()
 
 	if (mFlashingTimer)
 	{
-		delete mFlashingTimer;
+		mFlashingTimer->unset();
 	}
 }
 
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
index de7a4ab265..e49628acd5 100644
--- a/indra/llui/llflashtimer.cpp
+++ b/indra/llui/llflashtimer.cpp
@@ -35,6 +35,7 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 		, mCurrentTickCount(0)
         , mIsFlashingInProgress(false)
         , mIsCurrentlyHighlighted(false)
+        , mUnset(false)
 {
 	mEventTimer.stop();
 
@@ -48,6 +49,12 @@ LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
 	}
 }
 
+void LLFlashTimer::unset()
+{
+	mUnset = true;
+	mCallback = NULL;
+}
+
 BOOL LLFlashTimer::tick()
 {
 	mIsCurrentlyHighlighted = !mIsCurrentlyHighlighted;
@@ -62,7 +69,7 @@ BOOL LLFlashTimer::tick()
 		stopFlashing();
 	}
 
-	return FALSE;
+	return mUnset;
 }
 
 void LLFlashTimer::startFlashing()
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
index 5c8860b097..c60f99a8ea 100644
--- a/indra/llui/llflashtimer.h
+++ b/indra/llui/llflashtimer.h
@@ -52,6 +52,11 @@ public:
 
 	bool isFlashingInProgress();
 	bool isCurrentlyHighlighted();
+	/*
+	 * Use this instead of deleting this object.
+	 * The next call to tick() will return true and that will destroy this object.
+	 */
+	void unset();
 
 private:
 	callback_t		mCallback;
@@ -62,6 +67,7 @@ private:
 	S32 mCurrentTickCount;
 	bool mIsCurrentlyHighlighted;
 	bool mIsFlashingInProgress;
+	bool mUnset;
 };
 
 #endif /* LL_FLASHTIMER_H */
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 1b1d61e6d6..40900dce54 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -95,7 +95,7 @@ LLConversationViewSession::~LLConversationViewSession()
 		LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
 	}
 
-	delete mFlashTimer;
+	mFlashTimer->unset();
 }
 
 bool LLConversationViewSession::isHighlightAllowed()
-- 
cgit v1.2.3


From 2ee6bcab371a08791bccad3a4fa072c1d60cd6c9 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 3 Dec 2012 16:19:46 -0800
Subject: CHUI-571: Now when the 'Chat Preference' is set to 'Open
 Conversations window' the conversation line item with flash. The only time it
 does not flash is when the the conversation line item is already focused.
 Also fixed various focusing bugs when navigating between conversations and
 participants.

---
 indra/llui/llfolderviewitem.cpp                |  7 ++++++-
 indra/newview/llconversationview.cpp           | 18 ++++++++++++++----
 indra/newview/llfloaterimcontainer.cpp         | 26 +++++++++++++++++---------
 indra/newview/llfloaterimnearbychathandler.cpp |  5 -----
 indra/newview/llfloaterimsessiontab.cpp        |  2 +-
 indra/newview/llimview.cpp                     |  6 ++++++
 6 files changed, 44 insertions(+), 20 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 261f53d6b6..9b54a7a467 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -501,7 +501,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
 	// No handler needed for focus lost since this class has no
 	// state that depends on it.
 	gFocusMgr.setMouseCapture( this );
-
+    
 	if (!mIsSelected)
 	{
 		if(mask & MASK_CONTROL)
@@ -518,6 +518,11 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
 		}
 		make_ui_sound("UISndClick");
 	}
+    //Just re-select the item since it is clicked without ctrl or shift
+    else if(!(mask & (MASK_CONTROL | MASK_SHIFT)))
+    {
+        getRoot()->setSelection(this, FALSE);
+    }
 	else
 	{
 		mSelectPending = TRUE;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 1b1d61e6d6..a696fbdb47 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -218,9 +218,15 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
 {
 	LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
     LLUUID session_id = item? item->getUUID() : LLUUID();
+    //Will try to select a child node and then itself (if a child was not selected)
     BOOL result = LLFolderViewFolder::handleMouseDown(x, y, mask);
-	(LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
-    		selectConversationPair(session_id, false);
+
+    //This node (conversation) was selected and a child (participant) was not
+    if(result && getRoot()->getCurSelectedItem() == this)
+    {
+        (LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
+            selectConversationPair(session_id, false);
+    }
 
 	return result;
 }
@@ -548,8 +554,12 @@ BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
 	}
     LLUUID session_id = item? item->getUUID() : LLUUID();
     BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask);
-    (LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
-        		selectConversationPair(session_id, false);
+
+    if(result)
+    {
+        (LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
+            selectConversationPair(session_id, false);
+    }
 
 	return result;
 }
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index a04b8d79d6..3a80491dae 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1165,21 +1165,16 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
     selectConversation(session_id);    
 }
 
-// Will select only the conversation item
 void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
 {
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
-	if (widget)
-	{
-		(widget->getRoot())->setSelection(widget, FALSE, FALSE);
+    selectConversationPair(session_id, true);
 	}
-}
-
 
 // Synchronous select the conversation item and the conversation floater
 BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
 {
     BOOL handled = TRUE;
+    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
     /* widget processing */
     if (select_widget)
@@ -1198,7 +1193,7 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
         // Store the active session
         setSelectedSession(session_id);
 
-		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+		
 
 		if (session_floater->getHost())
 		{
@@ -1207,13 +1202,13 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 			// Switch to the conversation floater that is being selected
 			selectFloater(session_floater);
 		}
+    }
 
 		// Set the focus on the selected floater
 		if (!session_floater->hasFocus())
 		{
 			session_floater->setFocus(TRUE);
 		}
-    }
 
     return handled;
 }
@@ -1627,13 +1622,26 @@ void LLFloaterIMContainer::reSelectConversation()
 
 void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
 {
+    //Finds the conversation line item to flash using the session_id
 	LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id));
+    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+
 	if (widget)
 	{
+        //Start flash
 		if (is_flashes)
 		{
+            //Only flash when conversation is not active
+            if(session_floater
+                && (!session_floater->isInVisibleChain()) //conversation floater not displayed
+                    || 
+                    (session_floater->isInVisibleChain() && session_floater->hasFocus() == false)) //conversation floater is displayed but doesn't have focus
+                
+            {
 			widget->getFlashTimer()->startFlashing();
 		}
+		}
+        //Stop flash
 		else
 		{
 			widget->getFlashTimer()->stopFlashing();
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index d9c461e836..903c903381 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -619,11 +619,6 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
             chat["message"] = toast_msg;
             channel->addChat(chat);	
         }
-        //Will show Conversations floater when chat preference is set
-        else if(gSavedSettings.getString("NotificationNearbyChatOptions") == "openconversations")
-        {
-            LLFloaterReg::showInstance("im_container");
-        }
 
 	}
 }
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 6e58a66bcd..efc7be6dd6 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -306,7 +306,7 @@ void LLFloaterIMSessionTab::onFocusReceived()
 	LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
 	if (container)
 	{
-		container->selectConversationPair(mSessionID, true);
+		container->selectConversationPair(mSessionID, ! getHost());
 		container->showStub(! getHost());
 	}
 }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e5dda7e8d8..b6fd3ec9c8 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -191,6 +191,12 @@ void on_new_message(const LLSD& msg)
     }
     else if("openconversations" == action)
     {
+        LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+        if (im_box)
+        {
+            im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
+        }
+
         LLFloaterReg::showInstance("im_container");
     }
 }
-- 
cgit v1.2.3


From f1155c4fa5e9a4eaa5b4d452fc46a2246fb305bd Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 4 Dec 2012 04:14:51 +0200
Subject: CHUI-573 FIXED Notification chiclet shown when object chiclets are
 shown

---
 indra/newview/llchiclet.cpp                        | 882 +--------------------
 indra/newview/llchiclet.h                          | 555 +------------
 indra/newview/llchicletbar.cpp                     | 104 +--
 indra/newview/llchicletbar.h                       |  16 -
 indra/newview/llfloaterimsession.cpp               |  10 +-
 indra/newview/llscriptfloater.cpp                  | 121 ++-
 indra/newview/llsyswellwindow.cpp                  | 289 +------
 indra/newview/llsyswellwindow.h                    |  66 +-
 .../default/textures/bottomtray/Notices_Unread.png | Bin 3693 -> 0 bytes
 .../textures/bottomtray/VoicePTT_Lvl1_Dark.png     | Bin 602 -> 0 bytes
 .../textures/bottomtray/VoicePTT_Lvl2_Dark.png     | Bin 669 -> 0 bytes
 .../textures/bottomtray/VoicePTT_Lvl3_Dark.png     | Bin 639 -> 0 bytes
 .../textures/bottomtray/VoicePTT_Off_Dark.png      | Bin 547 -> 0 bytes
 .../textures/bottomtray/VoicePTT_On_Dark.png       | Bin 526 -> 0 bytes
 indra/newview/skins/default/textures/textures.xml  |   8 -
 .../skins/default/xui/da/menu_im_well_button.xml   |   4 -
 .../xui/da/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/de/menu_im_well_button.xml   |   4 -
 .../xui/de/menu_notification_well_button.xml       |   4 -
 .../xui/en/menu_notification_well_button.xml       |  16 -
 .../skins/default/xui/en/panel_activeim_row.xml    |  97 ---
 .../skins/default/xui/en/panel_chiclet_bar.xml     |  44 -
 .../default/xui/en/widgets/chiclet_im_adhoc.xml    |  55 --
 .../default/xui/en/widgets/chiclet_im_group.xml    |  56 --
 .../default/xui/en/widgets/chiclet_im_p2p.xml      |  56 --
 .../skins/default/xui/es/menu_im_well_button.xml   |   4 -
 .../xui/es/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/fr/menu_im_well_button.xml   |   4 -
 .../xui/fr/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/it/menu_im_well_button.xml   |   4 -
 .../xui/it/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/ja/menu_im_well_button.xml   |   4 -
 .../xui/ja/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/pl/menu_im_well_button.xml   |   4 -
 .../xui/pl/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/pt/menu_im_well_button.xml   |   4 -
 .../xui/pt/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/ru/menu_im_well_button.xml   |   4 -
 .../xui/ru/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/tr/menu_im_well_button.xml   |   4 -
 .../xui/tr/menu_notification_well_button.xml       |   4 -
 .../skins/default/xui/zh/menu_im_well_button.xml   |   4 -
 .../xui/zh/menu_notification_well_button.xml       |   4 -
 43 files changed, 100 insertions(+), 2363 deletions(-)
 delete mode 100644 indra/newview/skins/default/textures/bottomtray/Notices_Unread.png
 delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png
 delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png
 delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png
 delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png
 delete mode 100644 indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png
 delete mode 100644 indra/newview/skins/default/xui/da/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/da/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/de/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/de/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/en/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/en/panel_activeim_row.xml
 delete mode 100644 indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
 delete mode 100644 indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
 delete mode 100644 indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
 delete mode 100644 indra/newview/skins/default/xui/es/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/es/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/fr/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/it/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/it/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/ja/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/pl/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/pt/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/ru/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/tr/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/zh/menu_im_well_button.xml
 delete mode 100644 indra/newview/skins/default/xui/zh/menu_notification_well_button.xml

(limited to 'indra')

diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index a665aeb6bd..1acbdd32b7 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -27,35 +27,15 @@
 #include "llviewerprecompiledheaders.h" // must be first include
 #include "llchiclet.h"
 
-#include "llagent.h"
-#include "llavataractions.h"
-#include "llchicletbar.h"
-#include "lleventtimer.h"
-#include "llgroupactions.h"
-#include "lliconctrl.h"
 #include "llfloaterimsession.h"
 #include "llfloaterimcontainer.h"
-#include "llimview.h"
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
-#include "llmenugl.h"
 #include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "lloutputmonitorctrl.h"
 #include "llscriptfloater.h"
-#include "llspeakers.h"
-#include "lltextbox.h"
-#include "llvoiceclient.h"
-#include "llgroupmgr.h"
-#include "llnotificationmanager.h"
-#include "lltransientfloatermgr.h"
-#include "llsyswellwindow.h"
+#include "llsingleton.h"
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
-static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
-static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
-static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
-static LLDefaultChildRegistry::Register<LLAdHocChiclet> t5("chiclet_im_adhoc");
 static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
 static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer");
 
@@ -66,192 +46,6 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-
-LLSysWellChiclet::Params::Params()
-: button("button")
-, unread_notifications("unread_notifications")
-, max_displayed_count("max_displayed_count", 99)
-{
-	button.name = "button";
-	button.tab_stop = FALSE;
-	button.label = LLStringUtil::null;
-}
-
-LLSysWellChiclet::LLSysWellChiclet(const Params& p)
-: LLChiclet(p)
-, mButton(NULL)
-, mCounter(0)
-, mMaxDisplayedCount(p.max_displayed_count)
-, mIsNewMessagesState(false)
-, mFlashToLitTimer(NULL)
-, mContextMenu(NULL)
-{
-	LLButton::Params button_params = p.button;
-	mButton = LLUICtrlFactory::create<LLButton>(button_params);
-	addChild(mButton);
-
-
-	mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1));
-}
-
-LLSysWellChiclet::~LLSysWellChiclet()
-{
-	delete mFlashToLitTimer;
-}
-
-void LLSysWellChiclet::setCounter(S32 counter)
-{
-	// do nothing if the same counter is coming. EXT-3678.
-	if (counter == mCounter) return;
-
-	// note same code in LLChicletNotificationCounterCtrl::setCounter(S32 counter)
-	std::string s_count;
-	if(counter != 0)
-	{
-		static std::string more_messages_exist("+");
-		std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
-		s_count = llformat("%d%s"
-			, llmin(counter, mMaxDisplayedCount)
-			, more_messages.c_str()
-			);
-	}
-
-	mButton->setLabel(s_count);
-
-	mCounter = counter;
-}
-
-boost::signals2::connection LLSysWellChiclet::setClickCallback(
-	const commit_callback_t& cb)
-{
-	return mButton->setClickedCallback(cb);
-}
-
-void LLSysWellChiclet::setToggleState(BOOL toggled) {
-	mButton->setToggleState(toggled);
-}
-
-void LLSysWellChiclet::changeLitState(bool blink)
-{
-	setNewMessagesState(!mIsNewMessagesState);
-}
-
-void LLSysWellChiclet::setNewMessagesState(bool new_messages)
-{
-	/*
-	Emulate 4 states of button by background images, see detains in EXT-3147
-	xml attribute           Description
-	image_unselected        "Unlit" - there are no new messages
-	image_selected          "Unlit" + "Selected" - there are no new messages and the Well is open
-	image_pressed           "Lit" - there are new messages
-	image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well is open
-	*/
-	mButton->setForcePressedState(new_messages);
-
-	mIsNewMessagesState = new_messages;
-}
-
-void LLSysWellChiclet::updateWidget(bool is_window_empty)
-{
-	mButton->setEnabled(!is_window_empty);
-
-	if (LLChicletBar::instanceExists())
-	{
-		LLChicletBar::getInstance()->showWellButton(getName(), !is_window_empty);
-	}
-}
-// virtual
-BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-	if(!mContextMenu)
-	{
-		createMenu();
-	}
-	if (mContextMenu)
-	{
-		mContextMenu->show(x, y);
-		LLMenuGL::showPopup(this, mContextMenu, x, y);
-	}
-	return TRUE;
-}
-
-/************************************************************************/
-/*               LLNotificationChiclet implementation                   */
-/************************************************************************/
-LLNotificationChiclet::LLNotificationChiclet(const Params& p)
-:	LLSysWellChiclet(p),
-	mUreadSystemNotifications(0)
-{
-	mNotificationChannel.reset(new ChicletNotificationChannel(this));
-	// ensure that notification well window exists, to synchronously
-	// handle toast add/delete events.
-	LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
-}
-
-void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string action = user_data.asString();
-	if("close all" == action)
-	{
-		LLNotificationWellWindow::getInstance()->closeAll();
-	}
-}
-
-bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data)
-{
-	std::string item = user_data.asString();
-	if (item == "can close all")
-	{
-		return mUreadSystemNotifications != 0;
-	}
-	return true;
-}
-
-void LLNotificationChiclet::createMenu()
-{
-	if(mContextMenu)
-	{
-		llwarns << "Menu already exists" << llendl;
-		return;
-	}
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("NotificationWellChicletMenu.Action",
-		boost::bind(&LLNotificationChiclet::onMenuItemClicked, this, _2));
-
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-	enable_registrar.add("NotificationWellChicletMenu.EnableItem",
-		boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
-
-	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
-		("menu_notification_well_button.xml",
-		 LLMenuGL::sMenuContainer,
-		 LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-/*virtual*/
-void LLNotificationChiclet::setCounter(S32 counter)
-{
-	LLSysWellChiclet::setCounter(counter);
-	updateWidget(getCounter() == 0);
-	
-}
-
-bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
-{
-	if( !(notification->canLogToIM() && notification->hasFormElements())
-		&& (!notification->getPayload().has("give_inventory_notification")
-			|| notification->getPayload()["give_inventory_notification"]))
-	{
-		return true;
-	}
-	return false;
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
 LLChiclet::Params::Params()
  : show_counter("show_counter", true)
  , enable_counter("enable_counter", false)
@@ -303,7 +97,9 @@ LLSD LLChiclet::getValue() const
 void LLChiclet::setValue(const LLSD& value)
 {
 	if(value.isUUID())
+	{
 		setSessionId(value.asUUID());
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -315,12 +111,9 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
 , mShowSpeaker(false)
 , mDefaultWidth(p.rect().getWidth())
 , mNewMessagesIcon(NULL)
-, mSpeakerCtrl(NULL)
-, mCounterCtrl(NULL)
 , mChicletButton(NULL)
 , mPopupMenu(NULL)
 {
-	enableCounterControl(p.enable_counter);
 }
 
 /* virtual*/
@@ -331,107 +124,14 @@ BOOL LLIMChiclet::postBuild()
 	mChicletButton->setDoubleClickCallback(boost::bind(&LLIMChiclet::onMouseDown, this));
 	return TRUE;
 }
-void LLIMChiclet::setShowSpeaker(bool show)
-{
-	bool needs_resize = getShowSpeaker() != show;
-	if(needs_resize)
-	{		
-		mShowSpeaker = show;
-	}
-
-	toggleSpeakerControl();
-}
-
-void LLIMChiclet::enableCounterControl(bool enable) 
-{
-	mCounterEnabled = enable;
-	if(!enable)
-	{
-		LLChiclet::setShowCounter(false);
-	}
-}
-
-void LLIMChiclet::setShowCounter(bool show)
-{
-	if(!mCounterEnabled)
-	{
-		return;
-	}
-
-	bool needs_resize = getShowCounter() != show;
-	if(needs_resize)
-	{		
-		LLChiclet::setShowCounter(show);
-		toggleCounterControl();
-	}
-}
-
-void LLIMChiclet::initSpeakerControl()
-{
-	// virtual
-}
 
 void LLIMChiclet::setRequiredWidth()
 {
-	bool show_speaker = getShowSpeaker();
-	bool show_counter = getShowCounter();
 	S32 required_width = mDefaultWidth;
-
-	if (show_counter)
-	{
-		required_width += mCounterCtrl->getRect().getWidth();
-	}
-	if (show_speaker)
-	{
-		required_width += mSpeakerCtrl->getRect().getWidth();
-	} 
-
 	reshape(required_width, getRect().getHeight());
-
 	onChicletSizeChanged();
 }
 
-void LLIMChiclet::toggleSpeakerControl()
-{
-	if(getShowSpeaker())
-	{
-		// move speaker to the right of chiclet icon
-		LLRect speaker_rc = mSpeakerCtrl->getRect();
-		speaker_rc.setLeftTopAndSize(mDefaultWidth, speaker_rc.mTop, speaker_rc.getWidth(), speaker_rc.getHeight());
-		mSpeakerCtrl->setRect(speaker_rc);
-
-		if(getShowCounter())
-		{
-			// move speaker to the right of counter
-			mSpeakerCtrl->translate(mCounterCtrl->getRect().getWidth(), 0);
-		}
-
-		initSpeakerControl();		
-	}
-
-	setRequiredWidth();
-	mSpeakerCtrl->setSpeakerId(LLUUID::null);
-	mSpeakerCtrl->setVisible(getShowSpeaker());
-}
-
-void LLIMChiclet::setCounter(S32 counter)
-{
-	if (mCounterCtrl->getCounter() == counter)
-	{
-		return;
-	}
-
-	mCounterCtrl->setCounter(counter);
-	setShowCounter(counter);
-	setShowNewMessagesIcon(counter);
-}
-
-void LLIMChiclet::toggleCounterControl()
-{
-	setRequiredWidth();
-	mCounterCtrl->setVisible(getShowCounter());
-}
-
 void LLIMChiclet::setShowNewMessagesIcon(bool show)
 {
 	if(mNewMessagesIcon)
@@ -449,7 +149,6 @@ bool LLIMChiclet::getShowNewMessagesIcon()
 void LLIMChiclet::onMouseDown()
 {
 	LLFloaterIMSession::toggle(getSessionId());
-	setCounter(0);
 }
 
 void LLIMChiclet::setToggleState(bool toggle)
@@ -457,52 +156,6 @@ void LLIMChiclet::setToggleState(bool toggle)
 	mChicletButton->setToggleState(toggle);
 }
 
-void LLIMChiclet::draw()
-{
-	LLUICtrl::draw();
-}
-
-// static
-LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
-{
-	EType				type	= TYPE_UNKNOWN;
-
-	if(session_id.isNull())
-		return type;
-
-	EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
-	if (IM_COUNT == im_type)
-	{
-		llassert_always(0 && "IM session not found"); // should never happen
-		return type;
-	}
-
-	switch(im_type)
-	{
-	case IM_NOTHING_SPECIAL:
-	case IM_SESSION_P2P_INVITE:
-		type = TYPE_IM;
-		break;
-	case IM_SESSION_GROUP_START:
-	case IM_SESSION_INVITE:
-		if (gAgent.isInGroup(session_id))
-		{
-			type = TYPE_GROUP;
-		}
-		else
-		{
-			type = TYPE_AD_HOC;
-		}
-		break;
-	case IM_SESSION_CONFERENCE_START:
-		type = TYPE_AD_HOC;
-	default:
-		break;
-	}
-
-	return type;
-}
-
 BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	if(!mPopupMenu)
@@ -534,382 +187,6 @@ bool LLIMChiclet::canCreateMenu()
 	return true;
 }
 
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLIMP2PChiclet::Params::Params()
-: avatar_icon("avatar_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-{
-}
-
-LLIMP2PChiclet::LLIMP2PChiclet(const Params& p)
-: LLIMChiclet(p)
-, mChicletIconCtrl(NULL)
-{
-	LLButton::Params button_params = p.chiclet_button;
-	mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
-	addChild(mChicletButton);
-
-	LLIconCtrl::Params new_msg_params = p.new_message_icon;
-	mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
-	addChild(mNewMessagesIcon);
-
-	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
-	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
-	addChild(mChicletIconCtrl);
-
-	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
-	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
-	addChild(mCounterCtrl);
-
-	setCounter(getCounter());
-	setShowCounter(getShowCounter());
-
-	LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
-	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
-	addChild(mSpeakerCtrl);
-
-	sendChildToFront(mNewMessagesIcon);
-	setShowSpeaker(p.show_speaker);
-}
-
-void LLIMP2PChiclet::initSpeakerControl()
-{
-	mSpeakerCtrl->setSpeakerId(getOtherParticipantId());
-}
-
-void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
-{
-	LLIMChiclet::setOtherParticipantId(other_participant_id);
-	mChicletIconCtrl->setValue(getOtherParticipantId());
-}
-
-void LLIMP2PChiclet::updateMenuItems()
-{
-	if(!mPopupMenu)
-		return;
-	if(getSessionId().isNull())
-		return;
-
-	LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(getSessionId());
-	bool open_window_exists = open_im_floater && open_im_floater->getVisible();
-	mPopupMenu->getChild<LLUICtrl>("Send IM")->setEnabled(!open_window_exists);
-	
-	bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId());
-	mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
-}
-
-void LLIMP2PChiclet::createPopupMenu()
-{
-	if(!canCreateMenu())
-		return;
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2));
-
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
-		("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string level = user_data.asString();
-	LLUUID other_participant_id = getOtherParticipantId();
-
-	if("profile" == level)
-	{
-		LLAvatarActions::showProfile(other_participant_id);
-	}
-	else if("im" == level)
-	{
-		LLAvatarActions::startIM(other_participant_id);
-	}
-	else if("add" == level)
-	{
-		LLAvatarActions::requestFriendshipDialog(other_participant_id);
-	}
-	else if("end" == level)
-	{
-		LLAvatarActions::endIM(other_participant_id);
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLAdHocChiclet::Params::Params()
-: avatar_icon("avatar_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-, avatar_icon_color("avatar_icon_color", LLColor4::green)
-{
-}
-
-LLAdHocChiclet::LLAdHocChiclet(const Params& p)
-: LLIMChiclet(p)
-, mChicletIconCtrl(NULL)
-{
-	LLButton::Params button_params = p.chiclet_button;
-	mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
-	addChild(mChicletButton);
-
-	LLIconCtrl::Params new_msg_params = p.new_message_icon;
-	mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
-	addChild(mNewMessagesIcon);
-
-	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
-	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
-	//Make the avatar modified
-	mChicletIconCtrl->setColor(p.avatar_icon_color);
-	addChild(mChicletIconCtrl);
-
-	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
-	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
-	addChild(mCounterCtrl);
-
-	setCounter(getCounter());
-	setShowCounter(getShowCounter());
-
-	LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
-	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
-	addChild(mSpeakerCtrl);
-
-	sendChildToFront(mNewMessagesIcon);
-	setShowSpeaker(p.show_speaker);
-}
-
-void LLAdHocChiclet::setSessionId(const LLUUID& session_id)
-{
-	LLChiclet::setSessionId(session_id);
-	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
-	mChicletIconCtrl->setValue(im_session->mOtherParticipantID);
-}
-
-void LLAdHocChiclet::draw()
-{
-	switchToCurrentSpeaker();
-	LLIMChiclet::draw();
-}
-
-void LLAdHocChiclet::initSpeakerControl()
-{
-	switchToCurrentSpeaker();
-}
-
-void LLAdHocChiclet::switchToCurrentSpeaker()
-{
-	LLUUID speaker_id;
-	LLSpeakerMgr::speaker_list_t speaker_list;
-
-	LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE);
-	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
-	{
-		LLPointer<LLSpeaker> s = *i;
-		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
-		{
-			speaker_id = s->mID;
-			break;
-		}
-	}
-
-	mSpeakerCtrl->setSpeakerId(speaker_id);
-}
-
-void LLAdHocChiclet::createPopupMenu()
-{
-	if(!canCreateMenu())
-		return;
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2));
-
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
-		("menu_imchiclet_adhoc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string level = user_data.asString();
-	LLUUID group_id = getSessionId();
-
-	if("end" == level)
-	{
-		LLGroupActions::endIM(group_id);
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLIMGroupChiclet::Params::Params()
-: group_icon("group_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-{
-}
-
-LLIMGroupChiclet::LLIMGroupChiclet(const Params& p)
-: LLIMChiclet(p)
-, LLGroupMgrObserver(LLUUID::null)
-, mChicletIconCtrl(NULL)
-{
-	LLButton::Params button_params = p.chiclet_button;
-	mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
-	addChild(mChicletButton);
-
-	LLIconCtrl::Params new_msg_params = p.new_message_icon;
-	mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
-	addChild(mNewMessagesIcon);
-
-	LLChicletGroupIconCtrl::Params avatar_params = p.group_icon;
-	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletGroupIconCtrl>(avatar_params);
-	addChild(mChicletIconCtrl);
-
-	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
-	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
-	addChild(mCounterCtrl);
-
-	setCounter(getCounter());
-	setShowCounter(getShowCounter());
-
-	LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
-	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
-	addChild(mSpeakerCtrl);
-
-	sendChildToFront(mNewMessagesIcon);
-	setShowSpeaker(p.show_speaker);
-}
-
-LLIMGroupChiclet::~LLIMGroupChiclet()
-{
-	LLGroupMgr::getInstance()->removeObserver(this);
-}
-
-void LLIMGroupChiclet::draw()
-{
-	if(getShowSpeaker())
-	{
-		switchToCurrentSpeaker();
-	}
-	LLIMChiclet::draw();
-}
-
-void LLIMGroupChiclet::initSpeakerControl()
-{
-	switchToCurrentSpeaker();
-}
-
-void LLIMGroupChiclet::switchToCurrentSpeaker()
-{
-	LLUUID speaker_id;
-	LLSpeakerMgr::speaker_list_t speaker_list;
-
-	LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE);
-	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
-	{
-		LLPointer<LLSpeaker> s = *i;
-		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
-		{
-			speaker_id = s->mID;
-			break;
-		}
-	}
-
-	mSpeakerCtrl->setSpeakerId(speaker_id);
-}
-
-void LLIMGroupChiclet::setSessionId(const LLUUID& session_id)
-{
-	LLChiclet::setSessionId(session_id);
-
-	LLGroupMgr* grp_mgr = LLGroupMgr::getInstance();
-	LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id);
-	if (group_data && group_data->mInsigniaID.notNull())
-	{
-		mChicletIconCtrl->setValue(group_data->mInsigniaID);
-	}
-	else
-	{
-		if(getSessionId() != mID)
-		{
-			grp_mgr->removeObserver(this);
-			mID = getSessionId();
-			grp_mgr->addObserver(this);
-		}
-		grp_mgr->sendGroupPropertiesRequest(session_id);
-	}
-}
-
-void LLIMGroupChiclet::changed(LLGroupChange gc)
-{
-	if (GC_PROPERTIES == gc)
-	{
-		LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId());
-		if (group_data)
-		{
-			mChicletIconCtrl->setValue(group_data->mInsigniaID);
-		}
-	}
-}
-
-void LLIMGroupChiclet::updateMenuItems()
-{
-	if(!mPopupMenu)
-		return;
-	if(getSessionId().isNull())
-		return;
-
-	LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(getSessionId());
-	bool open_window_exists = open_im_floater && open_im_floater->getVisible();
-	mPopupMenu->getChild<LLUICtrl>("Chat")->setEnabled(!open_window_exists);
-}
-
-void LLIMGroupChiclet::createPopupMenu()
-{
-	if(!canCreateMenu())
-		return;
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2));
-
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
-		("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string level = user_data.asString();
-	LLUUID group_id = getSessionId();
-
-	if("group chat" == level)
-	{
-		LLGroupActions::startIM(group_id);
-	}
-	else if("info" == level)
-	{
-		LLGroupActions::show(group_id);
-	}
-	else if("end" == level)
-	{
-		LLGroupActions::endIM(group_id);
-	}
-}
-
-
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -964,20 +241,6 @@ void LLChicletPanel::onMessageCountChanged(const LLSD& data)
 	{
 		unread = 0;
 	}
-
-	std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(session_id);
-	std::list<LLChiclet *>::iterator iter;
-	for (iter = chiclets.begin(); iter != chiclets.end(); iter++) {
-		LLChiclet* chiclet = *iter;
-		if (chiclet != NULL)
-		{
-			chiclet->setCounter(unread);
-		}
-	    else
-	    {
-	    	llwarns << "Unable to set counter for chiclet " << session_id << llendl;
-	    }
-	}
 }
 
 void LLChicletPanel::objectChicletCallback(const LLSD& data)
@@ -992,10 +255,6 @@ void LLChicletPanel::objectChicletCallback(const LLSD& data)
 		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*iter);
 		if (chiclet != NULL)
 		{
-			if(data.has("unread"))
-			{
-				chiclet->setCounter(data["unread"]);
-			}
 			chiclet->setShowNewMessagesIcon(new_message);
 		}
 	}
@@ -1037,7 +296,6 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
 		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
 		if(chiclet)
 		{
-			chiclet->setShowSpeaker(true);
 			if (gSavedSettings.getBOOL("OpenIMOnVoice"))
 			{
 				LLFloaterIMContainer::getInstance()->showConversation(session_id);
@@ -1045,20 +303,6 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
 		}
 	}
 
-	if(!s_previous_active_voice_session_id.isNull() && s_previous_active_voice_session_id != session_id)
-	{
-		chiclets = LLIMChiclet::sFindChicletsSignal(s_previous_active_voice_session_id);
-
-		for(std::list<LLChiclet *>::iterator it = chiclets.begin(); it != chiclets.end(); ++it)
-		{
-			LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
-			if(chiclet)
-			{
-				chiclet->setShowSpeaker(false);
-			}
-		}		
-	}
-
 	s_previous_active_voice_session_id = session_id;
 }
 
@@ -1544,85 +788,6 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
 	return res;
 }
 
-S32 LLChicletPanel::getTotalUnreadIMCount()
-{
-	S32 count = 0;
-	chiclet_list_t::const_iterator it = mChicletList.begin();
-	for( ; mChicletList.end() != it; ++it)
-	{
-		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
-		if(chiclet)
-		{
-			count += chiclet->getCounter();
-		}
-	}
-	return count;
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-LLChicletNotificationCounterCtrl::Params::Params()
-: max_displayed_count("max_displayed_count", 99)
-{
-}
-
-LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p)
- : LLTextBox(p)
- , mCounter(0)
- , mInitialWidth(0)
- , mMaxDisplayedCount(p.max_displayed_count)
-{
-	mInitialWidth = getRect().getWidth();
-}
-
-void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
-{
-	mCounter = counter;
-
-	// note same code in LLSysWellChiclet::setCounter(S32 counter)
-	std::string s_count;
-	if(counter != 0)
-	{
-		static std::string more_messages_exist("+");
-		std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
-		s_count = llformat("%d%s"
-			, llmin(counter, mMaxDisplayedCount)
-			, more_messages.c_str()
-			);
-	}
-
-	if(mCounter != 0)
-	{
-		setText(s_count);
-	}
-	else
-	{
-		setText(std::string(""));
-	}
-}
-
-LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
-{
-	LLRect rc;
-	S32 text_width = getTextPixelWidth();
-
-	rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth);
-	
-	return rc;
-}
-
-void LLChicletNotificationCounterCtrl::setValue(const LLSD& value)
-{
-	if(value.isInteger())
-		setCounter(value.asInteger());
-}
-
-LLSD LLChicletNotificationCounterCtrl::getValue() const
-{
-	return LLSD(getCounter());
-}
-
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -1632,28 +797,6 @@ LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
 {
 }
 
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p)
-: LLIconCtrl(p)
-, mDefaultIcon(p.default_icon)
-{
-	setValue(LLUUID::null);
-}
-
-void LLChicletGroupIconCtrl::setValue(const LLSD& value )
-{
-	if(value.asUUID().isNull())
-	{
-		LLIconCtrl::setValue(mDefaultIcon);
-	}
-	else
-	{
-		LLIconCtrl::setValue(value);
-	}
-}
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -1681,15 +824,6 @@ void LLChicletInvOfferIconCtrl::setValue(const LLSD& value )
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
- : LLOutputMonitorCtrl(p)
-{
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
 LLScriptChiclet::Params::Params()
  : icon("icon")
  , chiclet_button("chiclet_button")
@@ -1725,11 +859,6 @@ void LLScriptChiclet::setSessionId(const LLUUID& session_id)
 	setToolTip(LLScriptFloaterManager::getObjectName(session_id));
 }
 
-void LLScriptChiclet::setCounter(S32 counter)
-{
-	setShowNewMessagesIcon( counter > 0 );
-}
-
 void LLScriptChiclet::onMouseDown()
 {
 	LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId());
@@ -1808,11 +937,6 @@ void LLInvOfferChiclet::setSessionId(const LLUUID& session_id)
 	}
 }
 
-void LLInvOfferChiclet::setCounter(S32 counter)
-{
-	setShowNewMessagesIcon( counter > 0 );
-}
-
 void LLInvOfferChiclet::onMouseDown()
 {
 	LLScriptFloaterManager::instance().toggleScriptFloater(getSessionId());
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 7f72c7f9e2..bd6c1a3e71 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -29,75 +29,10 @@
 
 #include "llavatariconctrl.h"
 #include "llbutton.h"
-#include "llflashtimer.h"
-#include "llpanel.h"
-#include "lltextbox.h"
-#include "lloutputmonitorctrl.h"
-#include "llgroupmgr.h"
-#include "llimview.h"
-#include "llnotifications.h"
 
 class LLMenuGL;
 class LLFloaterIMSession;
 
-/**
- * Class for displaying amount of messages/notifications(unread).
- */
-class LLChicletNotificationCounterCtrl : public LLTextBox
-{
-public:
-
-	struct Params :	public LLInitParam::Block<Params, LLTextBox::Params>
-	{
-		/**
-		* Contains maximum displayed count of unread messages. Default value is 9.
-		*
-		* If count is less than "max_unread_count" will be displayed as is.
-		* Otherwise 9+ will be shown (for default value).
-		*/
-		Optional<S32> max_displayed_count;
-
-		Params();
-	};
-
-	/**
-	 * Sets number of notifications
-	 */
-	virtual void setCounter(S32 counter);
-
-	/**
-	 * Returns number of notifications
-	 */
-	virtual S32 getCounter() const { return mCounter; }
-
-	/**
-	 * Returns width, required to display amount of notifications in text form.
-	 * Width is the only valid value.
-	 */
-	/*virtual*/ LLRect getRequiredRect();
-
-	/**
-	 * Sets number of notifications using LLSD
-	 */
-	/*virtual*/ void setValue(const LLSD& value);
-
-	/**
-	 * Returns number of notifications wrapped in LLSD
-	 */
-	/*virtual*/ LLSD getValue() const;
-
-protected:
-
-	LLChicletNotificationCounterCtrl(const Params& p);
-	friend class LLUICtrlFactory;
-
-private:
-
-	S32 mCounter;
-	S32 mInitialWidth;
-	S32 mMaxDisplayedCount;
-};
-
 /**
  * Class for displaying avatar's icon in P2P chiclet.
  */
@@ -121,35 +56,6 @@ protected:
 	friend class LLUICtrlFactory;
 };
 
-/**
- * Class for displaying group's icon in Group chiclet.
- */
-class LLChicletGroupIconCtrl : public LLIconCtrl
-{
-public:
-
-	struct Params :	public LLInitParam::Block<Params, LLIconCtrl::Params>
-	{
-		Optional<std::string> default_icon;
-
-		Params()
-		:	default_icon("default_icon", "Generic_Group")
-		{}
-	};
-
-	/**
-	 * Sets icon, if value is LLUUID::null - default icon will be set.
-	 */
-	virtual void setValue(const LLSD& value );
-
-protected:
-
-	LLChicletGroupIconCtrl(const Params& p);
-	friend class LLUICtrlFactory;
-
-	std::string mDefaultIcon;
-};
-
 /**
  * Class for displaying icon in inventory offer chiclet.
  */
@@ -183,23 +89,6 @@ private:
 	std::string mDefaultIcon;
 };
 
-/**
- * Class for displaying of speaker's voice indicator 
- */
-class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl
-{
-public:
-
-	struct Params : public LLInitParam::Block<Params, LLOutputMonitorCtrl::Params>
-	{
-		Params(){};
-	};
-protected:
-
-	LLChicletSpeakerCtrl(const Params&p);
-	friend class LLUICtrlFactory;
-};
-
 /**
  * Base class for all chiclets.
  */
@@ -227,26 +116,6 @@ public:
 	 */
 	virtual const LLUUID& getSessionId() const { return mSessionId; }
 
-	/**
-	 * Sets number of unread notifications.
-	 */
-	virtual void setCounter(S32 counter) = 0;
-
-	/**
-	 * Returns number of unread notifications.
-	 */
-	virtual S32 getCounter() = 0;
-
-	/**
-	 * Sets show counter state.
-	 */
-	virtual void setShowCounter(bool show) { mShowCounter = show; }
-
-	/**
-	 * Returns show counter state.
-	 */
-	virtual bool getShowCounter() {return mShowCounter;};
-
 	/**
 	 * Connects chiclet clicked event with callback.
 	 */
@@ -324,62 +193,6 @@ public:
 	 * It is used for default setting up of chicklet:click handler, etc.  
 	 */
 	BOOL postBuild();
-	/**
-	 * Sets IM session name. This name will be displayed in chiclet tooltip.
-	 */
-	virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
-
-	/**
-	 * Sets id of person/group user is chatting with.
-	 * Session id should be set before calling this
-	 */
-	virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
-
-	/**
-	 * Gets id of person/group user is chatting with.
-	 */
-	virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }
-
-	/**
-	 * Init Speaker Control with speaker's ID
-	 */
-	virtual void initSpeakerControl();
-
-	/**
-	 * set status (Shows/Hide) for voice control.
-	 */
-	virtual void setShowSpeaker(bool show);
-
-	/**
-	 * Returns voice chat status control visibility.
-	 */
-	virtual bool getShowSpeaker() {return mShowSpeaker;};
-
-	/**
-	 * Shows/Hides for voice control for a chiclet.
-	 */
-	virtual void toggleSpeakerControl();
-
-	/**
-	* Sets number of unread messages. Will update chiclet's width if number text 
-	* exceeds size of counter and notify it's parent about size change.
-	*/
-	virtual void setCounter(S32);
-
-	/**
-	* Enables/disables the counter control for a chiclet.
-	*/
-	virtual void enableCounterControl(bool enable);
-
-	/**
-	* Sets show counter state.
-	*/
-	virtual void setShowCounter(bool show);
-
-	/**
-	* Shows/Hides for counter control for a chiclet.
-	*/
-	virtual void toggleCounterControl();
 
 	/**
 	* Sets required width for a chiclet according to visible controls.
@@ -396,21 +209,6 @@ public:
 	 */
 	virtual bool getShowNewMessagesIcon();
 
-	virtual void draw();
-
-	/**
-	 * Determine whether given ID refers to a group or an IM chat session.
-	 * 
-	 * This is used when we need to chose what IM chiclet (P2P/group)
-	 * class to instantiate.
-	 * 
-	 * @param session_id session ID.
-	 * @return TYPE_GROUP in case of group chat session,
-	 *         TYPE_IM in case of P2P session,
-	 *         TYPE_UNKNOWN otherwise.
-	 */
-	static EType getIMSessionType(const LLUUID& session_id);
-
 	/**
 	 * The action taken on mouse down event.
 	 * 
@@ -452,8 +250,6 @@ protected:
 	S32 mDefaultWidth;
 
 	LLIconCtrl* mNewMessagesIcon;
-	LLChicletNotificationCounterCtrl* mCounterCtrl;
-	LLChicletSpeakerCtrl* mSpeakerCtrl;
 	LLButton* mChicletButton;
 
 	/** the id of another participant, either an avatar id or a group id*/
@@ -481,137 +277,6 @@ public:
 			sFindChicletsSignal;
 };
 
-/**
- * Implements P2P chiclet.
- */
-class LLIMP2PChiclet : public LLIMChiclet
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
-	{
-		Optional<LLButton::Params> chiclet_button;
-
-		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
-
-		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
-		Optional<LLChicletSpeakerCtrl::Params> speaker;
-
-		Optional<LLIconCtrl::Params> new_message_icon;
-
-		Optional<bool>	show_speaker;
-
-		Params();
-	};
-
-	/* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id);
-
-	/**
-	 * Init Speaker Control with speaker's ID
-	 */
-	/*virtual*/ void initSpeakerControl();
-
-	/**
-	 * Returns number of unread messages.
-	 */
-	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-protected:
-	LLIMP2PChiclet(const Params& p);
-	friend class LLUICtrlFactory;
-
-	/**
-	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
-	 * based on other participant's id.
-	 */
-	virtual void createPopupMenu();
-
-	/**
-	 * Processes clicks on chiclet popup menu.
-	 */
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/** 
-	 * Enables/disables menus based on relationship with other participant.
-	 * Enables/disables "show session" menu item depending on visible IM floater existence.
-	 */
-	virtual void updateMenuItems();
-
-private:
-
-	LLChicletAvatarIconCtrl* mChicletIconCtrl;
-};
-
-/**
- * Implements AD-HOC chiclet.
- */
-class LLAdHocChiclet : public LLIMChiclet
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
-	{
-		Optional<LLButton::Params> chiclet_button;
-
-		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
-
-		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
-		Optional<LLChicletSpeakerCtrl::Params> speaker;
-
-		Optional<LLIconCtrl::Params> new_message_icon;
-
-		Optional<bool>	show_speaker;
-
-		Optional<LLColor4>	avatar_icon_color;
-
-		Params();
-	};
-
-	/**
-	 * Sets session id.
-	 * Session ID for group chat is actually Group ID.
-	 */
-	/*virtual*/ void setSessionId(const LLUUID& session_id);
-
-	/**
-	 * Keep Speaker Control with actual speaker's ID
-	 */
-	/*virtual*/ void draw();
-
-	/**
-	 * Init Speaker Control with speaker's ID
-	 */
-	/*virtual*/ void initSpeakerControl();
-
-	/**
-	 * Returns number of unread messages.
-	 */
-	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-protected:
-	LLAdHocChiclet(const Params& p);
-	friend class LLUICtrlFactory;
-
-	/**
-	 * Creates chiclet popup menu. Will create AdHoc Chat menu 
-	 * based on other participant's id.
-	 */
-	virtual void createPopupMenu();
-
-	/**
-	 * Processes clicks on chiclet popup menu.
-	 */
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/**
-	 * Finds a current speaker and resets the SpeakerControl with speaker's ID
-	 */
-	/*virtual*/ void switchToCurrentSpeaker();
-
-private:
-
-	LLChicletAvatarIconCtrl* mChicletIconCtrl;
-};
 
 /**
  * Chiclet for script floaters.
@@ -633,10 +298,6 @@ public:
 
 	/*virtual*/ void setSessionId(const LLUUID& session_id);
 
-	/*virtual*/ void setCounter(S32 counter);
-
-	/*virtual*/ S32 getCounter() { return 0; }
-
 	/**
 	 * Toggle script floater
 	 */
@@ -682,10 +343,6 @@ public:
 
 	/*virtual*/ void setSessionId(const LLUUID& session_id);
 
-	/*virtual*/ void setCounter(S32 counter);
-
-	/*virtual*/ S32 getCounter() { return 0; }
-
 	/**
 	 * Toggle script floater
 	 */
@@ -709,214 +366,6 @@ private:
 	LLChicletInvOfferIconCtrl* mChicletIconCtrl;
 };
 
-/**
- * Implements Group chat chiclet.
- */
-class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver
-{
-public:
-
-	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
-	{
-		Optional<LLButton::Params> chiclet_button;
-
-		Optional<LLChicletGroupIconCtrl::Params> group_icon;
-
-		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
-		Optional<LLChicletSpeakerCtrl::Params> speaker;
-
-		Optional<LLIconCtrl::Params> new_message_icon;
-
-		Optional<bool>	show_speaker;
-
-		Params();
-	};
-
-	/**
-	 * Sets session id.
-	 * Session ID for group chat is actually Group ID.
-	 */
-	/*virtual*/ void setSessionId(const LLUUID& session_id);
-
-	/**
-	 * Keep Speaker Control with actual speaker's ID
-	 */
-	/*virtual*/ void draw();
-
-	/**
-	 * Callback for LLGroupMgrObserver, we get this when group data is available or changed.
-	 * Sets group icon.
-	 */
-	/*virtual*/ void changed(LLGroupChange gc);
-
-	/**
-	 * Init Speaker Control with speaker's ID
-	 */
-	/*virtual*/ void initSpeakerControl();
-
-	/**
-	 * Returns number of unread messages.
-	 */
-	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-	~LLIMGroupChiclet();
-
-protected:
-	LLIMGroupChiclet(const Params& p);
-	friend class LLUICtrlFactory;
-
-	/**
-	 * Finds a current speaker and resets the SpeakerControl with speaker's ID
-	 */
-	/*virtual*/ void switchToCurrentSpeaker();
-
-	/**
-	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
-	 * based on other participant's id.
-	 */
-	virtual void createPopupMenu();
-
-	/**
-	 * Processes clicks on chiclet popup menu.
-	 */
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/**
-	 * Enables/disables "show session" menu item depending on visible IM floater existence.
-	 */
-	virtual void updateMenuItems();
-
-private:
-
-	LLChicletGroupIconCtrl* mChicletIconCtrl;
-};
-
-/**
- * Implements notification chiclet. Used to display total amount of unread messages 
- * across all IM sessions, total amount of system notifications. See EXT-3147 for details
- */
-class LLSysWellChiclet : public LLChiclet
-{
-public:
-
-	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
-	{
-		Optional<LLButton::Params> button;
-
-		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
-		/**
-		 * Contains maximum displayed count of unread messages. Default value is 9.
-		 *
-		 * If count is less than "max_unread_count" will be displayed as is.
-		 * Otherwise 9+ will be shown (for default value).
-		 */
-		Optional<S32> max_displayed_count;
-
-		Params();
-	};
-
-	/*virtual*/ void setCounter(S32 counter);
-
-	// *TODO: mantipov: seems getCounter is not necessary for LLNotificationChiclet
-	// but inherited interface requires it to implement. 
-	// Probably it can be safe removed.
-	/*virtual*/S32 getCounter() { return mCounter; }
-
-	boost::signals2::connection setClickCallback(const commit_callback_t& cb);
-
-	/*virtual*/ ~LLSysWellChiclet();
-
-	void setToggleState(BOOL toggled);
-
-	void setNewMessagesState(bool new_messages);
-	//this method should change a widget according to state of the SysWellWindow 
-	virtual void updateWidget(bool is_window_empty);
-
-protected:
-
-	LLSysWellChiclet(const Params& p);
-	friend class LLUICtrlFactory;
-
-	/**
-	 * Change Well 'Lit' state from 'Lit' to 'Unlit' and vice-versa.
-	 *
-	 * There is an assumption that it will be called 2*N times to do not change its start state.
-	 * @see FlashToLitTimer
-	 */
-	void changeLitState(bool blink);
-
-	/**
-	 * Displays menu.
-	 */
-	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-
-	virtual void createMenu() = 0;
-
-protected:
-	class FlashToLitTimer;
-	LLButton* mButton;
-	S32 mCounter;
-	S32 mMaxDisplayedCount;
-	bool mIsNewMessagesState;
-
-	LLFlashTimer* mFlashToLitTimer;
-	LLContextMenu* mContextMenu;
-};
-
-class LLNotificationChiclet : public LLSysWellChiclet
-{
-	LOG_CLASS(LLNotificationChiclet);
-	
-	friend class LLUICtrlFactory;
-public:
-	struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
-
-protected:
-	struct ChicletNotificationChannel : public LLNotificationChannel
-	{
-		ChicletNotificationChannel(LLNotificationChiclet* chiclet) 
-		:	LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString())),
-			mChiclet(chiclet)
-		{
-			// connect counter handlers to the signals
-			connectToChannel("Group Notifications");
-			connectToChannel("Offer");
-			connectToChannel("Notifications");
-		}
-
-		static bool filterNotification(LLNotificationPtr notify);
-		// connect counter updaters to the corresponding signals
-		/*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
-		/*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
-
-		LLNotificationChiclet* const mChiclet;
-	};
-
-	boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
-
-	LLNotificationChiclet(const Params& p);
-
-	/**
-	 * Processes clicks on chiclet menu.
-	 */
-	void onMenuItemClicked(const LLSD& user_data);
-
-	/**
-	 * Enables chiclet menu items.
-	 */
-	bool enableMenuItem(const LLSD& user_data);
-
-	/**
-	 * Creates menu.
-	 */
-	/*virtual*/ void createMenu();
-
-	/*virtual*/ void setCounter(S32 counter);
-	S32 mUreadSystemNotifications;
-};
-
 /**
  * Storage class for all IM chiclets. Provides mechanism to display, 
  * scroll, create, remove chiclets.
@@ -1018,9 +467,7 @@ public:
 
 	S32 getMinWidth() const { return mMinWidth; }
 
-	S32 getTotalUnreadIMCount();
-
-	S32	notifyParent(const LLSD& info);
+	/*virtual*/ S32	notifyParent(const LLSD& info);
 
 	/**
 	 * Toggle chiclet by session id ON and toggle OFF all other chiclets.
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index cfcde64e7b..fde7764129 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -25,18 +25,11 @@
  */
 
 #include "llviewerprecompiledheaders.h" // must be first include
-
 #include "llchicletbar.h"
 
-// library includes
-#include "llfloaterreg.h"
-#include "lllayoutstack.h"
-
-// newview includes
 #include "llchiclet.h"
-#include "llfloaterimsession.h" // for LLFloaterIMSession
+#include "lllayoutstack.h"
 #include "llpaneltopinfobar.h"
-#include "llsyswellwindow.h"
 
 namespace
 {
@@ -60,106 +53,11 @@ LLChicletBar::LLChicletBar(const LLSD&)
 	buildFromFile("panel_chiclet_bar.xml");
 }
 
-LLChicletBar::~LLChicletBar()
-{
-}
-
-LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id)
-{
-	LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(session_id);
-
-	switch (im_chiclet_type)
-	{
-	case LLIMChiclet::TYPE_IM:
-		return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
-	case LLIMChiclet::TYPE_GROUP:
-		return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
-	case LLIMChiclet::TYPE_AD_HOC:
-		return getChicletPanel()->createChiclet<LLAdHocChiclet>(session_id);
-	case LLIMChiclet::TYPE_UNKNOWN:
-		break;
-	}
-
-	return NULL;
-}
-
-//virtual
-void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
-{
-	if (!getChicletPanel()) return;
-
-	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
-	if (!session) return;
-
-	// no need to spawn chiclets for participants in P2P calls called through Avaline
-	if (session->isP2P() && session->isOtherParticipantAvaline()) return;
-
-	// Do not spawn chiclet when using the new multitab conversation UI
-	if (LLFloaterIMSessionTab::isChatMultiTab())
-	{
-		LLFloaterIMSessionTab::addToHost(session_id);
-		return;
-	}
-	
-	if (getChicletPanel()->findChiclet<LLChiclet>(session_id)) return;
-
-	LLIMChiclet* chiclet = createIMChiclet(session_id);
-	if(chiclet)
-	{
-		chiclet->setIMSessionName(name);
-		chiclet->setOtherParticipantId(other_participant_id);
-
-		LLFloaterIMSession::onIMChicletCreated(session_id);
-
-	}
-	else
-	{
-		llwarns << "Could not create chiclet" << llendl;
-	}
-}
-
-//virtual
-void LLChicletBar::sessionRemoved(const LLUUID& session_id)
-{
-	if(getChicletPanel())
-	{
-		// IM floater should be closed when session removed and associated chiclet closed
-		LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
-		if (im_floater != NULL && !im_floater->getStartConferenceInSameFloater())
-		{
-			// Close the IM floater only if we are not planning to close the P2P chat
-			// and start a new conference in the same floater.
-			im_floater->closeFloater();
-		}
-
-		getChicletPanel()->removeChiclet(session_id);
-	}
-}
-
-void LLChicletBar::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
-	//this is only needed in case of outgoing ad-hoc/group chat sessions
-	LLChicletPanel* chiclet_panel = getChicletPanel();
-	if (chiclet_panel)
-	{
-		//it should be ad-hoc im chiclet or group im chiclet
-		LLChiclet* chiclet = chiclet_panel->findChiclet<LLChiclet>(old_session_id);
-		if (chiclet) chiclet->setSessionId(new_session_id);
-	}
-}
-
-S32 LLChicletBar::getTotalUnreadIMCount()
-{
-	return getChicletPanel()->getTotalUnreadIMCount();
-}
-
 BOOL LLChicletBar::postBuild()
 {
 	mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
 	mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
 
-	showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
-
 	LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
 	LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
 
diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h
index dc991ca772..956c82cb77 100644
--- a/indra/newview/llchicletbar.h
+++ b/indra/newview/llchicletbar.h
@@ -28,7 +28,6 @@
 #define LL_LLCHICLETBAR_H
 
 #include "llpanel.h"
-#include "llimview.h"
 
 class LLChicletPanel;
 class LLIMChiclet;
@@ -38,32 +37,17 @@ class LLLayoutStack;
 class LLChicletBar
 	: public LLSingleton<LLChicletBar>
 	, public LLPanel
-	, public LLIMSessionObserver
 {
 	LOG_CLASS(LLChicletBar);
 	friend class LLSingleton<LLChicletBar>;
 public:
-	~LLChicletBar();
 
 	BOOL postBuild();
 
 	LLChicletPanel*	getChicletPanel() { return mChicletPanel; }
 
-	// LLIMSessionObserver observe triggers
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
-    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {};
-	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
-	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
-	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-
-	S32 getTotalUnreadIMCount();
-
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
 
-	/**
-	 * Creates IM Chiclet based on session type (IM chat or Group chat)
-	 */
-	LLIMChiclet* createIMChiclet(const LLUUID& session_id);
 
 	/**
 	 * Shows/hides panel with specified well button (IM or Notification)
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 212b0df712..9829ae713c 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -616,10 +616,14 @@ void LLFloaterIMSession::setVisible(BOOL visible)
 
 	if(!visible)
 	{
-		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
-		if(chiclet)
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
 		{
-			chiclet->setToggleState(false);
+			LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(mSessionID);
+			if(NULL != chicletp)
+			{
+				chicletp->setToggleState(false);
+			}
 		}
 	}
 
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index dc12192697..0e0da6bdc7 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -95,7 +95,12 @@ bool LLScriptFloater::toggle(const LLUUID& notification_id)
 		show(notification_id);
 	}
 
-	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(notification_id, true);
+	LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+	if (NULL != chiclet_panelp)
+	{
+		chiclet_panelp->setChicletToggleState(notification_id, true);
+	}
+
 	return true;
 }
 
@@ -206,10 +211,14 @@ void LLScriptFloater::setVisible(BOOL visible)
 
 	if(!visible)
 	{
-		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId());
-		if(chiclet)
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
 		{
-			chiclet->setToggleState(false);
+			LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(getNotificationId());
+			if(NULL != chicletp)
+			{
+				chicletp->setToggleState(false);
+			}
 		}
 	}
 }
@@ -218,15 +227,19 @@ void LLScriptFloater::onMouseDown()
 {
 	if(getNotificationId().notNull())
 	{
-		// Remove new message icon
-		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId());
-		if (chiclet == NULL)
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
 		{
-			llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
-		}
-		else
-		{
-			chiclet->setShowNewMessagesIcon(false);
+			LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(getNotificationId());
+			// Remove new message icon
+			if (NULL == chicletp)
+			{
+				llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
+			}
+			else
+			{
+				chicletp->setShowNewMessagesIcon(false);
+			}
 		}
 	}
 }
@@ -262,7 +275,11 @@ void LLScriptFloater::onFocusLost()
 {
 	if(getNotificationId().notNull())
 	{
-		LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), false);
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
+		{
+			chiclet_panelp->setChicletToggleState(getNotificationId(), false);
+		}
 	}
 }
 
@@ -271,7 +288,11 @@ void LLScriptFloater::onFocusReceived()
 	// first focus will be received before setObjectId() call - don't toggle chiclet
 	if(getNotificationId().notNull())
 	{
-		LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), true);
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
+		{
+			chiclet_panelp->setChicletToggleState(getNotificationId(), true);
+		}
 	}
 }
 
@@ -279,28 +300,30 @@ void LLScriptFloater::dockToChiclet(bool dock)
 {
 	if (getDockControl() == NULL)
 	{
-		LLChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(getNotificationId());
-		if (chiclet == NULL)
-		{
-			llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl;
-			return;
-		}
-		else
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
 		{
-			LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet);
-		}
+			LLChiclet * chicletp = chiclet_panelp->findChiclet<LLChiclet>(getNotificationId());
+			if (NULL == chicletp)
+			{
+				llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl;
+				return;
+			}
 
-		// Stop saving position while we dock floater
-		bool save = getSavePosition();
-		setSavePosition(false);
+			chiclet_panelp->scrollToChiclet(chicletp);
 
-		setDockControl(new LLDockControl(chiclet, this, getDockTongue(),
-			LLDockControl::BOTTOM));
+			// Stop saving position while we dock floater
+			bool save = getSavePosition();
+			setSavePosition(false);
 
-		setDocked(dock);
+			setDockControl(new LLDockControl(chicletp, this, getDockTongue(),
+				LLDockControl::BOTTOM));
 
-		// Restore saving
-		setSavePosition(save);
+			setDocked(dock);
+
+			// Restore saving
+			setSavePosition(save);
+		}
 	}
 }
 
@@ -347,11 +370,15 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
 		script_notification_map_t::const_iterator it = findUsingObjectId(object_id);
 		if(it != mNotifications.end())
 		{
-			LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(it->first);
-			if(chiclet)
+			LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+			if (NULL != chiclet_panelp)
 			{
-				// Pass the new_message icon state further.
-				set_new_message = chiclet->getShowNewMessagesIcon();
+				LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(it->first);
+				if(NULL != chicletp)
+				{
+					// Pass the new_message icon state further.
+					set_new_message = chicletp->getShowNewMessagesIcon();
+				}
 			}
 
 			LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first);
@@ -367,14 +394,18 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
 
 	mNotifications.insert(std::make_pair(notification_id, object_id));
 
-	// Create inventory offer chiclet for offer type notifications
-	if( OBJ_GIVE_INVENTORY == obj_type )
+	LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+	if (NULL != chiclet_panelp)
 	{
-		LLChicletBar::instance().getChicletPanel()->createChiclet<LLInvOfferChiclet>(notification_id);
-	}
-	else
-	{
-		LLChicletBar::getInstance()->getChicletPanel()->createChiclet<LLScriptChiclet>(notification_id);
+		// Create inventory offer chiclet for offer type notifications
+		if( OBJ_GIVE_INVENTORY == obj_type )
+		{
+			chiclet_panelp->createChiclet<LLInvOfferChiclet>(notification_id);
+		}
+		else
+		{
+			chiclet_panelp->createChiclet<LLScriptChiclet>(notification_id);
+		}
 	}
 
 	LLIMWellWindow::getInstance()->addObjectRow(notification_id, set_new_message);
@@ -410,7 +441,11 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
 	// remove related chiclet
 	if (LLChicletBar::instanceExists())
 	{
-		LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id);
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
+		{
+			chiclet_panelp->removeChiclet(notification_id);
+		}
 	}
 
 	LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 3605129d48..8a43855a7d 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -23,35 +23,23 @@
  * $/LicenseInfo$
  */
 
-
 #include "llviewerprecompiledheaders.h" // must be first include
-
 #include "llsyswellwindow.h"
 
-#include "llagent.h"
-#include "llavatarnamecache.h"
-
-#include "llflatlistview.h"
-#include "llfloaterreg.h"
-#include "llnotifications.h"
-
-#include "llscriptfloater.h"
-#include "llviewercontrol.h"
-#include "llviewerwindow.h"
-
 #include "llchiclet.h"
 #include "llchicletbar.h"
-#include "lltoastpanel.h"
+#include "llflatlistview.h"
+#include "llfloaterreg.h"
 #include "llnotificationmanager.h"
 #include "llnotificationsutil.h"
+#include "llscriptfloater.h"
 #include "llspeakers.h"
-#include "lltoolbarview.h"
+#include "lltoastpanel.h"
 
 //---------------------------------------------------------------------------------
 LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true,  key),
 													mChannel(NULL),
 													mMessageList(NULL),
-													mSysWellChiclet(NULL),
 													NOTIFICATION_WELL_ANCHOR_NAME("notification_well_panel"),
 													IM_WELL_ANCHOR_NAME("im_well_panel"),
 													mIsReshapedByUser(false)
@@ -68,10 +56,6 @@ BOOL LLSysWellWindow::postBuild()
 	// get a corresponding channel
 	initChannel();
 
-	// click on SysWell Window should clear "new message" state (and 'Lit' status). EXT-3147.
-	// mouse up callback is not called in this case.
-	setMouseDownCallback(boost::bind(&LLSysWellWindow::releaseNewMessagesState, this));
-
 	return LLTransientDockableFloater::postBuild();
 }
 
@@ -95,14 +79,6 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
 	setVisible(TRUE);
 }
 
-void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet) 
-{ 
-	mSysWellChiclet = chiclet;
-	if(NULL != mSysWellChiclet)
-	{
-		mSysWellChiclet->updateWidget(isWindowEmpty());
-	}
-}
 //---------------------------------------------------------------------------------
 LLSysWellWindow::~LLSysWellWindow()
 {
@@ -113,10 +89,6 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
 {
 	if(mMessageList->removeItemByValue(id))
 	{
-		if (NULL != mSysWellChiclet)
-		{
-			mSysWellChiclet->updateWidget(isWindowEmpty());
-		}
 		reshapeWindow();
 	}
 	else
@@ -170,11 +142,6 @@ void LLSysWellWindow::setVisible(BOOL visible)
 		mChannel->updateShowToastsState();
 		mChannel->redrawToasts();
 	}
-
-	if (visible)
-	{
-		releaseNewMessagesState();
-	}
 }
 
 //---------------------------------------------------------------------------------
@@ -224,135 +191,12 @@ void LLSysWellWindow::reshapeWindow()
 	}
 }
 
-void LLSysWellWindow::releaseNewMessagesState()
-{
-	if (NULL != mSysWellChiclet)
-	{
-		mSysWellChiclet->setNewMessagesState(false);
-	}
-}
-
 //---------------------------------------------------------------------------------
 bool LLSysWellWindow::isWindowEmpty()
 {
 	return mMessageList->size() == 0;
 }
 
-/************************************************************************/
-/*         RowPanel implementation                                      */
-/************************************************************************/
-
-//---------------------------------------------------------------------------------
-LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId,
-		S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) :
-		LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent)
-{
-	buildFromFile( "panel_activeim_row.xml");
-
-	// Choose which of the pre-created chiclets (IM/group) to use.
-	// The other one gets hidden.
-
-	LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(sessionId);
-	switch (im_chiclet_type)
-	{
-	case LLIMChiclet::TYPE_GROUP:
-		mChiclet = getChild<LLIMGroupChiclet>("group_chiclet");
-		break;
-	case LLIMChiclet::TYPE_AD_HOC:
-		mChiclet = getChild<LLAdHocChiclet>("adhoc_chiclet");		
-		break;
-	case LLIMChiclet::TYPE_UNKNOWN: // assign mChiclet a non-null value anyway
-	case LLIMChiclet::TYPE_IM:
-		mChiclet = getChild<LLIMP2PChiclet>("p2p_chiclet");
-		break;
-	}
-
-	// Initialize chiclet.
-	mChiclet->setChicletSizeChangedCallback(boost::bind(&LLIMWellWindow::RowPanel::onChicletSizeChanged, this, mChiclet, _2));
-	mChiclet->enableCounterControl(true);
-	mChiclet->setCounter(chicletCounter);
-	mChiclet->setSessionId(sessionId);
-	mChiclet->setIMSessionName(name);
-	mChiclet->setOtherParticipantId(otherParticipantId);
-	mChiclet->setVisible(true);
-
-	if (im_chiclet_type == LLIMChiclet::TYPE_IM)
-	{
-		LLAvatarNameCache::get(otherParticipantId,
-			boost::bind(&LLIMWellWindow::RowPanel::onAvatarNameCache,
-				this, _1, _2));
-	}
-	else
-	{
-		LLTextBox* contactName = getChild<LLTextBox>("contact_name");
-		contactName->setValue(name);
-	}
-
-	mCloseBtn = getChild<LLButton>("hide_btn");
-	mCloseBtn->setCommitCallback(boost::bind(&LLIMWellWindow::RowPanel::onClosePanel, this));
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onAvatarNameCache(const LLUUID& agent_id,
-												 const LLAvatarName& av_name)
-{
-	LLTextBox* contactName = getChild<LLTextBox>("contact_name");
-	contactName->setValue( av_name.getCompleteName() );
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
-{
-	LLTextBox* text = getChild<LLTextBox>("contact_name");
-	S32 new_text_left = mChiclet->getRect().mRight + CHICLET_HPAD;
-	LLRect text_rect = text->getRect(); 
-	text_rect.mLeft = new_text_left;
-	text->setShape(text_rect);
-}
-
-//---------------------------------------------------------------------------------
-LLIMWellWindow::RowPanel::~RowPanel()
-{
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onClosePanel()
-{
-	gIMMgr->leaveSession(mChiclet->getSessionId());
-	// This row panel will be removed from the list in LLSysWellWindow::sessionRemoved().
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask)
-{
-	setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected"));
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected"));
-}
-
-//---------------------------------------------------------------------------------
-// virtual
-BOOL LLIMWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	// Pass the mouse down event to the chiclet (EXT-596).
-	if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown()
-	{
-		mChiclet->onMouseDown();
-		return TRUE;
-	}
-
-	return LLPanel::handleMouseDown(x, y, mask);
-}
-
-// virtual
-BOOL LLIMWellWindow::RowPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-	return mChiclet->handleRightMouseDown(x, y, mask);
-}
 /************************************************************************/
 /*         ObjectRowPanel implementation                                */
 /************************************************************************/
@@ -490,9 +334,7 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
 	LLSysWellItem* new_item = new LLSysWellItem(p);
 	if (mMessageList->addItem(new_item, value, ADD_TOP))
 	{
-		mSysWellChiclet->updateWidget(isWindowEmpty());
 		reshapeWindow();
-
 		new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
 		new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
 	}
@@ -576,9 +418,6 @@ void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
 	removeItemByID(notify->getID());
 }
 
-
-
-
 /************************************************************************/
 /*         LLIMWellWindow  implementation                               */
 /************************************************************************/
@@ -588,12 +427,10 @@ void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
 LLIMWellWindow::LLIMWellWindow(const LLSD& key)
 : LLSysWellWindow(key)
 {
-	LLIMMgr::getInstance()->addSessionObserver(this);
 }
 
 LLIMWellWindow::~LLIMWellWindow()
 {
-	LLIMMgr::getInstance()->removeSessionObserver(this);
 }
 
 // static
@@ -614,47 +451,11 @@ BOOL LLIMWellWindow::postBuild()
 	BOOL rv = LLSysWellWindow::postBuild();
 	setTitle(getString("title_im_well_window"));
 
-	LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findIMChiclet, this, _1));
 	LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findObjectChiclet, this, _1));
 
 	return rv;
 }
 
-//virtual
-void LLIMWellWindow::sessionAdded(const LLUUID& session_id,
-								   const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
-{
-	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
-	if (!session) return;
-
-	// no need to spawn chiclets for participants in P2P calls called through Avaline
-	if (session->isP2P() && session->isOtherParticipantAvaline()) return;
-
-	if (mMessageList->getItemByValue(session_id)) return;
-
-	addIMRow(session_id, 0, name, other_participant_id);	
-	reshapeWindow();
-}
-
-//virtual
-void LLIMWellWindow::sessionRemoved(const LLUUID& sessionId)
-{
-	delIMRow(sessionId);
-	reshapeWindow();
-}
-
-//virtual
-void LLIMWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
-	//for outgoing ad-hoc and group im sessions only
-	LLChiclet* chiclet = findIMChiclet(old_session_id);
-	if (chiclet)
-	{
-		chiclet->setSessionId(new_session_id);
-		mMessageList->updateValue(old_session_id, new_session_id);
-	}
-}
-
 LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id)
 {
 	if (!mMessageList) return NULL;
@@ -671,66 +472,6 @@ LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id)
 
 //////////////////////////////////////////////////////////////////////////
 // PRIVATE METHODS
-LLChiclet* LLIMWellWindow::findIMChiclet(const LLUUID& sessionId)
-{
-	if (!mMessageList) return NULL;
-
-	LLChiclet* res = NULL;
-	RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId);
-	if (panel != NULL)
-	{
-		res = panel->mChiclet;
-	}
-
-	return res;
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
-							   const std::string& name, const LLUUID& otherParticipantId)
-{
-	RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId);
-	if (!mMessageList->addItem(item, sessionId))
-	{
-		llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId
-			<< ", name: " << name
-			<< ", other participant ID: " << otherParticipantId
-			<< llendl;
-
-		item->die();
-	}
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::delIMRow(const LLUUID& sessionId)
-{
-	//fix for EXT-3252
-	//without this line LLIMWellWindow receive onFocusLost
-	//and hide itself. It was becaue somehow LLIMChicklet was in focus group for
-	//LLIMWellWindow...
-	//But I didn't find why this happen..
-	gFocusMgr.clearLastFocusForGroup(this);
-
-	if (!mMessageList->removeItemByValue(sessionId))
-	{
-		llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId
-			<< llendl;
-	}
-
-	// remove all toasts that belong to this session from a screen
-	if(mChannel)
-		mChannel->removeToastsBySessionID(sessionId);
-
-	// hide chiclet window if there are no items left
-	if(isWindowEmpty())
-	{
-		setVisible(FALSE);
-	}
-	else
-	{
-		setFocus(true);
-	}
-}
 
 void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_message/* = false*/)
 {
@@ -761,21 +502,6 @@ void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
 	}
 }
 
-
-void LLIMWellWindow::addIMRow(const LLUUID& session_id)
-{
-	if (hasIMRow(session_id)) return;
-
-	LLIMModel* im_model = LLIMModel::getInstance();
-	addIMRow(session_id, 0, im_model->getName(session_id), im_model->getOtherParticipantID(session_id));
-	reshapeWindow();
-}
-
-bool LLIMWellWindow::hasIMRow(const LLUUID& session_id)
-{
-	return mMessageList->getItemByValue(session_id);
-}
-
 void LLIMWellWindow::closeAll()
 {
 	// Generate an ignorable alert dialog if there is an active voice IM sesion
@@ -820,13 +546,6 @@ void LLIMWellWindow::closeAllImpl()
 	{
 		LLPanel* panel = mMessageList->getItemByValue(*iter);
 
-		RowPanel* im_panel = dynamic_cast <RowPanel*> (panel);
-		if (im_panel)
-		{
-			gIMMgr->leaveSession(*iter);
-			continue;
-		}
-
 		ObjectRowPanel* obj_panel = dynamic_cast <ObjectRowPanel*> (panel);
 		if (obj_panel)
 		{
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index d6480f1fc6..406ab1b59e 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -27,32 +27,26 @@
 #ifndef LL_LLSYSWELLWINDOW_H
 #define LL_LLSYSWELLWINDOW_H
 
-#include "llsyswellitem.h"
-
-#include "lltransientdockablefloater.h"
-#include "llbutton.h"
-#include "llscreenchannel.h"
-#include "llscrollcontainer.h"
 #include "llimview.h"
 #include "llnotifications.h"
-
-#include "boost/shared_ptr.hpp"
+#include "llscreenchannel.h"
+#include "llsyswellitem.h"
+#include "lltransientdockablefloater.h"
 
 class LLAvatarName;
-class LLFlatListView;
 class LLChiclet;
+class LLFlatListView;
 class LLIMChiclet;
 class LLScriptChiclet;
 class LLSysWellChiclet;
 
-
 class LLSysWellWindow : public LLTransientDockableFloater
 {
 public:
 	LOG_CLASS(LLSysWellWindow);
 
     LLSysWellWindow(const LLSD& key);
-    ~LLSysWellWindow();
+    virtual ~LLSysWellWindow();
 	BOOL postBuild();
 
 	// other interface functions
@@ -72,8 +66,6 @@ public:
 
 	void onStartUpToastClick(S32 x, S32 y, MASK mask);
 
-	void setSysWellChiclet(LLSysWellChiclet* chiclet);
-
 	// size constants for the window and for its elements
 	static const S32 MAX_WINDOW_HEIGHT		= 200;
 	static const S32 MIN_WINDOW_WIDTH		= 318;
@@ -87,17 +79,11 @@ protected:
 	virtual const std::string& getAnchorViewName() = 0;
 
 	void reshapeWindow();
-	void releaseNewMessagesState();
 
 	// pointer to a corresponding channel's instance
 	LLNotificationsUI::LLScreenChannel*	mChannel;
 	LLFlatListView*	mMessageList;
 
-	/**
-	 * Reference to an appropriate Well chiclet to release "new message" state. EXT-3147
-	 */
-	LLSysWellChiclet* mSysWellChiclet;
-
 	bool mIsReshapedByUser;
 };
 
@@ -157,7 +143,7 @@ private:
  * 
  * It contains a list list of all active IM sessions.
  */
-class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<LLIMWellWindow>
+class LLIMWellWindow : public LLSysWellWindow, LLInitClass<LLIMWellWindow>
 {
 public:
 	LLIMWellWindow(const LLSD& key);
@@ -169,59 +155,19 @@ public:
 
 	/*virtual*/ BOOL postBuild();
 
-	// LLIMSessionObserver observe triggers
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
-    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
-	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id) {};
-	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
-	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-
 	void addObjectRow(const LLUUID& notification_id, bool new_message = false);
 	void removeObjectRow(const LLUUID& notification_id);
-
-	void addIMRow(const LLUUID& session_id);
-	bool hasIMRow(const LLUUID& session_id);
-
 	void closeAll();
 
 protected:
 	/*virtual*/ const std::string& getAnchorViewName() { return IM_WELL_ANCHOR_NAME; }
 
 private:
-	LLChiclet * findIMChiclet(const LLUUID& sessionId);
 	LLChiclet* findObjectChiclet(const LLUUID& notification_id);
 
-	void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId);
-	void delIMRow(const LLUUID& sessionId);
 	bool confirmCloseAll(const LLSD& notification, const LLSD& response);
 	void closeAllImpl();
 
-	/**
-	 * Scrolling row panel.
-	 */
-	class RowPanel: public LLPanel
-	{
-	public:
-		RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter,
-				const std::string& name, const LLUUID& otherParticipantId);
-		virtual ~RowPanel();
-		void onMouseEnter(S32 x, S32 y, MASK mask);
-		void onMouseLeave(S32 x, S32 y, MASK mask);
-		BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-		BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-
-	private:
-		static const S32 CHICLET_HPAD = 10;
-		void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-		void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
-		void onClosePanel();
-	public:
-		LLIMChiclet* mChiclet;
-	private:
-		LLButton*	mCloseBtn;
-		const LLSysWellWindow* mParent;
-	};
-
 	class ObjectRowPanel: public LLPanel
 	{
 	public:
diff --git a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png
deleted file mode 100644
index 0ac5b72b8f..0000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png
deleted file mode 100644
index 857fa1e047..0000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png
deleted file mode 100644
index 453bb53673..0000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png
deleted file mode 100644
index 135a66ca0d..0000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png
deleted file mode 100644
index a63aec5e6d..0000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png
deleted file mode 100644
index 1719eb3e84..0000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 8d9fa52309..bf6e933dfd 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -365,8 +365,6 @@ with the same filename but different name
 
   <texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" />
 
-  <texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" />
-
   <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" />
   <texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" />
 
@@ -654,12 +652,6 @@ with the same filename but different name
   <texture name="VoicePTT_Off" file_name="bottomtray/VoicePTT_Off.png" preload="false" />
   <texture name="VoicePTT_On" file_name="bottomtray/VoicePTT_On.png" preload="false" />
   
-  <texture name="VoicePTT_Lvl1_Dark" file_name="bottomtray/VoicePTT_Lvl1_Dark.png" preload="false" />
-  <texture name="VoicePTT_Lvl2_Dark" file_name="bottomtray/VoicePTT_Lvl2_Dark.png" preload="false" />
-  <texture name="VoicePTT_Lvl3_Dark" file_name="bottomtray/VoicePTT_Lvl3_Dark.png" preload="false" />
-  <texture name="VoicePTT_Off_Dark" file_name="bottomtray/VoicePTT_Off_Dark.png" preload="false" />
-  <texture name="VoicePTT_On_Dark" file_name="bottomtray/VoicePTT_On_Dark.png" preload="false" />
-
   <texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" />
 
   <texture name="Web_Profile_Off" file_name="icons/Web_Profile_Off.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/da/menu_im_well_button.xml b/indra/newview/skins/default/xui/da/menu_im_well_button.xml
deleted file mode 100644
index 4889230919..0000000000
--- a/indra/newview/skins/default/xui/da/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Luk alle" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
deleted file mode 100644
index 40b35b5fdd..0000000000
--- a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Luk alle" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_im_well_button.xml b/indra/newview/skins/default/xui/de/menu_im_well_button.xml
deleted file mode 100644
index f464b71f4a..0000000000
--- a/indra/newview/skins/default/xui/de/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Alle schließen" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
deleted file mode 100644
index 0f2784f160..0000000000
--- a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Alle schließen" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
deleted file mode 100644
index 263ac40f4e..0000000000
--- a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<context_menu
- layout="topleft"
- name="Notification Well Button Context Menu">
-    <menu_item_call
-     label="Close All"
-     layout="topleft"
-     name="Close All">
-        <menu_item_call.on_click
-         function="NotificationWellChicletMenu.Action"
-         parameter="close all" />
-        <menu_item_call.on_enable
-         function="NotificationWellChicletMenu.EnableItem"
-         parameter="can close all" />
-    </menu_item_call>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
deleted file mode 100644
index 9369d1b5cf..0000000000
--- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-	name="panel_activeim_row"
-	layout="topleft"
-	follows="left|right"
-	top="0"
-	left="0"
-	height="35"
-	width="318"
-  background_opaque="false"
-  background_visible="true"
-  bg_alpha_color="0.0 0.0 0.0 0.0" >
-  <chiclet_im_p2p
-		name="p2p_chiclet"
-		layout="topleft"
-		follows="left"
-		top="3"
-		left="5"
-		height="25"
-		width="25"
-    visible="false"
-    speaker.name="speaker_p2p"
-    speaker.width="20"
-    speaker.height="25"
-    speaker.left="25"
-    speaker.top="25"
-    speaker.auto_update="true"
-    speaker.draw_border="false"
-    speaker.visible="false">
-  </chiclet_im_p2p>
-  <chiclet_im_group
-		name="group_chiclet"
-		layout="topleft"
-		follows="left"
-		top="3"
-		left="5"
-		height="25"
-		width="25"
-    visible="false"
-    speaker.name="speaker_grp"
-    speaker.width="20"
-    speaker.height="25"
-    speaker.left="25"
-    speaker.top="25"
-    speaker.auto_update="true"
-    speaker.draw_border="false"
-    speaker.visible="false">
-  </chiclet_im_group>
-  <chiclet_im_adhoc
-		name="adhoc_chiclet"
-		layout="topleft"
-		follows="left"
-		top="3"
-		left="5"
-		height="25"
-		width="25"
-    visible="false"
-    speaker.name="speaker_hoc"
-    speaker.width="20"
-    speaker.height="25"
-    speaker.left="25"
-    speaker.top="25"
-    speaker.auto_update="true"
-    speaker.draw_border="false"
-    speaker.visible="false">
-  </chiclet_im_adhoc>
-	<text
-	    translate="false"
-		type="string"
-		name="contact_name"
-		layout="topleft"
-		top="10"
-		left_pad="10"
-		height="14"
-		width="250"
-		length="1"
-		follows="right|left"
-		parse_urls="false"
-		use_ellipses="true"
-		font="SansSerifBold">
-    TestString PleaseIgnore
-  </text>
-  <button
-    top="10"
-    right="-5"
-    width="17"
-    height="17"
-    layout="topleft"
-    follows="right"
-    name="hide_btn"
-    mouse_opaque="true"
-    label=""
-    tab_stop="false"
-    image_unselected="Toast_CloseBtn"
-    image_selected="Toast_CloseBtn"
-  />
-</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
index fc321fdd23..390047d493 100644
--- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
@@ -77,49 +77,5 @@
                  width="12" />
       </chiclet_panel>
     </layout_panel>
-    <layout_panel auto_resize="false"
-                      width="4"
-                      min_width="4"/>
-    <layout_panel
-         auto_resize="false"
-         follows="right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         min_width="37"
-         name="notification_well_panel"
-         top="0"
-         width="37">
-      <chiclet_notification
-             follows="right"
-             height="23"
-             layout="topleft"
-             left="0"
-             max_displayed_count="99"
-             name="notification_well"
-             top="5"
-             width="35">
-        <button
-                 auto_resize="false"
-                 bottom_pad="3"
-                 follows="right"
-                 halign="center"
-                 height="23"
-                 image_overlay="Notices_Unread"
-                 image_overlay_alignment="center"
-                 image_pressed="WellButton_Lit"
-                 image_pressed_selected="WellButton_Lit_Selected"
-                 image_selected="PushButton_Press"
-                 label_color="Black"
-                 left="0"
-                 name="Unread"
-                 tool_tip="Notifications"
-                 width="34">
-          <init_callback
-                     function="Button.SetDockableFloaterToggle"
-                     parameter="notification_well_window" />
-        </button>
-      </chiclet_notification>
-    </layout_panel>
   </layout_stack>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
deleted file mode 100644
index 0e29ed0d0b..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_adhoc
- height="23"
- name="im_adhoc_chiclet"
- show_speaker="false"
- width="25">
-    <chiclet_im_adhoc.chiclet_button
-     height="25"
-     image_selected="PushButton_On"
-     image_unselected="PushButton_Off"
-     name="chiclet_button"
-     tab_stop="false"
-     width="25" />
-    <chiclet_im_adhoc.speaker
-      image_mute="Parcel_VoiceNo_Light"
-      image_off="VoicePTT_Off_Dark"
-      image_on="VoicePTT_On_Dark"
-      image_level_1="VoicePTT_Lvl1_Dark"
-      image_level_2="VoicePTT_Lvl2_Dark"
-      image_level_3="VoicePTT_Lvl3_Dark"
-      auto_update="true"
-      draw_border="false"
-      height="24"
-      left="25"
-      bottom="1"      
-      name="speaker"
-      visible="false"
-      width="20" />
-    <chiclet_im_adhoc.avatar_icon
-     bottom="3"
-     follows="left|top|bottom"
-     height="20"
-     left="2"
-     mouse_opaque="false"
-     name="adhoc_icon"
-     width="21" />
-    <chiclet_im_adhoc.unread_notifications
-     halign="center"
-     height="23"
-     left="25"
-     mouse_opaque="false"
-     name="unread"
-     text_color="white"
-     v_pad="3"
-     visible="false"
-     width="20" />
-    <chiclet_im_adhoc.new_message_icon
-  bottom="11"
-  height="14"
-  image_name="Unread_Chiclet"
-  left="12"
-  name="new_message_icon"
-  visible="false"
-  width="14" />
-</chiclet_im_adhoc>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
deleted file mode 100644
index 77011139bf..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_group
- height="23"
- name="im_group_chiclet"
- show_speaker="false"
- width="25">
-    <chiclet_im_group.chiclet_button
-     height="25"
-     image_selected="PushButton_On"
-     image_unselected="PushButton_Off"
-     name="chiclet_button"
-     tab_stop="false"
-     width="25" />
-    <chiclet_im_group.speaker
-      image_mute="Parcel_VoiceNo_Light"
-      image_off="VoicePTT_Off_Dark"
-      image_on="VoicePTT_On_Dark"
-      image_level_1="VoicePTT_Lvl1_Dark"
-      image_level_2="VoicePTT_Lvl2_Dark"
-      image_level_3="VoicePTT_Lvl3_Dark"
-      auto_update="true"
-      draw_border="false"
-      height="24"
-      left="25"
-      bottom="1"      
-      name="speaker"
-      visible="false"
-      width="20" />
-    <chiclet_im_group.group_icon
-     bottom="3"
-     default_icon="Generic_Group"
-     follows="left|top|bottom"
-     height="20"
-     left="2"
-     mouse_opaque="false"
-     name="group_icon"
-     width="21" />
-    <chiclet_im_group.unread_notifications
-     height="23"
-     halign="center"
-     left="25"
-     mouse_opaque="false"
-     name="unread"
-     text_color="white"
-     v_pad="3"
-     visible="false"
-     width="20"/>
-    <chiclet_im_group.new_message_icon
-bottom="11"
-  height="14"
-  image_name="Unread_Chiclet"
-  left="12"
-  name="new_message_icon"
-  visible="false"
-  width="14" />
-</chiclet_im_group>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
deleted file mode 100644
index 8b56a8f0f6..0000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_p2p
- height="23"
- name="im_p2p_chiclet"
- show_speaker="false"
- width="25">
-    <chiclet_im_p2p.chiclet_button
-     height="25"
-     image_selected="PushButton_On"
-     image_unselected="PushButton_Off"
-     name="chiclet_button"
-     tab_stop="false"
-     width="25"/>
-    <chiclet_im_p2p.speaker
-      image_mute="Parcel_VoiceNo_Light"
-      image_off="VoicePTT_Off_Dark"
-      image_on="VoicePTT_On_Dark"
-      image_level_1="VoicePTT_Lvl1_Dark"
-      image_level_2="VoicePTT_Lvl2_Dark"
-      image_level_3="VoicePTT_Lvl3_Dark"
-      auto_update="true"
-      draw_border="false"
-      height="24"
-      left="25"
-      bottom="1"
-      name="speaker"
-      visible="false"
-      width="20" />
-    <chiclet_im_p2p.avatar_icon
-     bottom="3"
-     color="white"
-     follows="left|top|bottom"
-     height="20"
-     left="2"
-     mouse_opaque="false"
-     name="avatar_icon"
-     width="21" />
-    <chiclet_im_p2p.unread_notifications
-     height="23"
-     halign="center"
-     left="25"
-     mouse_opaque="false"
-     name="unread"
-     text_color="white"
-     v_pad="3"
-     visible="false"
-     width="20"/>
-    <chiclet_im_p2p.new_message_icon
-  bottom="11"
-  height="14"
-  image_name="Unread_Chiclet"
-  left="12"
-  name="new_message_icon"
-  visible="false"
-  width="14" />
-</chiclet_im_p2p>
diff --git a/indra/newview/skins/default/xui/es/menu_im_well_button.xml b/indra/newview/skins/default/xui/es/menu_im_well_button.xml
deleted file mode 100644
index c8f6c217cc..0000000000
--- a/indra/newview/skins/default/xui/es/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Cerrar todo" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
deleted file mode 100644
index 0562d35be7..0000000000
--- a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Cerrar todo" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml b/indra/newview/skins/default/xui/fr/menu_im_well_button.xml
deleted file mode 100644
index 8ef1529e6b..0000000000
--- a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Tout fermer" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
deleted file mode 100644
index 323bfdbf16..0000000000
--- a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Tout fermer" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_im_well_button.xml b/indra/newview/skins/default/xui/it/menu_im_well_button.xml
deleted file mode 100644
index 9e471b771c..0000000000
--- a/indra/newview/skins/default/xui/it/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Chiudi tutto" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
deleted file mode 100644
index 8c82e30f0e..0000000000
--- a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Chiudi tutto" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml b/indra/newview/skins/default/xui/ja/menu_im_well_button.xml
deleted file mode 100644
index 3397004bd7..0000000000
--- a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="すべて閉じる" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
deleted file mode 100644
index 913bae8958..0000000000
--- a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="すべて閉じる" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml b/indra/newview/skins/default/xui/pl/menu_im_well_button.xml
deleted file mode 100644
index 207bc2211b..0000000000
--- a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Zamknij wszystkie" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
deleted file mode 100644
index bd3d42f9b1..0000000000
--- a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Zamknij" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml b/indra/newview/skins/default/xui/pt/menu_im_well_button.xml
deleted file mode 100644
index 2d37cefd6f..0000000000
--- a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Fechar tudo" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
deleted file mode 100644
index 43ad4134ec..0000000000
--- a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Fechar tudo" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml b/indra/newview/skins/default/xui/ru/menu_im_well_button.xml
deleted file mode 100644
index 5a5bde61b9..0000000000
--- a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Закрыть все" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
deleted file mode 100644
index 4d067e232a..0000000000
--- a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Закрыть все" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml b/indra/newview/skins/default/xui/tr/menu_im_well_button.xml
deleted file mode 100644
index c3e559a723..0000000000
--- a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Tümünü Kapat" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
deleted file mode 100644
index 39c66268f5..0000000000
--- a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="Tümünü Kapat" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml b/indra/newview/skins/default/xui/zh/menu_im_well_button.xml
deleted file mode 100644
index 4b9b4b2758..0000000000
--- a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="全部關閉" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
deleted file mode 100644
index b629f73584..0000000000
--- a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="Notification Well Button Context Menu">
-	<menu_item_call label="全部關閉" name="Close All"/>
-</context_menu>
-- 
cgit v1.2.3


From 60c72c85e2360284ecc3326871dcc76fcce0e945 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Mon, 3 Dec 2012 19:06:52 -0800
Subject: Cleaning up some unreferenced member variables and related types from
 LLNotifications.

---
 indra/llui/CMakeLists.txt              |   2 -
 indra/llui/llnotifications.cpp         |   3 -
 indra/llui/llnotifications.h           |   4 -
 indra/llui/llnotificationslistener.cpp | 354 ---------------------------------
 indra/llui/llnotificationslistener.h   |  69 -------
 indra/llui/llnotificationtemplate.h    |   1 -
 6 files changed, 433 deletions(-)
 delete mode 100644 indra/llui/llnotificationslistener.cpp
 delete mode 100644 indra/llui/llnotificationslistener.h

(limited to 'indra')

diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index ccc7aa8cec..9c961d67d6 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -71,7 +71,6 @@ set(llui_SOURCE_FILES
     llmultislider.cpp
     llmultisliderctrl.cpp
     llnotifications.cpp
-    llnotificationslistener.cpp
     llnotificationsutil.cpp
     llpanel.cpp
     llprogressbar.cpp
@@ -181,7 +180,6 @@ set(llui_HEADER_FILES
     llmultislider.h
     llnotificationptr.h
     llnotifications.h
-    llnotificationslistener.h
     llnotificationsutil.h
     llnotificationtemplate.h
     llnotificationvisibilityrule.h
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 66144671c9..61d5dcf12c 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -39,7 +39,6 @@
 #include "lldir.h"
 #include "llsdserialize.h"
 #include "lltrans.h"
-#include "llnotificationslistener.h"
 #include "llstring.h"
 #include "llsdparam.h"
 #include "llsdutil.h"
@@ -1167,8 +1166,6 @@ LLNotifications::LLNotifications()
 	mIgnoreAllNotifications(false)
 {
 	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
-
-    mListener.reset(new LLNotificationsListener(*this));
 }
 
 
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 088931858a..a41e9fa5a3 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -92,7 +92,6 @@
 #include "llevents.h"
 #include "llfunctorregistry.h"
 #include "llinitparam.h"
-#include "llnotificationslistener.h"
 #include "llnotificationptr.h"
 #include "llpointer.h"
 #include "llrefcount.h"
@@ -672,7 +671,6 @@ namespace LLNotificationComparators
 };
 
 typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
-typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
 typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet;
 typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
 
@@ -822,7 +820,6 @@ public:
 private:
 	std::string mName;
 	std::string mParent;
-	LLNotificationComparator mComparator;
 };
 
 // An interface class to provide a clean linker seam to the LLNotifications class.
@@ -942,7 +939,6 @@ private:
 
 	bool mIgnoreAllNotifications;
 
-    boost::scoped_ptr<LLNotificationsListener> mListener;
 	std::vector<LLNotificationChannelPtr> mDefaultChannels;
 };
 
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
deleted file mode 100644
index e4e127336b..0000000000
--- a/indra/llui/llnotificationslistener.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/**
- * @file   llnotificationslistener.cpp
- * @author Brad Kittenbrink
- * @date   2009-07-08
- * @brief  Implementation for llnotificationslistener.
- * 
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "llnotificationslistener.h"
-#include "llnotifications.h"
-#include "llnotificationtemplate.h"
-#include "llsd.h"
-#include "llui.h"
-
-LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
-    LLEventAPI("LLNotifications",
-               "LLNotifications listener to (e.g.) pop up a notification"),
-    mNotifications(notifications)
-{
-    add("requestAdd",
-        "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
-        "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
-        &LLNotificationsListener::requestAdd);
-    add("listChannels",
-        "Post to [\"reply\"] a map of info on existing channels",
-        &LLNotificationsListener::listChannels,
-        LLSD().with("reply", LLSD()));
-    add("listChannelNotifications",
-        "Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
-        &LLNotificationsListener::listChannelNotifications,
-        LLSD().with("reply", LLSD()).with("channel", LLSD()));
-    add("respond",
-        "Respond to notification [\"uuid\"] with data in [\"response\"]",
-        &LLNotificationsListener::respond,
-        LLSD().with("uuid", LLSD()));
-    add("cancel",
-        "Cancel notification [\"uuid\"]",
-        &LLNotificationsListener::cancel,
-        LLSD().with("uuid", LLSD()));
-    add("ignore",
-        "Ignore future notification [\"name\"]\n"
-        "(from <notification name= > in notifications.xml)\n"
-        "according to boolean [\"ignore\"].\n"
-        "If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n"
-        "Note that ignored notifications are not forwarded unless intercepted before\n"
-        "the \"Ignore\" channel.",
-        &LLNotificationsListener::ignore);
-    add("forward",
-        "Forward to [\"pump\"] future notifications on channel [\"channel\"]\n"
-        "according to boolean [\"forward\"]. When enabled, only types matching\n"
-        "[\"types\"] are forwarded, as follows:\n"
-        "omitted or undefined: forward all notifications\n"
-        "string: forward only the specific named [sig]type\n"
-        "array of string: forward any notification matching any named [sig]type.\n"
-        "When boolean [\"respond\"] is true, we auto-respond to each forwarded\n"
-        "notification.",
-        &LLNotificationsListener::forward,
-        LLSD().with("channel", LLSD()));
-}
-
-// This is here in the .cpp file so we don't need the definition of class
-// Forwarder in the header file.
-LLNotificationsListener::~LLNotificationsListener()
-{
-}
-
-void LLNotificationsListener::requestAdd(const LLSD& event_data) const
-{
-	if(event_data.has("reply"))
-	{
-		mNotifications.add(event_data["name"], 
-						   event_data["substitutions"], 
-						   event_data["payload"],
-						   boost::bind(&LLNotificationsListener::NotificationResponder, 
-									   this, 
-									   event_data["reply"].asString(), 
-									   _1, _2
-									   )
-						   );
-	}
-	else
-	{
-		mNotifications.add(event_data["name"], 
-						   event_data["substitutions"], 
-						   event_data["payload"]);
-	}
-}
-
-void LLNotificationsListener::NotificationResponder(const std::string& reply_pump, 
-										const LLSD& notification, 
-										const LLSD& response) const
-{
-	LLSD reponse_event;
-	reponse_event["notification"] = notification;
-	reponse_event["response"] = response;
-	LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
-}
-
-void LLNotificationsListener::listChannels(const LLSD& params) const
-{
-    LLReqID reqID(params);
-    LLSD response(reqID.makeResponse());
-    for (LLNotificationChannel::instance_iter cmi(LLNotificationChannel::beginInstances()),
-                                                     cmend(LLNotificationChannel::endInstances());
-         cmi != cmend; ++cmi)
-    {
-        LLSD channelInfo;
-        //channelInfo["parent"] = cmi->second->getParentChannelName();
-        response[cmi->getName()] = channelInfo;
-    }
-    LLEventPumps::instance().obtain(params["reply"]).post(response);
-}
-
-void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
-{
-    LLReqID reqID(params);
-    LLSD response(reqID.makeResponse());
-    LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"]));
-    if (channel)
-    {
-        LLSD notifications(LLSD::emptyArray());
-        for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
-             ni != nend; ++ni)
-        {
-            notifications.append(asLLSD(*ni));
-        }
-        response["notifications"] = notifications;
-    }
-    LLEventPumps::instance().obtain(params["reply"]).post(response);
-}
-
-void LLNotificationsListener::respond(const LLSD& params) const
-{
-    LLNotificationPtr notification(mNotifications.find(params["uuid"]));
-    if (notification)
-    {
-        notification->respond(params["response"]);
-    }
-}
-
-void LLNotificationsListener::cancel(const LLSD& params) const
-{
-    LLNotificationPtr notification(mNotifications.find(params["uuid"]));
-    if (notification)
-    {
-        mNotifications.cancel(notification);
-    }
-}
-
-void LLNotificationsListener::ignore(const LLSD& params) const
-{
-    // Calling a method named "ignore", but omitting its "ignore" Boolean
-    // argument, should by default cause something to be ignored. Explicitly
-    // pass ["ignore"] = false to cancel ignore.
-    bool ignore = true;
-    if (params.has("ignore"))
-    {
-        ignore = params["ignore"].asBoolean();
-    }
-    // This method can be used to affect either a single notification name or
-    // all future notifications. The two use substantially different mechanisms.
-    if (params["name"].isDefined())
-    {
-        // ["name"] was passed: ignore just that notification
-		LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
-		if (templatep)
-		{
-			templatep->mForm->setIgnored(ignore);
-		}
-    }
-    else
-    {
-        // no ["name"]: ignore all future notifications
-        mNotifications.setIgnoreAllNotifications(ignore);
-    }
-}
-
-class LLNotificationsListener::Forwarder: public LLEventTrackable
-{
-    LOG_CLASS(LLNotificationsListener::Forwarder);
-public:
-    Forwarder(LLNotifications& llnotifications, const std::string& channel):
-        mNotifications(llnotifications),
-        mRespond(false)
-    {
-        // Connect to the specified channel on construction. Because
-        // LLEventTrackable is a base, we should automatically disconnect when
-        // destroyed.
-        LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel));
-        if (channelptr)
-        {
-            // Insert our processing as a "passed filter" listener. This way
-            // we get to run before all the "changed" listeners, and we get to
-            // swipe it (hide it from the other listeners) if desired.
-            channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1));
-        }
-    }
-
-    void setPumpName(const std::string& name) { mPumpName = name; }
-    void setTypes(const LLSD& types) { mTypes = types; }
-    void setRespond(bool respond) { mRespond = respond; }
-
-private:
-    bool handle(const LLSD& notification) const;
-    bool matchType(const LLSD& filter, const std::string& type) const;
-
-    LLNotifications& mNotifications;
-    std::string mPumpName;
-    LLSD mTypes;
-    bool mRespond;
-};
-
-void LLNotificationsListener::forward(const LLSD& params)
-{
-    std::string channel(params["channel"]);
-    // First decide whether we're supposed to start forwarding or stop it.
-    // Default to true.
-    bool forward = true;
-    if (params.has("forward"))
-    {
-        forward = params["forward"].asBoolean();
-    }
-    if (! forward)
-    {
-        // This is a request to stop forwarding notifications on the specified
-        // channel. The rest of the params don't matter.
-        // Because mForwarders contains scoped_ptrs, erasing the map entry
-        // DOES delete the heap Forwarder object. Because Forwarder derives
-        // from LLEventTrackable, destroying it disconnects it from the
-        // channel.
-        mForwarders.erase(channel);
-        return;
-    }
-    // From here on, we know we're being asked to start (or modify) forwarding
-    // on the specified channel. Find or create an appropriate Forwarder.
-    ForwarderMap::iterator
-        entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
-    if (! entry->second)
-    {
-        entry->second.reset(new Forwarder(mNotifications, channel));
-    }
-    // Now, whether this Forwarder is brand-new or not, update it with the new
-    // request info.
-    Forwarder& fwd(*entry->second);
-    fwd.setPumpName(params["pump"]);
-    fwd.setTypes(params["types"]);
-    fwd.setRespond(params["respond"]);
-}
-
-bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const
-{
-    LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL;
-    if (notification["sigtype"].asString() == "delete")
-    {
-        LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL;
-        // let other listeners see the "delete" operation
-        return false;
-    }
-    LLNotificationPtr note(mNotifications.find(notification["id"]));
-    if (! note)
-    {
-        LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL;
-        return false;
-    }
-    if (! matchType(mTypes, note->getType()))
-    {
-        LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL;
-        // We're not supposed to intercept this particular notification. Let
-        // other listeners process it.
-        return false;
-    }
-    LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL;
-    // This is a notification we care about. Forward it through specified
-    // LLEventPump.
-    LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note));
-    // Are we also being asked to auto-respond?
-    if (mRespond)
-    {
-        LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL;
-        note->respond(LLSD::emptyMap());
-        // Did that succeed in removing the notification? Only cancel() if
-        // it's still around -- otherwise we get an LL_ERRS crash!
-        note = mNotifications.find(notification["id"]);
-        if (note)
-        {
-            LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL;
-            mNotifications.cancel(note);
-        }
-    }
-    // If we've auto-responded to this notification, then it's going to be
-    // deleted. Other listeners would get the change operation, try to look it
-    // up and be baffled by lookup failure. So when we auto-respond, suppress
-    // this notification: don't pass it to other listeners.
-    return mRespond;
-}
-
-bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
-{
-    // Decide whether this notification matches filter:
-    // undefined: forward all notifications
-    if (filter.isUndefined())
-    {
-        return true;
-    }
-    // array of string: forward any notification matching any named type
-    if (filter.isArray())
-    {
-        for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
-             ti != tend; ++ti)
-        {
-            if (ti->asString() == type)
-            {
-                return true;
-            }
-        }
-        // Didn't match any entry in the array
-        return false;
-    }
-    // string: forward only the specific named type
-    return (filter.asString() == type);
-}
-
-LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
-{
-    LLSD notificationInfo(note->asLLSD());
-    // For some reason the following aren't included in LLNotification::asLLSD().
-    notificationInfo["summary"] = note->summarize();
-    notificationInfo["id"]      = note->id();
-    notificationInfo["type"]    = note->getType();
-    notificationInfo["message"] = note->getMessage();
-    notificationInfo["label"]   = note->getLabel();
-    return notificationInfo;
-}
diff --git a/indra/llui/llnotificationslistener.h b/indra/llui/llnotificationslistener.h
deleted file mode 100644
index f9f7641de6..0000000000
--- a/indra/llui/llnotificationslistener.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file   llnotificationslistener.h
- * @author Brad Kittenbrink
- * @date   2009-07-08
- * @brief  Wrap subset of LLNotifications API in event API for test scripts.
- * 
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLNOTIFICATIONSLISTENER_H
-#define LL_LLNOTIFICATIONSLISTENER_H
-
-#include "lleventapi.h"
-#include "llnotificationptr.h"
-#include <boost/shared_ptr.hpp>
-#include <map>
-#include <string>
-
-class LLNotifications;
-class LLSD;
-
-class LLNotificationsListener : public LLEventAPI
-{
-public:
-    LLNotificationsListener(LLNotifications & notifications);
-    ~LLNotificationsListener();
-
-private:
-    void requestAdd(LLSD const & event_data) const;
-
-	void NotificationResponder(const std::string& replypump, 
-							   const LLSD& notification, 
-							   const LLSD& response) const;
-
-    void listChannels(const LLSD& params) const;
-    void listChannelNotifications(const LLSD& params) const;
-    void respond(const LLSD& params) const;
-    void cancel(const LLSD& params) const;
-    void ignore(const LLSD& params) const;
-    void forward(const LLSD& params);
-
-    static LLSD asLLSD(LLNotificationPtr);
-
-    class Forwarder;
-    typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap;
-    ForwarderMap mForwarders;
-	LLNotifications & mNotifications;
-};
-
-#endif // LL_LLNOTIFICATIONSLISTENER_H
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 906b83a400..18a82190b5 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -49,7 +49,6 @@
 //#include "llfunctorregistry.h"
 //#include "llpointer.h"
 #include "llinitparam.h"
-//#include "llnotificationslistener.h"
 //#include "llnotificationptr.h"
 //#include "llcachename.h"
 #include "llnotifications.h"
-- 
cgit v1.2.3


From 8c24cc8e3635888b766e30001749966eddc0dc7e Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 4 Dec 2012 14:38:19 +0200
Subject: CHUI-527 FIXED Changed term to "Multi-person chat"

---
 indra/newview/skins/default/xui/en/strings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index a884ac94d6..c75bd98c38 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3400,7 +3400,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
     Connecting...
   </string>
   <string name="conference-title">
-    Ad-hoc Conference
+    Multi-person chat
   </string>
   <string name="conference-title-incoming">
     Conference with [AGENT_NAME]
-- 
cgit v1.2.3


From ed9e48bf6bd440a004c0d82da79503de34261610 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 4 Dec 2012 14:48:59 +0200
Subject: CHUI-530 FIXED Using selectConversationPair will show appropriate
 session floater.

---
 indra/newview/llfloaterimcontainer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 3a80491dae..c1daea0aeb 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1162,7 +1162,7 @@ bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_ve
 void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
 {
     setVisibleAndFrontmost(false);
-    selectConversation(session_id);    
+    selectConversationPair(session_id, true);
 }
 
 void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
-- 
cgit v1.2.3


From 7527431bedce5529d33add21ec53336800f48fd0 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 5 Dec 2012 13:54:55 +0200
Subject: CHUI-572 FIXED Changed initial position for floaters according to
 description.

---
 indra/newview/skins/default/xui/en/floater_camera.xml       | 2 +-
 indra/newview/skins/default/xui/en/floater_destinations.xml | 7 ++++---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 9 +++++----
 indra/newview/skins/default/xui/en/floater_moveview.xml     | 2 +-
 4 files changed, 11 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index 22bc488a92..4b4821a383 100644
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
  positioning="specified"
- left="458"
+ left="643"
  bottom="-80"
  follows="left|bottom"
  legacy_header_height="18"
diff --git a/indra/newview/skins/default/xui/en/floater_destinations.xml b/indra/newview/skins/default/xui/en/floater_destinations.xml
index 39aa8e07bb..41b57530fc 100644
--- a/indra/newview/skins/default/xui/en/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/en/floater_destinations.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- positioning="cascading"
  ignore_ui_scale="false"
  legacy_header_height="225"
  can_minimize="true"
@@ -12,16 +11,18 @@
  height="230"
  layout="topleft"
  name="Destinations"
+ right="-10"
+ bottom="-80"
  single_instance="true"
  help_topic="destinations"
  save_rect="true"
  save_visibility="true"
  title="DESTINATIONS"
- width="840">
+ width="550">
     <web_browser
       top="25"
       height="200"
-      width="840"
+      width="550"
       follows="all"
       name="destination_guide_contents"
       trusted_content="true"/>
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 4aa7c88312..152c897120 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -3,7 +3,7 @@
  can_close="true"  
  can_minimize="true"
  can_resize="true"
- height="430"
+ height="230"
  layout="topleft"
  min_height="50"
  name="floater_im_box"
@@ -13,7 +13,8 @@
  single_instance="true"
  reuse_instance="true"
  title="CONVERSATIONS"
- width="680">
+ bottom="-80"
+ width="450">
     <string
      name="collapse_icon"
      value="Conv_toolbar_collapse"/>
@@ -23,13 +24,13 @@
     <layout_stack
      animate="true" 
      follows="all"
-     height="430"
+     height="230"
      layout="topleft"
      left="0"
      name="conversations_stack"
      orientation="horizontal"
      top="0"
-     width="680">
+     width="450">
         <layout_panel
          auto_resize="true"
          user_resize="true"        
diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml
index 4e7ee7913f..02d9805ddf 100644
--- a/indra/newview/skins/default/xui/en/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/en/floater_moveview.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
  positioning="specified"
- left="320"
+ left="505"
  bottom="-80"
  legacy_header_height="18"
  can_dock="false"
-- 
cgit v1.2.3


From 04dee1bad92da5910394f920247db60bade9ecc1 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 4 Dec 2012 20:49:42 +0200
Subject: CHUI-504 FIXED Open Conversation floater on first login. added
 toggleInstanceOrBringToFront("im_container") to LLStartup; typo corr.

---
 indra/newview/llstartup.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 1704ad9055..34259658ea 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1520,7 +1520,7 @@ bool idle_startup()
 	}
 
 	//---------------------------------------------------------------------
-	// Agent Send
+	// World Wait
 	//---------------------------------------------------------------------
 	if(STATE_WORLD_WAIT == LLStartUp::getStartupState())
 	{
@@ -1846,6 +1846,10 @@ bool idle_startup()
 			// Set the show start location to true, now that the user has logged
 			// on with this install.
 			gSavedSettings.setBOOL("ShowStartLocation", TRUE);
+
+			// Open Conversation floater on first login.
+			LLFloaterReg::toggleInstanceOrBringToFront("im_container");
+
 		}
 
 		display_startup();
@@ -2167,7 +2171,6 @@ bool idle_startup()
 		LLStartUp::setStartupState( STATE_STARTED );
 		display_startup();
 
-		// Unmute audio if desired and setup volumes.
 		// Unmute audio if desired and setup volumes.
 		// This is a not-uncommon crash site, so surround it with
 		// llinfos output to aid diagnosis.
-- 
cgit v1.2.3


From b43c8afc36a11c34fa76443be85430cac6c72c42 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 4 Dec 2012 14:51:33 -0800
Subject: CHUI-550, CHUI-551 : Fixed : Changed conversation sorting according
 to designer's desires.

---
 indra/newview/llconversationmodel.cpp | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 728b1a3f4c..0b7c3939df 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -528,12 +528,8 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 	{
 		// If both are sessions
 		U32 sort_order = getSortOrderSessions();
-		if ((type_a == LLConversationItem::CONV_SESSION_NEARBY) || (type_b == LLConversationItem::CONV_SESSION_NEARBY))
-		{
-			// If one is the nearby session, put nearby session *always* first
-			return (type_a == LLConversationItem::CONV_SESSION_NEARBY);
-		}
-		else if (sort_order == LLConversationFilter::SO_DATE)
+
+		if (sort_order == LLConversationFilter::SO_DATE)
 		{
 			// Sort by time
 			F64 time_a = 0.0;
@@ -552,14 +548,22 @@ bool LLConversationSort::operator()(const LLConversationItem* const& a, const LL
 			}
 			// If no time available, we'll default to sort by name at the end of this method
 		}
-		else if (sort_order == LLConversationFilter::SO_SESSION_TYPE)
+		else
 		{
-			if (type_a != type_b)
+			if ((type_a == LLConversationItem::CONV_SESSION_NEARBY) || (type_b == LLConversationItem::CONV_SESSION_NEARBY))
 			{
-				// Lowest types come first. See LLConversationItem definition of types
-				return (type_a < type_b);
+				// If one is the nearby session, put nearby session *always* last
+				return (type_b == LLConversationItem::CONV_SESSION_NEARBY);
 			}
+			else if (sort_order == LLConversationFilter::SO_SESSION_TYPE)
+			{
+				if (type_a != type_b)
+				{
+					// Lowest types come first. See LLConversationItem definition of types
+					return (type_a < type_b);
+				}
 			// If types are identical, we'll default to sort by name at the end of this method
+			}
 		}
 	}
 	else
-- 
cgit v1.2.3


From 8642088d65ec340b50661e2a3bf74820ec595010 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 4 Dec 2012 19:23:36 -0800
Subject: CHUI-571: Fixed bug where when the converation floater was torn off
 and a new im received, the incorrect conversation would be displayed and
 focused. In order to do this removed the conversation floater panels from
 being focused immediately when set visible. Also there was a bug when showing
 the stub panel for torn off conversations. The tab container was not setting
 the stub panel index properly to 0, which is where the stub panel existed in
 the tab container's list. This is post code review submit. Will submit
 another with minor code review changes.

---
 indra/llui/lltabcontainer.cpp           |  3 ++-
 indra/newview/llfloaterimcontainer.cpp  | 14 +++-----------
 indra/newview/llfloaterimnearbychat.cpp |  1 -
 indra/newview/llfloaterimsession.cpp    |  1 -
 indra/newview/llfloaterimsessiontab.cpp |  2 +-
 indra/newview/llimview.cpp              | 20 ++++++++++++++++----
 6 files changed, 22 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 3c1dfc1184..0dd63c2632 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1559,7 +1559,8 @@ BOOL LLTabContainer::setTab(S32 which)
 
 void LLTabContainer::hideAllTabs()
 {
-	setCurrentPanelIndex(-1);
+
+	setCurrentPanelIndex(0);
 	for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
 	{
 		(* iter)->mTabPanel->setVisible(FALSE);
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c1daea0aeb..d50581a314 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -546,8 +546,10 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
 			// *TODO: find a way to move this to XML as a default panel or something like that
 			LLSD name("nearby_chat");
 			LLFloaterReg::toggleInstanceOrBringToFront(name);
+            setSelectedSession(LLUUID(NULL));
 		}
 		openNearbyChat();
+        selectConversationPair(getSelectedSession(), false);
 	}
 
 	nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
@@ -571,7 +573,6 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
 	
 	// Now, do the normal multifloater show/hide
 	LLMultiFloater::setVisible(visible);
-	
 }
 
 void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
@@ -1624,22 +1625,13 @@ void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id,
 {
     //Finds the conversation line item to flash using the session_id
 	LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id));
-    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
 	if (widget)
 	{
         //Start flash
 		if (is_flashes)
 		{
-            //Only flash when conversation is not active
-            if(session_floater
-                && (!session_floater->isInVisibleChain()) //conversation floater not displayed
-                    || 
-                    (session_floater->isInVisibleChain() && session_floater->hasFocus() == false)) //conversation floater is displayed but doesn't have focus
-                
-            {
-			widget->getFlashTimer()->startFlashing();
-		}
+	        widget->getFlashTimer()->startFlashing();
 		}
         //Stop flash
 		else
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index a20fce876c..80a41e2f37 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -228,7 +228,6 @@ void LLFloaterIMNearbyChat::setVisible(BOOL visible)
 	{
 		removeScreenChat();
 	}
-    setFocus(visible);
 }
 
 // virtual
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 212b0df712..cb730c6237 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -629,7 +629,6 @@ void LLFloaterIMSession::setVisible(BOOL visible)
         
 	}
 
-    setFocus(visible);
 }
 
 BOOL LLFloaterIMSession::getVisible()
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index d04fa2674d..da25f95ffe 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -60,6 +60,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
   , mRefreshTimer(new LLTimer())
   , mIsHostAttached(false)
 {
+    setAutoFocus(FALSE);
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
 	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
@@ -124,7 +125,6 @@ void LLFloaterIMSessionTab::setVisible(BOOL visible)
 	{
 			LLFloaterIMSessionTab::addToHost(mSessionID);
 	}
-    setFocus(visible);
 }
 
 /*virtual*/
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index b6fd3ec9c8..821e62c4e6 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -192,12 +192,24 @@ void on_new_message(const LLSD& msg)
     else if("openconversations" == action)
     {
         LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-        if (im_box)
+        LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+
+        //Don't flash and show conversation floater when conversation already active (has focus)
+        if(session_floater
+            && (!session_floater->isInVisibleChain()) //conversation floater not displayed
+                || 
+                (session_floater->isInVisibleChain() && session_floater->hasFocus() == false)) //conversation floater is displayed but doesn't have focus
+
         {
-            im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
+            //Flash line item
+            if (im_box)
+            {
+                im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
+            }
+
+            //Surface conversations floater
+            LLFloaterReg::showInstance("im_container");
         }
-
-        LLFloaterReg::showInstance("im_container");
     }
 }
 
-- 
cgit v1.2.3


From e1b7153b4782ec4d1f8b028b435e7e4f0cf98dc2 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 5 Dec 2012 17:08:38 +0200
Subject: CHUI-530 Additional fix

---
 indra/newview/llfloaterimcontainer.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c1daea0aeb..36eb9435e9 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1599,6 +1599,7 @@ void LLFloaterIMContainer::openNearbyChat()
 		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,LLUUID()));
 		if (nearby_chat)
 		{
+			selectConversation(LLUUID());
 			nearby_chat->setOpen(TRUE);
 		}
 	}
-- 
cgit v1.2.3


From e0b1b063c14081a7c53ab5620db20385e1f2bbbd Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 5 Dec 2012 20:03:15 +0200
Subject: CHUI-577 FIXED "Mute text" and "Block voice" items are added to
 context menu instead of "Block\unblock"

---
 indra/newview/llconversationmodel.cpp              |  1 +
 indra/newview/llfloaterimcontainer.cpp             | 29 ++++++++++++++++++++--
 indra/newview/llfloaterimcontainer.h               |  1 +
 .../skins/default/xui/en/menu_conversation.xml     | 11 ++++++--
 4 files changed, 38 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 0b7c3939df..4328c60b1a 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -115,6 +115,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t&   items)
     items.push_back(std::string("share"));
     items.push_back(std::string("pay"));
     items.push_back(std::string("block_unblock"));
+    items.push_back(std::string("MuteText"));
 
 	if(this->getType() != CONV_SESSION_1_ON_1)
 	{
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 8e7edba0c0..a5b93f3692 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -926,7 +926,11 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
 		}
 		else if ("block_unblock" == command)
 		{
-			LLAvatarActions::toggleBlock(userID);
+			toggleMute(userID, LLMute::flagVoiceChat);
+		}
+		else if ("mute_unmute" == command)
+		{
+			toggleMute(userID, LLMute::flagTextChat);
 		}
 		else if ("selected" == command || "mute_all" == command || "unmute_all" == command)
 		{
@@ -1144,8 +1148,12 @@ bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_ve
     {
 		if ("is_blocked" == item)
 		{
-			return LLAvatarActions::isBlocked(uuids.front());
+			return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagVoiceChat);
 		}
+		else if (item == "is_muted")
+		{
+		    return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagTextChat);
+	    }
 		else if ("is_allowed_text_chat" == item)
 		{
 			const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
@@ -1591,6 +1599,23 @@ void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
 	}
 }
 
+void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags)
+{
+        BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
+        std::string name;
+        gCacheName->getFullName(participant_id, name);
+        LLMute mute(participant_id, name, LLMute::AGENT);
+
+        if (!is_muted)
+        {
+                LLMuteList::getInstance()->add(mute, flags);
+        }
+        else
+        {
+                LLMuteList::getInstance()->remove(mute, flags);
+        }
+}
+
 void LLFloaterIMContainer::openNearbyChat()
 {
 	// If there's only one conversation in the container and that conversation is the nearby chat
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 1badce0d2d..c9987bffe8 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -150,6 +150,7 @@ private:
 	void moderateVoiceAllParticipants(bool unmute);
 	void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
 	void toggleAllowTextChat(const LLUUID& participant_uuid);
+	void toggleMute(const LLUUID& participant_id, U32 flags);
 	void openNearbyChat();
 
 	LLButton* mExpandCollapseBtn;
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 908b2c174f..e8265fe482 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -105,14 +105,21 @@
         <on_enable function="Avatar.EnableItem" parameter="can_pay" />
     </menu_item_call>
     <menu_item_check
-     label="Block / unblock"
+     label="Block Voice"
      layout="topleft"
      name="block_unblock">
         <on_click function="Avatar.DoToSelected" parameter="block_unblock" />
 		<on_check function="Avatar.CheckItem" parameter="is_blocked" />
 		<on_enable  function="Avatar.EnableItem" parameter="can_block" />
     </menu_item_check>
-	<menu_item_call
+    <menu_item_check
+     label="Block Text"
+     layout="topleft"
+     name="MuteText">
+     <on_click function="Avatar.DoToSelected" parameter="mute_unmute"/>
+     <on_check function="Avatar.CheckItem" parameter="is_muted" />
+     <on_enable  function="Avatar.EnableItem" parameter="can_block" />
+    <menu_item_call
      label="Group Profile"
      layout="topleft"
      name="group_profile">
-- 
cgit v1.2.3


From fc000880b40143534c47c475a7a0aba6ab75039e Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 5 Dec 2012 20:47:21 +0200
Subject: CHUI-519 FIXED Do not put offered items into the trash while in Busy
 / DND mode

---
 indra/llui/llnotifications.cpp                           |  3 ++-
 indra/llui/llnotifications.h                             | 13 +++++++++++--
 indra/newview/llnotificationofferhandler.cpp             |  1 +
 indra/newview/llviewermessage.cpp                        |  5 ++++-
 indra/newview/skins/default/xui/en/menu_conversation.xml |  3 ++-
 5 files changed, 20 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 66144671c9..fd9bfec203 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -475,7 +475,8 @@ LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) :
 	mCancelled(false),
 	mIgnored(false),
 	mResponderObj(NULL),
-	mId(p.id.isProvided() ? p.id : LLUUID::generateNewID())
+	mId(p.id.isProvided() ? p.id : LLUUID::generateNewID()),
+	mOfferFromAgent(p.offer_from_agent)
 {
 	if (p.functor.name.isChosen())
 	{
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 088931858a..372b9ce46f 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -316,6 +316,7 @@ public:
 												expiry;
 		Optional<LLNotificationContext*>		context;
 		Optional<void*>							responder;
+		Optional<bool>							offer_from_agent;
 
 		struct Functor : public LLInitParam::ChoiceBlock<Functor>
 		{
@@ -339,7 +340,8 @@ public:
 			payload("payload"),
 			form_elements("form"),
 			substitutions("substitutions"),
-			expiry("expiry")
+			expiry("expiry"),
+			offer_from_agent("offer_from_agent", false)
 		{
 			time_stamp = LLDate::now();
 			responder = NULL;
@@ -352,7 +354,8 @@ public:
 			payload("payload"),
 			form_elements("form"),
 			substitutions("substitutions"),
-			expiry("expiry")
+			expiry("expiry"),
+			offer_from_agent("offer_from_agent", false)
 		{
 			functor.name = _name;
 			name = _name;
@@ -378,6 +381,7 @@ private:
 	LLNotificationFormPtr mForm;
 	void* mResponderObj; // TODO - refactor/remove this field
 	LLNotificationResponderPtr mResponder;
+	bool mOfferFromAgent;
 
 	// a reference to the template
 	LLNotificationTemplatePtr mTemplatep;
@@ -513,6 +517,11 @@ public:
 		return mTimestamp;
 	}
 
+	bool getOfferFromAgent() const
+	{
+		return mOfferFromAgent;
+	}
+
 	std::string getType() const;
 	std::string getMessage() const;
 	std::string getFooter() const;
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 91003c7d53..ff5b5e21f7 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -113,6 +113,7 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 			p.panel = notify_box;
 			// we not save offer notifications to the syswell floater that should be added to the IM floater
 			p.can_be_stored = !add_notif_to_im;
+			p.force_show = notification->getOfferFromAgent();
 
 			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
 			if(channel)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index dc8192105f..ea804508c8 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1971,6 +1971,7 @@ void inventory_offer_handler(LLOfferInfo* info)
 		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
 		info->mPersist = true;
 		p.name = "UserGiveItem";
+		p.offer_from_agent = true;
 		
 		// Prefetch the item into your local inventory.
 		LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
@@ -2738,7 +2739,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				// Same as closing window
 				info->forceResponse(IOR_DECLINE);
 			}
-			else if (is_do_not_disturb && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565)
+			// old logic: busy mode must not affect interaction with objects (STORM-565)
+			// new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
+			else if (is_do_not_disturb && dialog == IM_TASK_INVENTORY_OFFERED)
 			{
 				// Until throttling is implemented, do not disturb mode should reject inventory instead of silently
 				// accepting it.  SEE SL-39554
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index e8265fe482..01ef8ebdb5 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -116,9 +116,10 @@
      label="Block Text"
      layout="topleft"
      name="MuteText">
-     <on_click function="Avatar.DoToSelected" parameter="mute_unmute"/>
+     <on_click function="Avatar.DoToSelected" parameter="mute_unmute" />
      <on_check function="Avatar.CheckItem" parameter="is_muted" />
      <on_enable  function="Avatar.EnableItem" parameter="can_block" />
+    </menu_item_check>
     <menu_item_call
      label="Group Profile"
      layout="topleft"
-- 
cgit v1.2.3


From ffe80818064572a19b52d4f39f0e14538f701275 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 5 Dec 2012 12:40:44 -0800
Subject: CHUI 571: Code review changes, now LLFloaterIMContainer::showStub
 inlines code for hiding all tab panels and then showing the stub panel.
 Before the function would call hideAllTabs()

---
 indra/llui/lltabcontainer.cpp          | 12 ------------
 indra/llui/lltabcontainer.h            |  4 +---
 indra/newview/llfloaterimcontainer.cpp | 27 +++++++++++++++++++++++----
 3 files changed, 24 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 0dd63c2632..91527c68f2 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1556,18 +1556,6 @@ BOOL LLTabContainer::setTab(S32 which)
 	return is_visible;
 }
 
-
-void LLTabContainer::hideAllTabs()
-{
-
-	setCurrentPanelIndex(0);
-	for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
-	{
-		(* iter)->mTabPanel->setVisible(FALSE);
-	}
-}
-
-
 BOOL LLTabContainer::selectTabByName(const std::string& name)
 {
 	LLPanel* panel = getPanelByName(name);
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index a9cdf22b16..57862fc626 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -192,7 +192,7 @@ public:
 	BOOL 		selectTabPanel( LLPanel* child );
 	BOOL 		selectTab(S32 which);
 	BOOL 		selectTabByName(const std::string& title);
-	void        hideAllTabs();
+    void        setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; }
 
 	BOOL        getTabPanelFlashing(LLPanel* child);
 	void		setTabPanelFlashing(LLPanel* child, BOOL state);
@@ -243,8 +243,6 @@ private:
 
 	void setTabsHidden(BOOL hidden)		{ mTabsHidden = hidden; }
 	BOOL getTabsHidden() const			{ return mTabsHidden; }
-	
-	void setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; }
 
 	void scrollPrev() { mScrollPos = llmax(0, mScrollPos-1); } // No wrap
 	void scrollNext() { mScrollPos = llmin(mScrollPos+1, mMaxScrollPos); } // No wrap
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index a5b93f3692..23c21d5309 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -516,13 +516,32 @@ void LLFloaterIMContainer::tabClose()
 	}
 }
 
+//Shows/hides the stub panel when a conversation floater is torn off
 void LLFloaterIMContainer::showStub(bool stub_is_visible)
 {
-	if (stub_is_visible)
-	{
-		mTabContainer->hideAllTabs();
-	}
+    S32 tabCount = 0;
+    LLPanel * tabPanel = NULL;
+
+    if(stub_is_visible)
+    {
+        tabCount = mTabContainer->getTabCount();
+
+        //Hide all tabs even stub
+        for(S32 i = 0; i < tabCount; ++i)
+        {
+            tabPanel = mTabContainer->getPanelByIndex(i);
+
+            if(tabPanel)
+            {
+                tabPanel->setVisible(false);
+            }
+        }
+
+        //Set the index to the stub panel since we will be showing the stub
+        mTabContainer->setCurrentPanelIndex(0);
+    }
 
+    //Now show/hide the stub
 	mStubPanel->setVisible(stub_is_visible);
 }
 
-- 
cgit v1.2.3


From a4a2cc62c3411f0391b90d9720a13b49b0e123ef Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 5 Dec 2012 16:08:17 -0800
Subject: CHUI-509 : Fixed : Add params to inventory widgets to control font
 colors (required for library items and links).

---
 indra/llui/llfolderviewitem.cpp     | 39 ++++++++++++++++++-------------------
 indra/llui/llfolderviewitem.h       | 10 +++++++---
 indra/newview/llinventorybridge.cpp |  5 +++++
 indra/newview/llinventorybridge.h   |  1 +
 indra/newview/llinventorypanel.cpp  | 24 +++++++++++++++++++++++
 indra/newview/llinventorypanel.h    |  7 +++++++
 6 files changed, 63 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 9b54a7a467..60a6d3e3ea 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -47,16 +47,14 @@ static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
 // statics 
 std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
 
+bool LLFolderViewItem::sColorSetInitialized = false;
 LLUIColor LLFolderViewItem::sFgColor;
 LLUIColor LLFolderViewItem::sHighlightBgColor;
-LLUIColor LLFolderViewItem::sHighlightFgColor;
 LLUIColor LLFolderViewItem::sFocusOutlineColor;
 LLUIColor LLFolderViewItem::sMouseOverColor;
 LLUIColor LLFolderViewItem::sFilterBGColor;
 LLUIColor LLFolderViewItem::sFilterTextColor;
 LLUIColor LLFolderViewItem::sSuffixColor;
-LLUIColor LLFolderViewItem::sLibraryColor;
-LLUIColor LLFolderViewItem::sLinkColor;
 LLUIColor LLFolderViewItem::sSearchStatusColor;
 
 // only integers can be initialized in header
@@ -106,6 +104,8 @@ LLFolderViewItem::Params::Params()
 	item_top_pad("item_top_pad"),
 	creation_date(),
 	allow_open("allow_open", true),
+	font_color("font_color"),
+	font_highlight_color("font_highlight_color"),
     left_pad("left_pad", 0),
     icon_pad("icon_pad", 0),
     icon_width("icon_width", 0),
@@ -113,7 +113,7 @@ LLFolderViewItem::Params::Params()
     text_pad_right("text_pad_right", 0),
     arrow_size("arrow_size", 0),
     max_folder_item_overlap("max_folder_item_overlap", 0)
-{}
+{ }
 
 // Default constructor
 LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
@@ -137,6 +137,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mViewModelItem(p.listener),
 	mIsMouseOverTitle(false),
 	mAllowOpen(p.allow_open),
+	mFontColor(p.font_color),
+	mFontHighlightColor(p.font_highlight_color),
     mLeftPad(p.left_pad),
     mIconPad(p.icon_pad),
     mIconWidth(p.icon_width),
@@ -145,17 +147,18 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
     mArrowSize(p.arrow_size),
     mMaxFolderItemOverlap(p.max_folder_item_overlap)
 {
-	sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-	sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
-	sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
-	sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
-	sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
-	sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
-	sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
-	sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
-	sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
-	sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
-	sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+	if (!sColorSetInitialized)
+	{
+		sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+		sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+		sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+		sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+		sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+		sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+		sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
+		sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+		sColorSetInitialized = true;
+	}
 
 	if (mViewModelItem)
 	{
@@ -785,10 +788,6 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
 
 void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x)
 {
-    //TODO RN: implement this in terms of getColor()
-    //if (highlight_link) color = sLinkColor;
-    //if (gInventory.isObjectDescendentOf(getViewModelItem()->getUUID(), gInventory.getLibraryRootFolderID())) color = sLibraryColor;
-
     //--------------------------------------------------------------------------------//
     // Draw the actual label text
     //
@@ -857,7 +856,7 @@ void LLFolderViewItem::draw()
 		box_image->draw(box_rect, sFilterBGColor);
     }
 
-    LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
+    LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor;
     drawLabel(font, text_left, y, color, right_x);
 
 	//--------------------------------------------------------------------------------//
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 2e633a39e5..f33f21c8f8 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -61,6 +61,9 @@ public:
 		Optional<time_t>							creation_date;
 		Optional<bool>								allow_open;
 
+		Optional<LLUIColor>                         font_color;
+		Optional<LLUIColor>                         font_highlight_color;
+		
         Optional<S32>                               left_pad,
                                                     icon_pad,
                                                     icon_width,
@@ -116,19 +119,20 @@ protected:
 								mIsMouseOverTitle,
 								mAllowOpen,
 								mSelectPending;
+	
+	LLUIColor                   mFontColor;
+	LLUIColor                   mFontHighlightColor;
 
 	// For now assuming all colors are the same in derived classes.
+	static bool                 sColorSetInitialized;
 	static LLUIColor			sFgColor;
 	static LLUIColor			sFgDisabledColor;
 	static LLUIColor			sHighlightBgColor;
-	static LLUIColor			sHighlightFgColor;
 	static LLUIColor			sFocusOutlineColor;
 	static LLUIColor			sMouseOverColor;
 	static LLUIColor			sFilterBGColor;
 	static LLUIColor			sFilterTextColor;
 	static LLUIColor			sSuffixColor;
-	static LLUIColor			sLibraryColor;
-	static LLUIColor			sLinkColor;
 	static LLUIColor			sSearchStatusColor;
 
 	// this is an internal method used for adding items to folders. A
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 73631f4ba8..cf8253ca4d 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -255,6 +255,11 @@ BOOL LLInvFVBridge::isLink() const
 	return mIsLink;
 }
 
+BOOL LLInvFVBridge::isLibraryItem() const
+{
+	return gInventory.isObjectDescendentOf(getUUID(),gInventory.getLibraryRootFolderID());
+}
+
 /*virtual*/
 /**
  * @brief Adds this item into clipboard storage
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 5e96f00920..5c6cf0f0f0 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -107,6 +107,7 @@ public:
 	virtual BOOL isItemMovable() const;
 	virtual BOOL isItemInTrash() const;
 	virtual BOOL isLink() const;
+	virtual BOOL isLibraryItem() const;
 	//virtual BOOL removeItem() = 0;
 	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
 	virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 098a44b9d8..81e7f166e1 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -57,6 +57,15 @@ const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("Recent
 const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
 static const LLInventoryFolderViewModelBuilder INVENTORY_BRIDGE_BUILDER;
 
+// statics 
+bool LLInventoryPanel::sColorSetInitialized = false;
+LLUIColor LLInventoryPanel::sDefaultColor;
+LLUIColor LLInventoryPanel::sDefaultHighlightColor;
+LLUIColor LLInventoryPanel::sLibraryColor;
+LLUIColor LLInventoryPanel::sLinkColor;
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInventoryPanelObserver
 //
@@ -140,6 +149,15 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 {
 	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
 
+	if (!sColorSetInitialized)
+	{
+		sDefaultColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+		sDefaultHighlightColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+		sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
+		sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
+		sColorSetInitialized = true;
+	}
+	
 	// context menu callbacks
 	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
 	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
@@ -705,6 +723,9 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
 	params.listener = bridge;
 	params.tool_tip = params.name;
 
+	params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));
+	params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor));
+	
 	return LLUICtrlFactory::create<LLFolderViewFolder>(params);
 }
 
@@ -718,6 +739,9 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
 	params.listener = bridge;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
+
+	params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));
+	params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor));
 	
 	return LLUICtrlFactory::create<LLFolderViewItem>(params);
 }
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index c4f3c1b47d..9639086c11 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -275,6 +275,13 @@ protected:
 	// Builds the UI.  Call this once the inventory is usable.
 	void 				initializeViews();
 
+	// Specific inventory colors
+	static bool                 sColorSetInitialized;
+	static LLUIColor			sDefaultColor;
+	static LLUIColor			sDefaultHighlightColor;
+	static LLUIColor			sLibraryColor;
+	static LLUIColor			sLinkColor;
+	
 	LLFolderViewItem*	buildNewViews(const LLUUID& id);
 	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const;
 	
-- 
cgit v1.2.3


From 3a49beed0e96a797a6d663bcae5e932437ca3661 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 5 Dec 2012 20:25:46 -0800
Subject: CHUI-580 : WIP : Change the display name cache system, deprecating
 the old protocol and using the cap (People API) whenever available. Still has
 occurence of Resident as last name to clean up.

---
 indra/llcommon/llavatarname.cpp           | 69 ++++++++++++++++++++++++++++++-
 indra/llcommon/llavatarname.h             | 57 ++++++++++++++++++-------
 indra/llmessage/llavatarnamecache.cpp     | 56 ++++++++-----------------
 indra/llmessage/llavatarnamecache.h       |  2 +
 indra/llmessage/llcachename.cpp           |  6 ++-
 indra/llui/llscrolllistctrl.cpp           |  2 +-
 indra/llui/llurlentry.cpp                 |  4 +-
 indra/newview/llavataractions.cpp         | 16 +++----
 indra/newview/llavatariconctrl.cpp        |  2 +-
 indra/newview/llavatarlist.cpp            |  9 ++--
 indra/newview/llavatarlistitem.cpp        |  4 +-
 indra/newview/llcallingcard.cpp           |  6 +--
 indra/newview/llchathistory.cpp           | 14 +++----
 indra/newview/llconversationmodel.cpp     |  4 +-
 indra/newview/llfavoritesbar.cpp          | 10 ++---
 indra/newview/llfloateravatarpicker.cpp   | 12 ++----
 indra/newview/llfloaterdisplayname.cpp    | 10 ++---
 indra/newview/llfloaterimnearbychat.cpp   |  2 +-
 indra/newview/llfloaterscriptlimits.cpp   | 15 +------
 indra/newview/llfloatersellland.cpp       |  2 +-
 indra/newview/llfloatertopobjects.cpp     | 14 ++-----
 indra/newview/llfloatervoicevolume.cpp    |  2 +-
 indra/newview/llfriendcard.cpp            |  2 +-
 indra/newview/llimview.cpp                | 20 +++------
 indra/newview/llinspectavatar.cpp         |  6 +--
 indra/newview/llinventorybridge.cpp       |  5 +--
 indra/newview/llnamelistctrl.cpp          |  4 +-
 indra/newview/llpanelblockedlist.cpp      |  2 +-
 indra/newview/llpanelgroupinvite.cpp      |  4 +-
 indra/newview/llpanelgroupnotices.cpp     |  5 +--
 indra/newview/llpanelgrouproles.cpp       |  4 +-
 indra/newview/llparticipantlist.cpp       |  2 +-
 indra/newview/lltoastgroupnotifypanel.cpp |  6 +--
 indra/newview/lltoolpie.cpp               |  3 +-
 indra/newview/llviewerdisplayname.cpp     |  6 +--
 indra/newview/llviewermenu.cpp            |  6 +--
 indra/newview/llviewermessage.cpp         | 15 ++-----
 indra/newview/llvoavatar.cpp              | 24 +++++------
 indra/newview/llvoicevivox.cpp            |  4 +-
 39 files changed, 224 insertions(+), 212 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index 3206843bf4..b49e6a7aac 100644
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -30,6 +30,7 @@
 #include "llavatarname.h"
 
 #include "lldate.h"
+#include "llframetimer.h"
 #include "llsd.h"
 
 // Store these in pre-built std::strings to avoid memory allocations in
@@ -42,6 +43,8 @@ static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default");
 static const std::string DISPLAY_NAME_EXPIRES("display_name_expires");
 static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
 
+bool LLAvatarName::sUseDisplayNames = true;
+
 LLAvatarName::LLAvatarName()
 :	mUsername(),
 	mDisplayName(),
@@ -61,6 +64,17 @@ bool LLAvatarName::operator<(const LLAvatarName& rhs) const
 		return mUsername < rhs.mUsername;
 }
 
+//static 
+void LLAvatarName::setUseDisplayNames(bool use)
+{
+	sUseDisplayNames = use;
+}
+//static 
+bool LLAvatarName::useDisplayNames() 
+{ 
+	return sUseDisplayNames; 
+}
+
 LLSD LLAvatarName::asLLSD() const
 {
 	LLSD sd;
@@ -85,6 +99,33 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
 	mExpires = expires.secondsSinceEpoch();
 	LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE];
 	mNextUpdate = next_update.secondsSinceEpoch();
+	
+	// Some avatars don't have explicit display names set. Force a legible display name here.
+	if (mDisplayName.empty())
+	{
+		mDisplayName = mUsername;
+	}
+}
+
+void LLAvatarName::fromString(const std::string& full_name, F64 expires)
+{
+	mDisplayName = full_name;
+	std::string::size_type index = full_name.find(' ');
+	if (index != std::string::npos)
+	{
+		mLegacyFirstName = full_name.substr(0, index);
+		mLegacyLastName = full_name.substr(index+1);
+		mUsername = mLegacyFirstName + " " + mLegacyLastName;
+	}
+	else
+	{
+		mLegacyFirstName = full_name;
+		mLegacyLastName = "";
+		mUsername = full_name;
+	}
+	mIsDisplayNameDefault = true;
+	mIsTemporaryName = true;
+	mExpires = LLFrameTimer::getTotalSeconds() + expires;
 }
 
 std::string LLAvatarName::getCompleteName() const
@@ -104,9 +145,22 @@ std::string LLAvatarName::getCompleteName() const
 	return name;
 }
 
-std::string LLAvatarName::getLegacyName() const
+std::string LLAvatarName::getDisplayName() const
+{
+	if (sUseDisplayNames)
+	{
+		return mDisplayName;
+	}
+	else
+	{
+		return getUserName();
+	}
+}
+
+std::string LLAvatarName::getUserName() const
 {
-	if (mLegacyFirstName.empty() && mLegacyLastName.empty()) // display names disabled?
+	// If we cannot create a user name from the legacy strings, use the display name
+	if (mLegacyFirstName.empty() && mLegacyLastName.empty())
 	{
 		return mDisplayName;
 	}
@@ -118,3 +172,14 @@ std::string LLAvatarName::getLegacyName() const
 	name += mLegacyLastName;
 	return name;
 }
+
+void LLAvatarName::dump() const
+{
+	llinfos << "Merov debug : display = " << mDisplayName << ", user = " << mUsername << ", complete = " << getCompleteName() << ", legacy = " << getUserName() << " first = " << mLegacyFirstName << " last = " << mLegacyLastName << llendl;
+	LL_DEBUGS("AvNameCache") << "LLAvatarName: "
+	                         << "user '" << mUsername << "' "
+							 << "display '" << mDisplayName << "' "
+	                         << "expires in " << mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
+							 << LL_ENDL;
+}
+
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index ba258d6d52..cf9eb27b03 100644
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -43,19 +43,50 @@ public:
 
 	void fromLLSD(const LLSD& sd);
 
+	// Used only in legacy mode when the display name capability is not provided server side
+	void fromString(const std::string& full_name, F64 expires = 0.0f);
+	
+	static void setUseDisplayNames(bool use);
+	static bool useDisplayNames();
+	
+	// Name is valid if not temporary and not yet expired
+	bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); }
+	
+	// 
+	bool isDisplayNameDefault() const { return mIsDisplayNameDefault; }
+	
 	// For normal names, returns "James Linden (james.linden)"
 	// When display names are disabled returns just "James Linden"
 	std::string getCompleteName() const;
-
-	// Returns "James Linden" or "bobsmith123 Resident" for backwards
-	// compatibility with systems like voice and muting
-	// *TODO: Eliminate this in favor of username only
-	std::string getLegacyName() const;
-
+	
+	// "José Sanchez" or "James Linden", UTF-8 encoded Unicode
+	// Takes the display name preference into account. This is truly the name that should 
+	// be used for all UI where an avatar name has to be used unless we truly want something else (rare)
+	std::string getDisplayName() const;
+	
+	// Returns "James Linden" or "bobsmith123 Resident"
+	// Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name
+	// Also used for backwards compatibility with systems like voice and muting
+	std::string getUserName() const;
+	
+	// Debug print of the object
+	void dump() const;
+	
+	// Names can change, so need to keep track of when name was
+	// last checked.
+	// Unix time-from-epoch seconds for efficiency
+	F64 mExpires;
+	
+	// You can only change your name every N hours, so record
+	// when the next update is allowed
+	// Unix time-from-epoch seconds
+	F64 mNextUpdate;
+	
+private:
 	// "bobsmith123" or "james.linden", US-ASCII only
 	std::string mUsername;
 
-	// "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode
+	// "José Sanchez" or "James Linden", UTF-8 encoded Unicode
 	// Contains data whether or not user has explicitly set
 	// a display name; may duplicate their username.
 	std::string mDisplayName;
@@ -81,15 +112,9 @@ public:
 	// shown in UI, but are not serialized.
 	bool mIsTemporaryName;
 
-	// Names can change, so need to keep track of when name was
-	// last checked.
-	// Unix time-from-epoch seconds for efficiency
-	F64 mExpires;
-	
-	// You can only change your name every N hours, so record
-	// when the next update is allowed
-	// Unix time-from-epoch seconds
-	F64 mNextUpdate;
+	// Global flag indicating if display name should be used or not
+	// This will affect the output of the high level "get" methods
+	static bool sUseDisplayNames;
 };
 
 #endif
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 700525e1fa..329871d8eb 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -43,10 +43,6 @@ namespace LLAvatarNameCache
 {
 	use_display_name_signal_t mUseDisplayNamesSignal;
 
-	// Manual override for display names - can disable even if the region
-	// supports it.
-	bool sUseDisplayNames = true;
-
 	// Cache starts in a paused state until we can determine if the
 	// current region supports display names.
 	bool sRunning = false;
@@ -209,17 +205,8 @@ public:
 			// Use expiration time from header
 			av_name.mExpires = expires;
 
-			// Some avatars don't have explicit display names set
-			if (av_name.mDisplayName.empty())
-			{
-				av_name.mDisplayName = av_name.mUsername;
-			}
-
-			LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << " "
-									 << "user '" << av_name.mUsername << "' "
-									 << "display '" << av_name.mDisplayName << "' "
-									 << "expires in " << expires - now << " seconds"
-									 << LL_ENDL;
+			LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
+			av_name.dump();
 			
 			// cache it and fire signals
 			LLAvatarNameCache::processName(agent_id, av_name, true);
@@ -291,12 +278,9 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
         LLAvatarNameCache::sPendingQueue.erase(agent_id);
 
         LLAvatarName& av_name = existing->second;
-        LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
-                                 << agent_id 
-                                 << "user '" << av_name.mUsername << "' "
-                                 << "display '" << av_name.mDisplayName << "' "
-                                 << "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
-                                 << LL_ENDL;
+        LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL;
+		av_name.dump();
+
 		av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
     }
 }
@@ -476,7 +460,7 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)
 		const LLUUID& agent_id = it->first;
 		const LLAvatarName& av_name = it->second;
 		// Do not write temporary or expired entries to the stored cache
-		if (!av_name.mIsTemporaryName && av_name.mExpires >= max_unrefreshed)
+		if (av_name.isValidName(max_unrefreshed))
 		{
 			// key must be a string
 			agents[agent_id.asString()] = av_name.asLLSD();
@@ -513,7 +497,7 @@ void LLAvatarNameCache::idle()
 
 	if (!sAskQueue.empty())
 	{
-        if (useDisplayNames())
+        if (hasNameLookupURL())
         {
             requestNamesViaCapability();
         }
@@ -565,7 +549,7 @@ void LLAvatarNameCache::eraseUnrefreshed()
             {
                 const LLUUID& agent_id = it->first;
                 LL_DEBUGS("AvNameCache") << agent_id 
-                                         << " user '" << av_name.mUsername << "' "
+                                         << " user '" << av_name.getUserName() << "' "
                                          << "expired " << now - av_name.mExpires << " secs ago"
                                          << LL_ENDL;
                 sCache.erase(it++);
@@ -583,14 +567,12 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
 										LLAvatarName* av_name)
 {
 	llassert(av_name);
-	av_name->mUsername = "";
-	av_name->mDisplayName = full_name;
-	av_name->mIsDisplayNameDefault = true;
-	av_name->mIsTemporaryName = true;
-	av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME;
+	av_name->fromString(full_name,TEMP_CACHE_ENTRY_LIFETIME);
 	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
 							 << full_name
 							 << LL_ENDL;
+	// DEBUG ONLY!!! DO NOT COMMIT!!!
+	av_name->dump();
 }
 
 // fills in av_name if it has it in the cache, even if expired (can check expiry time)
@@ -600,7 +582,7 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
 	if (sRunning)
 	{
 		// ...only do immediate lookups when cache is running
-		if (useDisplayNames())
+		if (hasNameLookupURL())
 		{
 			// ...use display names cache
 			std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
@@ -662,7 +644,7 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
 	if (sRunning)
 	{
 		// ...only do immediate lookups when cache is running
-		if (useDisplayNames())
+		if (hasNameLookupURL())
 		{
 			// ...use new cache
 			std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
@@ -720,20 +702,16 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
 
 void LLAvatarNameCache::setUseDisplayNames(bool use)
 {
-	if (use != sUseDisplayNames)
+	if (use != LLAvatarName::useDisplayNames())
 	{
-		sUseDisplayNames = use;
-		// flush our cache
-		sCache.clear();
-
+		LLAvatarName::setUseDisplayNames(use);
 		mUseDisplayNamesSignal();
 	}
 }
 
-bool LLAvatarNameCache::useDisplayNames()
+void LLAvatarNameCache::flushCache()
 {
-	// Must be both manually set on and able to look up names.
-	return sUseDisplayNames && !sNameLookupURL.empty();
+	sCache.clear();
 }
 
 void LLAvatarNameCache::erase(const LLUUID& agent_id)
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 79f170f7c8..e172601432 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -81,6 +81,8 @@ namespace LLAvatarNameCache
 	void setUseDisplayNames(bool use);
 	bool useDisplayNames();
 
+	void flushCache();
+	
 	void erase(const LLUUID& agent_id);
 
     /// Provide some fallback for agents that return errors
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 479efabb5f..da07c9ae42 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -524,6 +524,7 @@ std::string LLCacheName::cleanFullName(const std::string& full_name)
 }
 
 //static 
+// Transform hard-coded name provided by server to a more legible username
 std::string LLCacheName::buildUsername(const std::string& full_name)
 {
 	// rare, but handle hard-coded error names returned from server
@@ -549,8 +550,9 @@ std::string LLCacheName::buildUsername(const std::string& full_name)
 		return username;
 	}
 
-	// if the input wasn't a correctly formatted legacy name just return it unchanged
-	return full_name;
+	// if the input wasn't a correctly formatted legacy name, just return it  
+	// cleaned up from a potential terminal "Resident"
+	return cleanFullName(full_name);
 }
 
 //static 
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 3e0653e9a4..7ed7042aff 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1832,7 +1832,7 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
 	{
 		LLAvatarName av_name;
 		LLAvatarNameCache::get(LLUUID(id), &av_name);
-		name = av_name.getLegacyName();
+		name = av_name.getUserName();
 	}
 	LLUrlAction::copyURLToClipboard(name);
 }
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index a9e8fbb4e4..fd2635c73a 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -597,7 +597,7 @@ LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName()
 
 std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name)
 {
-	return avatar_name.mDisplayName;
+	return avatar_name.getDisplayName();
 }
 
 //
@@ -613,7 +613,7 @@ LLUrlEntryAgentUserName::LLUrlEntryAgentUserName()
 
 std::string LLUrlEntryAgentUserName::getName(const LLAvatarName& avatar_name)
 {
-	return avatar_name.mUsername.empty() ? avatar_name.getLegacyName() : avatar_name.mUsername;
+	return avatar_name.getUserName();
 }
 
 //
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 1969a0bc5f..59b862503c 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -135,7 +135,7 @@ void LLAvatarActions::removeFriendsDialog(const uuid_vec_t& ids)
 		LLAvatarName av_name;
 		if(LLAvatarNameCache::get(agent_id, &av_name))
 		{
-			args["NAME"] = av_name.mDisplayName;
+			args["NAME"] = av_name.getDisplayName();
 		}
 
 		msgType = "RemoveFromFriends";
@@ -180,7 +180,7 @@ void LLAvatarActions::offerTeleport(const uuid_vec_t& ids)
 static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
 										  const LLAvatarName& av_name)
 {
-	std::string name = av_name.mDisplayName;
+	std::string name = av_name.getDisplayName();
 	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id);
 	if (session_id != LLUUID::null)
 	{
@@ -215,7 +215,7 @@ void LLAvatarActions::endIM(const LLUUID& id)
 static void on_avatar_name_cache_start_call(const LLUUID& agent_id,
 											const LLAvatarName& av_name)
 {
-	std::string name = av_name.mDisplayName;
+	std::string name = av_name.getDisplayName();
 	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id, true);
 	if (session_id != LLUUID::null)
 	{
@@ -315,11 +315,7 @@ static const char* get_profile_floater_name(const LLUUID& avatar_id)
 
 static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
-	std::string username = av_name.mUsername;
-	if (username.empty())
-	{
-		username = LLCacheName::buildUsername(av_name.mDisplayName);
-	}
+	std::string username = av_name.getUserName();
 	
 	llinfos << "opening web profile for " << username << llendl;		
 	std::string url = getProfileURL(username);
@@ -379,7 +375,7 @@ void LLAvatarActions::showOnMap(const LLUUID& id)
 		return;
 	}
 
-	gFloaterWorldMap->trackAvatar(id, av_name.mDisplayName);
+	gFloaterWorldMap->trackAvatar(id, av_name.getDisplayName());
 	LLFloaterReg::showInstance("world_map");
 }
 
@@ -709,7 +705,7 @@ void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_name
 	const std::string& separator = LLTrans::getString("words_separator");
 	for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
 	{
-		residents_string.append((*it).mDisplayName);
+		residents_string.append((*it).getDisplayName());
 		if	(++it == avatar_names.end())
 		{
 			break;
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index b7278d4a3a..0db38c947c 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -318,7 +318,7 @@ void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarN
 	{
 		// Most avatar icon controls are next to a UI element that shows
 		// a display name, so only show username.
-		mFullName = av_name.mUsername;
+		mFullName = av_name.getUserName();
 
 		if (mDrawTooltip)
 		{
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 771419f60a..e54e47180f 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -278,7 +278,7 @@ void LLAvatarList::refresh()
 		LLAvatarName av_name;
 		have_names &= LLAvatarNameCache::get(buddy_id, &av_name);
 
-		if (!have_filter || findInsensitive(av_name.mDisplayName, mNameFilter))
+		if (!have_filter || findInsensitive(av_name.getDisplayName(), mNameFilter))
 		{
 			if (nadded >= ADD_LIMIT)
 			{
@@ -296,8 +296,9 @@ void LLAvatarList::refresh()
 				}
 				else
 				{
+					std::string display_name = av_name.getDisplayName();
 					addNewItem(buddy_id, 
-						av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName, 
+						display_name.empty() ? waiting_str : display_name, 
 						LLAvatarTracker::instance().isBuddyOnline(buddy_id));
 				}
 				
@@ -325,7 +326,7 @@ void LLAvatarList::refresh()
 			const LLUUID& buddy_id = it->asUUID();
 			LLAvatarName av_name;
 			have_names &= LLAvatarNameCache::get(buddy_id, &av_name);
-			if (!findInsensitive(av_name.mDisplayName, mNameFilter))
+			if (!findInsensitive(av_name.getDisplayName(), mNameFilter))
 			{
 				removeItemByUUID(buddy_id);
 				modified = true;
@@ -398,7 +399,7 @@ bool LLAvatarList::filterHasMatches()
 		// If name has not been loaded yet we consider it as a match.
 		// When the name will be loaded the filter will be applied again(in refresh()).
 
-		if (have_name && !findInsensitive(av_name.mDisplayName, mNameFilter))
+		if (have_name && !findInsensitive(av_name.getDisplayName(), mNameFilter))
 		{
 			continue;
 		}
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 7ff1b39573..84e177d4a4 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -449,8 +449,8 @@ void LLAvatarListItem::setNameInternal(const std::string& name, const std::strin
 
 void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name)
 {
-	setAvatarName(av_name.mDisplayName);
-	setAvatarToolTip(av_name.mUsername);
+	setAvatarName(av_name.getDisplayName());
+	setAvatarToolTip(av_name.getUserName());
 
 	//requesting the list to resort
 	notifyParent(LLSD().with("sort", LLSD()));
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 60d60abd45..9a295faa73 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -723,7 +723,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
 	// Popup a notify box with online status of this agent
 	// Use display name only because this user is your friend
 	LLSD args;
-	args["NAME"] = av_name.mDisplayName;
+	args["NAME"] = av_name.getDisplayName();
 	args["STATUS"] = online ? LLTrans::getString("OnlineStatus") : LLTrans::getString("OfflineStatus");
 
 	LLNotificationPtr notification;
@@ -869,7 +869,7 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship
 {
 	LLAvatarName av_name;
 	LLAvatarNameCache::get( buddy_id, &av_name);
-	buddy_map_t::value_type value(av_name.mDisplayName, buddy_id);
+	buddy_map_t::value_type value(av_name.getDisplayName(), buddy_id);
 	if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION))
 	{
 		mMappable.insert(value);
@@ -892,7 +892,7 @@ bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* bud
 {
 	LLAvatarName av_name;
 	LLAvatarNameCache::get(buddy_id, &av_name);
-	mFullName = av_name.mDisplayName;
+	mFullName = av_name.getDisplayName();
 	buddy_map_t::value_type value(mFullName, buddy_id);
 	if(buddy->isOnline())
 	{
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index a33bd88273..3e25d9c457 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -553,15 +553,15 @@ private:
 
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
 	{
-		mFrom = av_name.mDisplayName;
+		mFrom = av_name.getDisplayName();
 
 		LLTextBox* user_name = getChild<LLTextBox>("user_name");
-		user_name->setValue( LLSD(av_name.mDisplayName ) );
-		user_name->setToolTip( av_name.mUsername );
+		user_name->setValue( LLSD(av_name.getDisplayName() ) );
+		user_name->setToolTip( av_name.getUserName() );
 
 		if (gSavedSettings.getBOOL("NameTagShowUsernames") && 
-			LLAvatarNameCache::useDisplayNames() &&
-			!av_name.mIsDisplayNameDefault)
+			av_name.useDisplayNames() &&
+			!av_name.isDisplayNameDefault())
 		{
 			LLStyle::Params style_params_name;
 			LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor");
@@ -569,9 +569,9 @@ private:
 			style_params_name.font.name("SansSerifSmall");
 			style_params_name.font.style("NORMAL");
 			style_params_name.readonly_color(userNameColor);
-			user_name->appendText("  - " + av_name.mUsername, FALSE, style_params_name);
+			user_name->appendText("  - " + av_name.getUserName(), FALSE, style_params_name);
 		}
-		setToolTip( av_name.mUsername );
+		setToolTip( av_name.getUserName() );
 		// name might have changed, update width
 		updateMinUserNameWidth();
 	}
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 728b1a3f4c..76c422f34d 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -443,8 +443,8 @@ void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
 
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
 {
-	mName = (av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername);
-	mDisplayName = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
+	mName = av_name.getUserName();
+	mDisplayName = av_name.getDisplayName();
 	mNeedsRefresh = true;
 	if(mParent != NULL)
 	{
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index c68577db75..ff0e01a200 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -1520,8 +1520,8 @@ void LLFavoritesOrderStorage::saveFavoritesSLURLs()
 
 	LLAvatarName av_name;
 	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Saved favorites for " << av_name.getLegacyName() << llendl;
-	fav_llsd[av_name.getLegacyName()] = user_llsd;
+	lldebugs << "Saved favorites for " << av_name.getUserName() << llendl;
+	fav_llsd[av_name.getUserName()] = user_llsd;
 
 	llofstream file;
 	file.open(filename);
@@ -1539,10 +1539,10 @@ void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
 
 	LLAvatarName av_name;
 	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Removed favorites for " << av_name.getLegacyName() << llendl;
-	if (fav_llsd.has(av_name.getLegacyName()))
+	lldebugs << "Removed favorites for " << av_name.getUserName() << llendl;
+	if (fav_llsd.has(av_name.getUserName()))
 	{
-		fav_llsd.erase(av_name.getLegacyName());
+		fav_llsd.erase(av_name.getUserName());
 	}
 
 	llofstream out_file;
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 6ada809cdb..f7dd4a4a6b 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -307,9 +307,9 @@ void LLFloaterAvatarPicker::populateNearMe()
 		else
 		{
 			element["columns"][0]["column"] = "name";
-			element["columns"][0]["value"] = av_name.mDisplayName;
+			element["columns"][0]["value"] = av_name.getDisplayName();
 			element["columns"][1]["column"] = "username";
-			element["columns"][1]["value"] = av_name.mUsername;
+			element["columns"][1]["value"] = av_name.getUserName();
 
 			sAvatarNameMap[av] = av_name;
 		}
@@ -505,9 +505,7 @@ void LLFloaterAvatarPicker::find()
 	LLViewerRegion* region = gAgent.getRegion();
 	url = region->getCapability("AvatarPickerSearch");
 	// Prefer use of capabilities to search on both SLID and display name
-	// but allow display name search to be manually turned off for test
-	if (!url.empty()
-		&& LLAvatarNameCache::useDisplayNames())
+	if (!url.empty())
 	{
 		// capability urls don't end in '/', but we need one to parse
 		// query parameters correctly
@@ -679,9 +677,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
 				found_one = TRUE;
 
 				LLAvatarName av_name;
-				av_name.mLegacyFirstName = first_name;
-				av_name.mLegacyLastName = last_name;
-				av_name.mDisplayName = avatar_name;
+				av_name.fromString(avatar_name);
 				const LLUUID& agent_id = avatar_id;
 				sAvatarNameMap[agent_id] = av_name;
 
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
index ac8f107928..be1ee77152 100644
--- a/indra/newview/llfloaterdisplayname.cpp
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -164,10 +164,9 @@ void LLFloaterDisplayName::onCancel()
 
 void LLFloaterDisplayName::onReset()
 {
-	if (LLAvatarNameCache::useDisplayNames())
+	if (LLAvatarNameCache::hasNameLookupURL())
 	{
-		LLViewerDisplayName::set("",
-			boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+		LLViewerDisplayName::set("",boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
 	}	
 	else
 	{
@@ -199,10 +198,9 @@ void LLFloaterDisplayName::onSave()
 		return;
 	}
 	
-	if (LLAvatarNameCache::useDisplayNames())
+	if (LLAvatarNameCache::hasNameLookupURL())
 	{
-		LLViewerDisplayName::set(display_name_utf8,
-			boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));	
+		LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));	
 	}
 	else
 	{
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index a20fce876c..24b0355fca 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -545,7 +545,7 @@ void	LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLS
 			LLAvatarName av_name;
 			LLAvatarNameCache::get(chat.mFromID, &av_name);
 
-			if (!av_name.mIsDisplayNameDefault)
+			if (!av_name.isDisplayNameDefault())
 			{
 				from_name = av_name.getCompleteName();
 			}
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index a50907601c..8d8bba7b17 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -602,15 +602,7 @@ void LLPanelScriptLimitsRegionMemory::onNameCache(
 		return;
 	}
 	
-	std::string name;
-	if (LLAvatarNameCache::useDisplayNames())
-	{
-		name = LLCacheName::buildUsername(full_name);
-	}
-	else
-	{
-		name = full_name;
-	}
+	std::string name = LLCacheName::buildUsername(full_name);
 
 	std::vector<LLSD>::iterator id_itor;
 	for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)
@@ -713,10 +705,7 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
 				else
 				{
 					name_is_cached = gCacheName->getFullName(owner_id, owner_buf);  // username
-					if (LLAvatarNameCache::useDisplayNames())
-					{
-						owner_buf = LLCacheName::buildUsername(owner_buf);
-					}
+					owner_buf = LLCacheName::buildUsername(owner_buf);
 				}
 				if(!name_is_cached)
 				{
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 484ecbcd04..c97a6792f3 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -238,7 +238,7 @@ void LLFloaterSellLandUI::updateParcelInfo()
 void LLFloaterSellLandUI::onBuyerNameCache(const LLAvatarName& av_name)
 {
 	getChild<LLUICtrl>("sell_to_agent")->setValue(av_name.getCompleteName());
-	getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.mUsername);
+	getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.getUserName());
 }
 
 void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 2d91a61b54..7530c72dd2 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -199,17 +199,9 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 		// Owner names can have trailing spaces sent from server
 		LLStringUtil::trim(owner_buf);
 		
-		if (LLAvatarNameCache::useDisplayNames())
-		{
-			// ...convert hard-coded name from server to a username
-			// *TODO: Send owner_id from server and look up display name
-			owner_buf = LLCacheName::buildUsername(owner_buf);
-		}
-		else
-		{
-			// ...just strip out legacy "Resident" name
-			owner_buf = LLCacheName::cleanFullName(owner_buf);
-		}
+		// *TODO: Send owner_id from server and look up display name
+		owner_buf = LLCacheName::buildUsername(owner_buf);
+
 		columns[column_num]["column"] = "owner";
 		columns[column_num]["value"] = owner_buf;
 		columns[column_num++]["font"] = "SANSSERIF";
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
index 87b388b30a..a1df73a065 100644
--- a/indra/newview/llfloatervoicevolume.cpp
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -151,7 +151,7 @@ void LLFloaterVoiceVolume::updateVolumeControls()
 
 		// By convention, we only display and toggle voice mutes, not all mutes
 		bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
-		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
+		bool is_linden = LLStringUtil::endsWith(mAvatarName.getUserName(), " Linden");
 
 		mute_btn->setEnabled(!is_linden);
 		mute_btn->setValue(is_muted);
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index a64ddd185d..0e72fab32c 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -533,7 +533,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
 	bool shouldBeAdded = true;
 	LLAvatarName av_name;
 	LLAvatarNameCache::get(avatarID, &av_name);
-	const std::string& name = av_name.mUsername;
+	const std::string& name = av_name.getUserName();
 
 	lldebugs << "Processing buddy name: " << name 
 		<< ", id: " << avatarID
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e5dda7e8d8..0de8f124ee 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -306,7 +306,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 
 void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name)
 {
-	if (av_name.mIsTemporaryName)
+	if (!av_name.isValidName())
 	{
 		S32 separator_index = mName.rfind(" ");
 		std::string name = mName.substr(0, separator_index);
@@ -626,15 +626,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 		// so no need for a callback in LLAvatarNameCache::get()
 		if (LLAvatarNameCache::get(mOtherParticipantID, &av_name))
 		{
-			if (av_name.mUsername.empty())
-			{
-				// Display names are off, use mDisplayName which will be the legacy name
-				mHistoryFileName = LLCacheName::buildUsername(av_name.mDisplayName);
-			}
-			else
-			{
-				mHistoryFileName =  av_name.mUsername;
-			}
+			mHistoryFileName = LLCacheName::buildUsername(av_name.getUserName());
 		}
 		else
 		{
@@ -836,7 +828,7 @@ bool LLIMModel::logToFile(const std::string& file_name, const std::string& from,
 		LLAvatarName av_name;
 		if (!from_id.isNull() && 
 			LLAvatarNameCache::get(from_id, &av_name) &&
-			!av_name.mIsDisplayNameDefault)
+			!av_name.isDisplayNameDefault())
 		{	
 			from_name = av_name.getCompleteName();
 		}
@@ -1926,7 +1918,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(callee_id, &av_name))
 		{
-			final_callee_name = av_name.mDisplayName;
+			final_callee_name = av_name.getDisplayName();
 			title = av_name.getCompleteName();
 		}
 	}
@@ -2464,7 +2456,7 @@ void LLIMMgr::addMessage(
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
 		{
-			fixed_session_name = (av_name.mDisplayName.empty() ? av_name.mUsername : av_name.mDisplayName);
+			fixed_session_name = av_name.getDisplayName();
 		}
 		LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg);
 
@@ -3110,7 +3102,7 @@ void LLIMMgr::noteOfflineUsers(
 			{
 				LLUIString offline = LLTrans::getString("offline_message");
 				// Use display name only because this user is your friend
-				offline.setArg("[NAME]", av_name.mDisplayName);
+				offline.setArg("[NAME]", av_name.getDisplayName());
 				im_model.proccessOnlineOfflineNotification(session_id, offline);
 			}
 		}
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 8a15cd279f..3507b729be 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -263,9 +263,9 @@ void LLInspectAvatar::onAvatarNameCache(
 {
 	if (agent_id == mAvatarID)
 	{
-		getChild<LLUICtrl>("user_name")->setValue(av_name.mDisplayName);
-		getChild<LLUICtrl>("user_name_small")->setValue(av_name.mDisplayName);
-		getChild<LLUICtrl>("user_slid")->setValue(av_name.mUsername);
+		getChild<LLUICtrl>("user_name")->setValue(av_name.getDisplayName());
+		getChild<LLUICtrl>("user_name_small")->setValue(av_name.getDisplayName());
+		getChild<LLUICtrl>("user_slid")->setValue(av_name.getUserName());
 		mAvatarName = av_name;
 		
 		// show smaller display name if too long to display in regular size
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 73631f4ba8..bad4e8c231 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4712,10 +4712,9 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
 			gCacheName->getFullName(item->getCreatorUUID(), callingcard_name);
 			// IDEVO
 			LLAvatarName av_name;
-			if (LLAvatarNameCache::useDisplayNames()
-				&& LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
+			if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
 			{
-				callingcard_name = av_name.mDisplayName + " (" + av_name.mUsername + ")";
+				callingcard_name = av_name.getCompleteName();
 			}
 			LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID());
 			if (session_id != LLUUID::null)
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index b0fbad33b0..855007e403 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -320,7 +320,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
 			else if (LLAvatarNameCache::get(id, &av_name))
 			{
 				if (mShortNames)
-					fullname = av_name.mDisplayName;
+					fullname = av_name.getDisplayName();
 				else
 					fullname = av_name.getCompleteName();
 			}
@@ -390,7 +390,7 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
 {
 	std::string name;
 	if (mShortNames)
-		name = av_name.mDisplayName;
+		name = av_name.getDisplayName();
 	else
 		name = av_name.getCompleteName();
 
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 7612af8f5e..b4deb7a920 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -224,7 +224,7 @@ void LLPanelBlockedList::onFilterEdit(const std::string& search_string)
 void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
 {
 	if (names.empty() || ids.empty()) return;
-	LLMute mute(ids[0], names[0].getLegacyName(), LLMute::AGENT);
+	LLMute mute(ids[0], names[0].getUserName(), LLMute::AGENT);
 	LLMuteList::getInstance()->add(mute);
 	showPanelAndSelect(mute.mID);
 }
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 7efeb77e23..a2bbc5400c 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -482,7 +482,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
 				}
 				else
 				{
-					names.push_back(av_name.getLegacyName());
+					names.push_back(av_name.getUserName());
 				}
 			}
 		}
@@ -495,7 +495,7 @@ void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& a
 	std::vector<std::string> names;
 	uuid_vec_t agent_ids;
 	agent_ids.push_back(id);
-	names.push_back(av_name.getLegacyName());
+	names.push_back(av_name.getUserName());
 
 	mImplementation->addUsers(names, agent_ids);
 }
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 31c0e3d01a..93b108efcc 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -543,10 +543,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
 		msg->getU32("Data","Timestamp",timestamp,i);
 
 		// we only have the legacy name here, convert it to a username
-		if (LLAvatarNameCache::useDisplayNames())
-		{
-			name = LLCacheName::buildUsername(name);
-		}
+		name = LLCacheName::buildUsername(name);
 
 		LLSD row;
 		row["id"] = id;
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 5720168f81..7ad7e7149b 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1616,7 +1616,7 @@ void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemb
 	}
 	
 	// trying to avoid unnecessary hash lookups
-	if (matchesSearchFilter(av_name.getLegacyName()))
+	if (matchesSearchFilter(av_name.getUserName()))
 	{
 		addMemberToList(id, member);
 		if(!mMembersList->getEnabled())
@@ -1670,7 +1670,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
 		{
-			if (matchesSearchFilter(av_name.getLegacyName()))
+			if (matchesSearchFilter(av_name.getUserName()))
 			{
 				addMemberToList(mMemberProgress->first, mMemberProgress->second);
 			}
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 6c838f8a45..c53760bca1 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -381,7 +381,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 		// Create a participant view model instance
 		LLAvatarName avatar_name;
 		bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
-		participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.mDisplayName , avatar_id, mRootViewModel);
+		participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.getDisplayName() , avatar_id, mRootViewModel);
 		participant->fetchAvatarName();
 	}
 	else
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index ed350ea144..4dc0d424ac 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -69,10 +69,8 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
 
 	//header title
 	std::string from_name = payload["sender_name"].asString();
-	if (LLAvatarNameCache::useDisplayNames())
-	{
-		from_name = LLCacheName::buildUsername(from_name);
-	}
+	from_name = LLCacheName::buildUsername(from_name);
+
 	std::stringstream from;
 	from << from_name << "/" << groupData.mName;
 	LLTextBox* pTitleText = getChild<LLTextBox>("title");
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 3cd761b73b..c81f6ace70 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -991,8 +991,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 			}
 
 			LLAvatarName av_name;
-			if (LLAvatarNameCache::useDisplayNames() && 
-				LLAvatarNameCache::get(hover_object->getID(), &av_name))
+			if (LLAvatarNameCache::get(hover_object->getID(), &av_name))
 			{
 				final_name = av_name.getCompleteName();
 			}
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
index 5741fab29a..4bd38562bc 100644
--- a/indra/newview/llviewerdisplayname.cpp
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -97,7 +97,7 @@ void LLViewerDisplayName::set(const std::string& display_name, const set_name_sl
 
 	// People API expects array of [ "old value", "new value" ]
 	LLSD change_array = LLSD::emptyArray();
-	change_array.append(av_name.mDisplayName);
+	change_array.append(av_name.getDisplayName());
 	change_array.append(display_name);
 	
 	llinfos << "Set name POST to " << cap_url << llendl;
@@ -189,8 +189,8 @@ class LLDisplayNameUpdate : public LLHTTPNode
 
 		LLSD args;
 		args["OLD_NAME"] = old_display_name;
-		args["SLID"] = av_name.mUsername;
-		args["NEW_NAME"] = av_name.mDisplayName;
+		args["SLID"] = av_name.getUserName();
+		args["NEW_NAME"] = av_name.getDisplayName();
 		LLNotificationsUtil::add("DisplayNameUpdate", args);
 		if (agent_id == gAgent.getID())
 		{
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 511807ec2f..5284d2650e 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8080,11 +8080,7 @@ class LLWorldPostProcess : public view_listener_t
 
 void handle_flush_name_caches()
 {
-	// Toggle display names on and off to flush
-	bool use_display_names = LLAvatarNameCache::useDisplayNames();
-	LLAvatarNameCache::setUseDisplayNames(!use_display_names);
-	LLAvatarNameCache::setUseDisplayNames(use_display_names);
-
+	LLAvatarNameCache::flushCache();
 	if (gCacheName) gCacheName->clear();
 }
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index dc8192105f..6397ef7961 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2245,16 +2245,7 @@ static std::string clean_name_from_task_im(const std::string& msg,
 		// Don't try to clean up group names
 		if (!from_group)
 		{
-			if (LLAvatarNameCache::useDisplayNames())
-			{
-				// ...just convert to username
-				final += LLCacheName::buildUsername(name);
-			}
-			else
-			{
-				// ...strip out legacy "Resident" name
-				final += LLCacheName::cleanFullName(name);
-			}
+			final += LLCacheName::buildUsername(name);
 		}
 		final += match[3].str();
 		return final;
@@ -2268,7 +2259,7 @@ void notification_display_name_callback(const LLUUID& id,
 					  LLSD& substitutions, 
 					  const LLSD& payload)
 {
-	substitutions["NAME"] = av_name.mDisplayName;
+	substitutions["NAME"] = av_name.getDisplayName();
 	LLNotificationsUtil::add(name, substitutions, payload);
 }
 
@@ -3452,7 +3443,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(from_id, &av_name))
 		{
-			chat.mFromName = av_name.mDisplayName;
+			chat.mFromName = av_name.getDisplayName();
 		}
 		else
 		{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 220c4ef59a..7cc4e3ed04 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3188,29 +3188,27 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
 		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
 
-		if (LLAvatarNameCache::useDisplayNames())
+		if (LLAvatarName::useDisplayNames())
 		{
 			LLAvatarName av_name;
 			if (!LLAvatarNameCache::get(getID(), &av_name))
 			{
-				// ...call this function back when the name arrives
-				// and force a rebuild
-				LLAvatarNameCache::get(getID(),
-					boost::bind(&LLVOAvatar::clearNameTag, this));
+				// ...call this function back when the name arrives and force a rebuild
+				LLAvatarNameCache::get(getID(),boost::bind(&LLVOAvatar::clearNameTag, this));
 			}
 
 			// Might be blank if name not available yet, that's OK
 			if (show_display_names)
 			{
-				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
+				addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL,
 					LLFontGL::getFontSansSerif());
 			}
 			// Suppress SLID display if display name matches exactly (ugh)
-			if (show_usernames && !av_name.mIsDisplayNameDefault)
+			if (show_usernames && !av_name.isDisplayNameDefault())
 			{
 				// *HACK: Desaturate the color
 				LLColor4 username_color = name_tag_color * 0.83f;
-				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
+				addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL,
 					LLFontGL::getFontSansSerifSmall());
 			}
 		}
@@ -3421,20 +3419,18 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
 	{
 		color_name = "NameTagFriend";
 	}
-	else if (LLAvatarNameCache::useDisplayNames())
+	else if (LLAvatarName::useDisplayNames())
 	{
-		// ...color based on whether username "matches" a computed display
-		// name
+		// ...color based on whether username "matches" a computed display name
 		LLAvatarName av_name;
-		if (LLAvatarNameCache::get(getID(), &av_name)
-			&& av_name.mIsDisplayNameDefault)
+		if (LLAvatarNameCache::get(getID(), &av_name) && av_name.isDisplayNameDefault())
 		{
 			color_name = "NameTagMatch";
 		}
 		else
 		{
 			color_name = "NameTagMismatch";
-	}
+		}
 	}
 	else
 	{
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 37491e5b58..6fdda12a1c 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -2668,7 +2668,7 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)
 		// *NOTE: For now, we feed legacy names to Vivox because I don't know
 		// if their service can support a mix of new and old clients with
 		// different sorts of names.
-		std::string name = av_name.getLegacyName();
+		std::string name = av_name.getUserName();
 
 		const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id);
 		bool canSeeMeOnline = false;
@@ -6200,7 +6200,7 @@ void LLVivoxVoiceClient::lookupName(const LLUUID &id)
 void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id,
 										   const LLAvatarName& av_name)
 {
-	std::string display_name = av_name.mDisplayName;
+	std::string display_name = av_name.getDisplayName();
 	avatarNameResolved(agent_id, display_name);
 }
 
-- 
cgit v1.2.3


From 5f6d55eb1b264780fbb703b115e9b4428cc4ee2b Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 6 Dec 2012 15:19:10 +0200
Subject: CHUI-444 (Click target off when conversation list is minimized to
 icons)

---
 indra/llui/llfolderviewitem.cpp | 4 ++--
 indra/llui/llfolderviewitem.h   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 9b54a7a467..9facf65802 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1863,7 +1863,7 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
 	}
 	if( !handled )
 	{
-		if(mIndentation < x && x < mIndentation + (isMinimized() ? 0 : mArrowSize) + mTextPad)
+		if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
 		{
 			toggleOpen();
 			handled = TRUE;
@@ -1887,7 +1887,7 @@ BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 	}
 	if( !handled )
 	{
-		if(mIndentation < x && x < mIndentation + (isMinimized() ? 0 : mArrowSize) + mTextPad)
+		if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
 		{
 			// don't select when user double-clicks plus sign
 			// so as not to contradict single-click behavior
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 2e633a39e5..a35193f948 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -292,7 +292,7 @@ protected:
 	friend class LLUICtrlFactory;
 
 	void updateLabelRotation();
-	virtual bool isMinimized() { return FALSE; }
+	virtual bool isCollapsed() { return FALSE; }
 
 public:
 	typedef std::list<LLFolderViewItem*> items_t;
-- 
cgit v1.2.3


From 272d438ce299fab146e9a30046b7591de7467511 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 6 Dec 2012 18:23:30 +0200
Subject: CHUI-576 (Group moderation menus do not work in torn off dialogs)

---
 indra/newview/llfloaterimcontainer.cpp  | 20 +++++++++++++-------
 indra/newview/llfloaterimsessiontab.cpp | 12 ++++++++++++
 indra/newview/llfloaterimsessiontab.h   |  1 +
 3 files changed, 26 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c1daea0aeb..257c17a058 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -850,8 +850,16 @@ const LLConversationItem * LLFloaterIMContainer::getCurSelectedViewModelItem()
         mConversationsRoot->getCurSelectedItem() && 
         mConversationsRoot->getCurSelectedItem()->getViewModelItem())
     {
-        conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
-    }
+		LLFloaterIMSessionTab *selectedSession = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+		if (selectedSession && selectedSession->isTornOff())
+		{
+			conversationItem = selectedSession->getCurSelectedViewModelItem();
+		}
+		else
+		{
+			conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
+		}
+	}
 
     return conversationItem;
 }
@@ -1532,21 +1540,19 @@ void LLFloaterIMContainer::moderateVoiceParticipant(const LLUUID& avatar_id, boo
 
 LLSpeakerMgr * LLFloaterIMContainer::getSpeakerMgrForSelectedParticipant()
 {
-	LLFolderViewItem * selected_folder_itemp = mConversationsRoot->getCurSelectedItem();
-	if (NULL == selected_folder_itemp)
+	LLFolderViewItem *selectedItem = mConversationsRoot->getCurSelectedItem();
+	if (NULL == selectedItem)
 	{
 		llwarns << "Current selected item is null" << llendl;
 		return NULL;
 	}
 
-	LLFolderViewFolder * conversation_itemp = selected_folder_itemp->getParentFolder();
-
 	conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin();
 	conversations_widgets_map::const_iterator end = mConversationsWidgets.end();
 	const LLUUID * conversation_uuidp = NULL;
 	while(iter != end)
 	{
-		if (iter->second == conversation_itemp)
+		if (iter->second == selectedItem || iter->second == selectedItem->getParentFolder())
 		{
 			conversation_uuidp = &iter->first;
 			break;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index d04fa2674d..85d1b1fb49 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -831,4 +831,16 @@ void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
     }
 }
 
+LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()
+{
+	LLConversationItem *conversationItem = NULL;
 
+	if(mConversationsRoot && 
+        mConversationsRoot->getCurSelectedItem() && 
+        mConversationsRoot->getCurSelectedItem()->getViewModelItem())
+	{
+		conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem()) ;
+	}
+
+	return conversationItem;
+}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 8efa0955fc..4851904074 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -94,6 +94,7 @@ public:
 	virtual void onTearOffClicked();
 	
 	virtual void updateMessages() {}
+	LLConversationItem* getCurSelectedViewModelItem();
 
 protected:
 
-- 
cgit v1.2.3


From e2c080b5582d08302d1deaf1fb64cab1a67c138a Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 6 Dec 2012 19:26:52 +0200
Subject: CHUI-505 FIXED Open Call Log if user has new events while out: force
 open Conversation Log Floater when received a saved offline message

---
 indra/newview/llimview.cpp | 13 +++++++++++++
 1 file changed, 13 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 821e62c4e6..ea123d3f15 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -30,6 +30,7 @@
 
 #include "llavatarnamecache.h"	// IDEVO
 #include "llavataractions.h"
+#include "llfloaterconversationlog.h"
 #include "llfloaterreg.h"
 #include "llfontgl.h"
 #include "llgl.h"
@@ -2467,6 +2468,18 @@ void LLIMMgr::addMessage(
 		new_session_id = computeSessionID(dialog, other_participant_id);
 	}
 
+	// Open conversation log if offline messages are present
+	if (is_offline_msg)
+	{
+		LLFloaterConversationLog* floater_log =
+				LLFloaterReg::getTypedInstance<LLFloaterConversationLog>("conversation");
+		if (floater_log && !(floater_log->isFrontmost()))
+		{
+            floater_log->openFloater();
+			floater_log->setFrontmost(TRUE);
+		}
+	}
+
 	//*NOTE session_name is empty in case of incoming P2P sessions
 	std::string fixed_session_name = from;
 	bool name_is_setted = false;
-- 
cgit v1.2.3


From 218cbebbd8bdbfadc954731ee54f6472ed847139 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 6 Dec 2012 15:52:55 -0800
Subject: CHUI-579: When the 'Pop up message' preference is set the
 conversation line item and/or FUI button flash depending on what is focused.
 Also when the 'Flash the toolbar button' preference is set the FUI button
 will flash or the line item will flash depending upon what is focused.

---
 indra/newview/llimview.cpp | 65 ++++++++++++++++++++++++++++------------------
 1 file changed, 40 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 821e62c4e6..1a2632f921 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -155,57 +155,72 @@ void on_new_message(const LLSD& msg)
 
     // execution of the action
 
+    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+
+    bool sessionFloaterInActive = session_floater
+                                    && (!session_floater->isInVisibleChain()) //conversation floater not displayed
+                                        || 
+                                        (session_floater->isInVisibleChain() && session_floater->hasFocus() == false); //conversation floater is displayed but doesn't have focus
+
     if ("toast" == action)
     {
         // Skip toasting if we have open window of IM with this session id
-        LLFloaterIMSession* open_im_floater = LLFloaterIMSession::findInstance(session_id);
         if (
-            open_im_floater
-            && open_im_floater->isInVisibleChain()
-            && open_im_floater->hasFocus()
-            && !open_im_floater->isMinimized()
-            && !(open_im_floater->getHost()
-            && open_im_floater->getHost()->isMinimized())
+            session_floater
+            && session_floater->isInVisibleChain()
+            && session_floater->hasFocus()
+            && !session_floater->isMinimized()
+            && !(session_floater->getHost()
+            && session_floater->getHost()->isMinimized())
             )
         {
             return;
         }
 
 	    // Skip toasting for system messages and for nearby chat
-	    if (participant_id.isNull() || session_id.isNull())
+	    if (participant_id.isNull())
         {
             return;
         }
 
-        //Show toast
-        LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+        //Show IM toasts (upper right toasts)
+        if(session_id.notNull())
+        {
+            LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+        }
+
+        //Session floater has focus, so don't need to show notification flashes
+        if(sessionFloaterInActive)
+        {
+            //Flash converstation line item anytime that conversation doesn't have focus
+            im_box->flashConversationItemWidget(session_id, true);
+
+            //Only flash the 'Chat' FUI button when the conversation floater isn't focused (implies not front most floater)
+            if(!im_box->hasFocus())
+            {
+                gToolBarView->flashCommand(LLCommandId("chat"), true);
+            }
+        }
     }
     else if ("flash" == action)
     {
-        LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-        if (im_box)
+        if(sessionFloaterInActive && !im_box->hasFocus())
+        {
+            gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat"
+        }
+        else if(sessionFloaterInActive)
         {
             im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
         }
-        gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat"
     }
     else if("openconversations" == action)
     {
-        LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-        LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
-
         //Don't flash and show conversation floater when conversation already active (has focus)
-        if(session_floater
-            && (!session_floater->isInVisibleChain()) //conversation floater not displayed
-                || 
-                (session_floater->isInVisibleChain() && session_floater->hasFocus() == false)) //conversation floater is displayed but doesn't have focus
-
+        if(sessionFloaterInActive)
         {
             //Flash line item
-            if (im_box)
-            {
-                im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
-            }
+            im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
 
             //Surface conversations floater
             LLFloaterReg::showInstance("im_container");
-- 
cgit v1.2.3


From 9da625d439a9a911733564177e32facc3669dc58 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Thu, 6 Dec 2012 20:28:25 -0800
Subject: CHUI-494: WIP First pass at getting the suppression of events in DND
 working.

---
 indra/newview/llbrowsernotification.cpp       |   5 +
 indra/newview/llfloateroutbox.cpp             |  17 +--
 indra/newview/llimhandler.cpp                 |   2 +-
 indra/newview/llnotificationalerthandler.cpp  |  28 ++++-
 indra/newview/llnotificationgrouphandler.cpp  |   2 +-
 indra/newview/llnotificationhandler.h         | 145 ++++++++++++++++----------
 indra/newview/llnotificationhandlerutil.cpp   |  12 ++-
 indra/newview/llnotificationhinthandler.cpp   |  27 ++++-
 indra/newview/llnotificationofferhandler.cpp  |   2 +-
 indra/newview/llnotificationscripthandler.cpp |   2 +-
 indra/newview/llnotificationtiphandler.cpp    |   2 +-
 indra/newview/llviewerwindow.cpp              |  31 ++----
 indra/newview/llviewerwindow.h                |   9 +-
 13 files changed, 184 insertions(+), 100 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index 9e608d2c8b..19747757db 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -35,6 +35,11 @@
 
 using namespace LLNotificationsUI;
 
+LLBrowserNotification::LLBrowserNotification()
+	: LLSystemNotificationHandler("Browser", "browser")
+{
+}
+
 bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
 {
 	LLUUID media_id = notification->getPayload()["media_id"].asUUID();
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 18ed36d0f3..29a3e6ac3a 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -49,6 +49,11 @@
 /// LLOutboxNotification class
 ///----------------------------------------------------------------------------
 
+LLNotificationsUI::LLOutboxNotification::LLOutboxNotification()
+	: LLSystemNotificationHandler("Outbox", "outbox")
+{
+}
+
 bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify)
 {
 	LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox");
@@ -60,10 +65,10 @@ bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotifi
 
 void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p)
 {
-	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
-	if (sys_handler)
+	LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+	if (notification_handler)
 	{
-		sys_handler->onDelete(p);
+		notification_handler->onDelete(p);
 	}
 }
 
@@ -524,9 +529,9 @@ void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
 
 void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
 {
-	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
-	llassert(sys_handler);
+	LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+	llassert(notification_handler);
 	
-	sys_handler->processNotification(notification);
+	notification_handler->processNotification(notification);
 }
 
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 047472a282..72967eb6c7 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -38,7 +38,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLIMHandler::LLIMHandler()
-:	LLSysHandler("IM Notifications", "notifytoast")
+:	LLCommunicationNotificationHandler("IM Notifications", "notifytoast")
 {
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel()->getHandle();
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 2bc9cdd3c1..58a9b01a45 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -29,6 +29,7 @@
 
 #include "llnotificationhandler.h"
 
+#include "llagentcamera.h"
 #include "llnotifications.h"
 #include "llprogressview.h"
 #include "lltoastnotifypanel.h"
@@ -41,7 +42,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal) 
-:	LLSysHandler(name, notification_type),
+:	LLSystemNotificationHandler(name, notification_type),
 	mIsModal(is_modal)
 {
 	LLScreenChannelBase::Params p;
@@ -123,3 +124,28 @@ void LLAlertHandler::onChange( LLNotificationPtr notification )
 	if(channel)
 		channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
 }
+
+//--------------------------------------------------------------------------
+LLViewerAlertHandler::LLViewerAlertHandler(const std::string& name, const std::string& notification_type)
+	: LLSystemNotificationHandler(name, notification_type)
+{
+}
+
+bool LLViewerAlertHandler::processNotification(const LLNotificationPtr& p)
+{
+	if (gHeadlessClient)
+	{
+		LL_INFOS("LLViewerAlertHandler") << "Alert: " << p->getName() << LL_ENDL;
+	}
+
+	// If we're in mouselook, the mouse is hidden and so the user can't click 
+	// the dialog buttons.  In that case, change to First Person instead.
+	if( gAgentCamera.cameraMouselook() )
+	{
+		gAgentCamera.changeCameraToDefault();
+	}
+
+	return false;
+}
+
+
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 18cd94e685..8fef102cf8 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -38,7 +38,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLGroupHandler::LLGroupHandler()
-:	LLSysHandler("Group Notifications", "groupnotify")
+:	LLCommunicationNotificationHandler("Group Notifications", "groupnotify")
 {
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 4bded6ab30..98b0eecd0d 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -27,6 +27,7 @@
 #ifndef LL_LLNOTIFICATIONHANDLER_H
 #define LL_LLNOTIFICATIONHANDLER_H
 
+#include <boost/intrusive_ptr.hpp>
 
 #include "llwindow.h"
 
@@ -86,23 +87,39 @@ protected:
 /**
  * Handler for system notifications.
  */
-class LLSysHandler : public LLEventHandler, public LLNotificationChannel
+class LLNotificationHandler : public LLEventHandler, public LLNotificationChannel
 {
 public:
-	LLSysHandler(const std::string& name, const std::string& notification_type);
-	virtual ~LLSysHandler() {};
+	LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName);
+	virtual ~LLNotificationHandler() {};
 
 	// base interface functions
-	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
+	virtual void onAdd(LLNotificationPtr p) { processNotification(p); }
+	virtual void onChange(LLNotificationPtr p) { processNotification(p); }
+	virtual void onLoad(LLNotificationPtr p) { processNotification(p); }
+	virtual void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
 
-	virtual bool processNotification(const LLNotificationPtr& notify)=0;
+	virtual bool processNotification(const LLNotificationPtr& notify) = 0;
+};
+
+class LLSystemNotificationHandler : public LLNotificationHandler
+{
+public:
+	LLSystemNotificationHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLSystemNotificationHandler() {};
+};
+
+class LLCommunicationNotificationHandler : public LLNotificationHandler
+{
+public:
+	LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLCommunicationNotificationHandler() {};
 };
 
 /**
- * Handler for chat message notifications.
+ * Handler for chat message notifications. 
  */
+// XXX stinson 12/06/2012 : can I just remove the LLChatHandler class?
 class LLChatHandler : public LLEventHandler
 {
 public:
@@ -115,67 +132,62 @@ public:
  * Handler for IM notifications.
  * It manages life time of IMs, group messages.
  */
-class LLIMHandler : public LLSysHandler
+class LLIMHandler : public LLCommunicationNotificationHandler
 {
 public:
 	LLIMHandler();
 	virtual ~LLIMHandler();
+	bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	bool processNotification(const LLNotificationPtr& p);
-	/*virtual*/ void initChannel();
+	virtual void initChannel();
 };
 
 /**
  * Handler for system informational notices.
  * It manages life time of tip notices.
  */
-class LLTipHandler : public LLSysHandler
+class LLTipHandler : public LLSystemNotificationHandler
 {
 public:
 	LLTipHandler();
 	virtual ~LLTipHandler();
 
-	// base interface functions
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	/*virtual*/ void initChannel();
+	virtual void initChannel();
 };
 
 /**
  * Handler for system informational notices.
  * It manages life time of script notices.
  */
-class LLScriptHandler : public LLSysHandler
+class LLScriptHandler : public LLSystemNotificationHandler
 {
 public:
 	LLScriptHandler();
 	virtual ~LLScriptHandler();
 
-	/*virtual*/ void onDelete(LLNotificationPtr p);
-	// base interface functions
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	/*virtual*/ void onDeleteToast(LLToast* toast);
-	/*virtual*/ void initChannel();
+	virtual void onDeleteToast(LLToast* toast);
+	virtual void initChannel();
 };
 
 
 /**
  * Handler for group system notices.
  */
-class LLGroupHandler : public LLSysHandler
+class LLGroupHandler : public LLCommunicationNotificationHandler
 {
 public:
 	LLGroupHandler();
 	virtual ~LLGroupHandler();
 	
-	// base interface functions
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void initChannel();
@@ -184,15 +196,14 @@ protected:
 /**
  * Handler for alert system notices.
  */
-class LLAlertHandler : public LLSysHandler
+class LLAlertHandler : public LLSystemNotificationHandler
 {
 public:
 	LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);
 	virtual ~LLAlertHandler();
 
-	/*virtual*/ void onChange(LLNotificationPtr p);
-	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual void onChange(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void initChannel();
@@ -200,67 +211,87 @@ protected:
 	bool	mIsModal;
 };
 
+class LLViewerAlertHandler  : public LLSystemNotificationHandler
+{
+	LOG_CLASS(LLViewerAlertHandler);
+public:
+	LLViewerAlertHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLViewerAlertHandler() {};
+
+	virtual void onDelete(LLNotificationPtr p) {};
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
+};
+
+typedef boost::intrusive_ptr<LLViewerAlertHandler> LLViewerAlertHandlerPtr;
+
 /**
  * Handler for offers notices.
  * It manages life time of offer notices.
  */
-class LLOfferHandler : public LLSysHandler
+class LLOfferHandler : public LLCommunicationNotificationHandler
 {
 public:
 	LLOfferHandler();
 	virtual ~LLOfferHandler();
 
-	// base interface functions
-	/*virtual*/ void onChange(LLNotificationPtr p);
-	/*virtual*/ void onDelete(LLNotificationPtr notification);
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual void onChange(LLNotificationPtr p);
+	virtual void onDelete(LLNotificationPtr notification);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	/*virtual*/ void initChannel();
+	virtual void initChannel();
 };
 
 /**
  * Handler for UI hints.
  */
-class LLHintHandler : public LLNotificationChannel
+class LLHintHandler : public LLSystemNotificationHandler
 {
 public:
-	LLHintHandler() : LLNotificationChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"))
-	{}
+	LLHintHandler();
 	virtual ~LLHintHandler() {}
 
-	/*virtual*/ void onAdd(LLNotificationPtr p);
-	/*virtual*/ void onLoad(LLNotificationPtr p);
-	/*virtual*/ void onDelete(LLNotificationPtr p);
+	virtual void onAdd(LLNotificationPtr p);
+	virtual void onLoad(LLNotificationPtr p);
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 
 /**
  * Handler for browser notifications
  */
-class LLBrowserNotification : public LLNotificationChannel
+class LLBrowserNotification : public LLSystemNotificationHandler
 {
 public:
-	LLBrowserNotification()
-	: LLNotificationChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"))
-	{}
-	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
-	bool processNotification(const LLNotificationPtr& p);
+	LLBrowserNotification();
+	virtual ~LLBrowserNotification() {}
+
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 	
 /**
  * Handler for outbox notifications
  */
-class LLOutboxNotification : public LLNotificationChannel
+class LLOutboxNotification : public LLSystemNotificationHandler
 {
 public:
-	LLOutboxNotification()
-	:	LLNotificationChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"))
-	{}
-	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onChange(LLNotificationPtr p) { }
-	/*virtual*/ void onDelete(LLNotificationPtr p);
-	bool processNotification(const LLNotificationPtr& p);
+	LLOutboxNotification();
+	virtual ~LLOutboxNotification() {};
+	virtual void onChange(LLNotificationPtr p) { }
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 	
 class LLHandlerUtil
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 7f1216ff40..f0175d677c 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -41,8 +41,16 @@
 
 using namespace LLNotificationsUI;
 
-LLSysHandler::LLSysHandler(const std::string& name, const std::string& notification_type)
-:	LLNotificationChannel(name, "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
+LLNotificationHandler::LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName)
+:	LLNotificationChannel(name, parentName, LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
+{}
+
+LLSystemNotificationHandler::LLSystemNotificationHandler(const std::string& name, const std::string& notification_type)
+	: LLNotificationHandler(name, notification_type, "System")
+{}
+
+LLCommunicationNotificationHandler::LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type)
+	: LLNotificationHandler(name, notification_type, "Communication")
 {}
 
 // static
diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp
index 271f418507..f40369a2e0 100644
--- a/indra/newview/llnotificationhinthandler.cpp
+++ b/indra/newview/llnotificationhinthandler.cpp
@@ -33,6 +33,27 @@
 
 using namespace LLNotificationsUI;
 
-void LLHintHandler::onAdd(LLNotificationPtr p) { LLHints::show(p); }
-void LLHintHandler::onLoad(LLNotificationPtr p) { LLHints::show(p); }
-void LLHintHandler::onDelete(LLNotificationPtr p) { LLHints::hide(p); }
+LLHintHandler::LLHintHandler()
+	: LLSystemNotificationHandler("Hints", "hint")
+{
+}
+
+void LLHintHandler::onAdd(LLNotificationPtr p)
+{
+	LLHints::show(p);
+}
+
+void LLHintHandler::onLoad(LLNotificationPtr p)
+{
+	LLHints::show(p);
+}
+
+void LLHintHandler::onDelete(LLNotificationPtr p)
+{
+	LLHints::hide(p);
+}
+
+bool LLHintHandler::processNotification(const LLNotificationPtr& p)
+{
+	return false;
+}
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index ff5b5e21f7..da38c9063b 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -41,7 +41,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLOfferHandler::LLOfferHandler()
-:	LLSysHandler("Offer", "offer")
+:	LLCommunicationNotificationHandler("Offer", "offer")
 {
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 290a81f91c..e2d4e9f8ce 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -39,7 +39,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLScriptHandler::LLScriptHandler()
-:	LLSysHandler("Notifications", "notify")
+:	LLSystemNotificationHandler("Notifications", "notify")
 {
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index faa67b5ea4..a85335f1ba 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -42,7 +42,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLTipHandler::LLTipHandler()
-:	LLSysHandler("NotificationTips", "notifytip")
+:	LLSystemNotificationHandler("NotificationTips", "notifytip")
 {
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 1b45e6f85d..7b1cf6e180 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -39,6 +39,7 @@
 #include "llagentcamera.h"
 #include "llfloaterreg.h"
 #include "llmeshrepository.h"
+#include "llnotificationhandler.h"
 #include "llpanellogin.h"
 #include "llviewerkeyboard.h"
 #include "llviewermenu.h"
@@ -127,6 +128,7 @@
 #include "llmorphview.h"
 #include "llmoveview.h"
 #include "llnavigationbar.h"
+#include "llnotificationhandler.h"
 #include "llpanelpathfindingrebakenavmesh.h"
 #include "llpaneltopinfobar.h"
 #include "llpopupview.h"
@@ -1554,11 +1556,13 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
 	mViewerWindowListener.reset(new LLViewerWindowListener(this));
 
-	mAlertsChannel.reset(new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")));
-	mModalAlertsChannel.reset(new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")));
+	mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
+	mCommunicationChannel.reset(new LLNotificationChannel("Communication", "Visible", boost::bind(&LLAgent::isDoNotDisturb, &gAgent)));
+	mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
+	mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
 
-	mAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
-	mModalAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
+	//mAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
+	//mModalAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
 	bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications");
 	LLNotifications::instance().setIgnoreAllNotifications(ignore);
 	if (ignore)
@@ -5001,25 +5005,6 @@ LLRect LLViewerWindow::getChatConsoleRect()
 //----------------------------------------------------------------------------
 
 
-//static 
-bool LLViewerWindow::onAlert(const LLSD& notify)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if (gHeadlessClient)
-	{
-		llinfos << "Alert: " << notification->getName() << llendl;
-	}
-
-	// If we're in mouselook, the mouse is hidden and so the user can't click 
-	// the dialog buttons.  In that case, change to First Person instead.
-	if( gAgentCamera.cameraMouselook() )
-	{
-		gAgentCamera.changeCameraToDefault();
-	}
-	return false;
-}
-
 void LLViewerWindow::setUIVisibility(bool visible)
 {
 	mUIVisible = visible;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index ee6a7793f8..b828a05384 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -43,6 +43,8 @@
 #include "lltimer.h"
 #include "llstat.h"
 #include "llmousehandler.h"
+#include "llnotifications.h"
+#include "llnotificationhandler.h"
 #include "llhandle.h"
 #include "llinitparam.h"
 
@@ -401,7 +403,6 @@ public:
 
 private:
 	bool                    shouldShowToolTipFor(LLMouseHandler *mh);
-	static bool onAlert(const LLSD& notify);
 
 	void			switchToolByMask(MASK mask);
 	void			destroyWindow();
@@ -418,8 +419,10 @@ private:
 	bool			mActive;
 	bool			mUIVisible;
 
-	boost::shared_ptr<class LLNotificationChannel>	mAlertsChannel,
-													mModalAlertsChannel;
+	LLNotificationChannelPtr                    mSystemChannel;
+	LLNotificationChannelPtr                    mCommunicationChannel;
+	LLNotificationsUI::LLViewerAlertHandlerPtr  mAlertsChannel;
+	LLNotificationsUI::LLViewerAlertHandlerPtr  mModalAlertsChannel;
 
 	LLRect			mWindowRectRaw;				// whole window, including UI
 	LLRect			mWindowRectScaled;			// whole window, scaled by UI size
-- 
cgit v1.2.3


From bb322a1cccd3fab28951ad4e11b5edcfc4e48140 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 7 Dec 2012 00:10:50 -0800
Subject: CHUI-580 : Fixed : Clean up the use of display name. Allow the use of
 the legacy protocol in settings.xml

---
 indra/llcommon/llavatarname.cpp         |  75 ++++++++++----
 indra/llcommon/llavatarname.h           |  13 ++-
 indra/llmessage/llavatarnamecache.cpp   | 170 +++++++++++---------------------
 indra/llmessage/llavatarnamecache.h     |  32 +++---
 indra/llmessage/llcachename.h           |   2 +-
 indra/llui/tests/llurlentry_stub.cpp    |   5 -
 indra/newview/app_settings/settings.xml |  11 +++
 indra/newview/llstartup.cpp             |   2 +-
 indra/newview/llviewermenu.cpp          |   2 +-
 9 files changed, 154 insertions(+), 158 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index b49e6a7aac..95ecce509b 100644
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -45,6 +45,12 @@ static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
 
 bool LLAvatarName::sUseDisplayNames = true;
 
+// Minimum time-to-live (in seconds) for a name entry.
+// Avatar name should always guarantee to expire reasonably soon by default
+// so if the failure to get a valid expiration time was due to something temporary 
+// we will eventually request and get the right data.
+const F64 MIN_ENTRY_LIFETIME = 60.0;
+
 LLAvatarName::LLAvatarName()
 :	mUsername(),
 	mDisplayName(),
@@ -107,40 +113,67 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
 	}
 }
 
-void LLAvatarName::fromString(const std::string& full_name, F64 expires)
+// Transform a string (typically provided by the legacy service) into a decent
+// avatar name instance.
+void LLAvatarName::fromString(const std::string& full_name)
 {
 	mDisplayName = full_name;
 	std::string::size_type index = full_name.find(' ');
 	if (index != std::string::npos)
 	{
+		// The name is in 2 parts (first last)
 		mLegacyFirstName = full_name.substr(0, index);
 		mLegacyLastName = full_name.substr(index+1);
-		mUsername = mLegacyFirstName + " " + mLegacyLastName;
+		if (mLegacyLastName != "Resident")
+		{
+			mUsername = mLegacyFirstName + "." + mLegacyLastName;
+			mDisplayName = full_name;
+			LLStringUtil::toLower(mUsername);
+		}
+		else
+		{
+			// Very old names do have a dummy "Resident" last name 
+			// that we choose to hide from users.
+			mUsername = mLegacyFirstName;
+			mDisplayName = mLegacyFirstName;
+		}
 	}
 	else
 	{
 		mLegacyFirstName = full_name;
 		mLegacyLastName = "";
 		mUsername = full_name;
+		mDisplayName = full_name;
 	}
 	mIsDisplayNameDefault = true;
 	mIsTemporaryName = true;
+	setExpires(MIN_ENTRY_LIFETIME);
+}
+
+void LLAvatarName::setExpires(F64 expires)
+{
 	mExpires = LLFrameTimer::getTotalSeconds() + expires;
 }
 
 std::string LLAvatarName::getCompleteName() const
 {
 	std::string name;
-	if (mUsername.empty() || mIsDisplayNameDefault)
-	// If the display name feature is off
-	// OR this particular display name is defaulted (i.e. based on user name),
-	// then display only the easier to read instance of the person's name.
+	if (sUseDisplayNames)
 	{
-		name = mDisplayName;
+		if (mUsername.empty() || mIsDisplayNameDefault)
+		{
+			// If this particular display name is defaulted (i.e. based on user name),
+			// then display only the easier to read instance of the person's name.
+			name = mDisplayName;
+		}
+		else
+		{
+			name = mDisplayName + " (" + mUsername + ")";
+		}
 	}
 	else
 	{
-		name = mDisplayName + " (" + mUsername + ")";
+		name = getUserName();
 	}
 	return name;
 }
@@ -159,23 +192,29 @@ std::string LLAvatarName::getDisplayName() const
 
 std::string LLAvatarName::getUserName() const
 {
-	// If we cannot create a user name from the legacy strings, use the display name
-	if (mLegacyFirstName.empty() && mLegacyLastName.empty())
+	std::string name;
+	if (mLegacyLastName.empty() || (mLegacyLastName == "Resident"))
 	{
-		return mDisplayName;
+		if (mLegacyFirstName.empty())
+		{
+			// If we cannot create a user name from the legacy strings, use the display name
+			name = mDisplayName;
+		}
+		else
+		{
+			// The last name might be empty if it defaulted to "Resident"
+			name = mLegacyFirstName;
+		}
+	}
+	else
+	{
+		name = mLegacyFirstName + " " + mLegacyLastName;
 	}
-
-	std::string name;
-	name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() );
-	name = mLegacyFirstName;
-	name += " ";
-	name += mLegacyLastName;
 	return name;
 }
 
 void LLAvatarName::dump() const
 {
-	llinfos << "Merov debug : display = " << mDisplayName << ", user = " << mUsername << ", complete = " << getCompleteName() << ", legacy = " << getUserName() << " first = " << mLegacyFirstName << " last = " << mLegacyLastName << llendl;
 	LL_DEBUGS("AvNameCache") << "LLAvatarName: "
 	                         << "user '" << mUsername << "' "
 							 << "display '" << mDisplayName << "' "
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index cf9eb27b03..2f8c534974 100644
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -39,20 +39,25 @@ public:
 	
 	bool operator<(const LLAvatarName& rhs) const;
 
+	// Conversion to and from LLSD (cache file or server response)
 	LLSD asLLSD() const;
-
 	void fromLLSD(const LLSD& sd);
 
 	// Used only in legacy mode when the display name capability is not provided server side
-	void fromString(const std::string& full_name, F64 expires = 0.0f);
+	// or to otherwise create a temporary valid item.
+	void fromString(const std::string& full_name);
 	
+	// Set the name object to become invalid in "expires" seconds from now
+	void setExpires(F64 expires);
+
+	// Set and get the display name flag set by the user in preferences.
 	static void setUseDisplayNames(bool use);
 	static bool useDisplayNames();
 	
-	// Name is valid if not temporary and not yet expired
+	// A name object is valid if not temporary and not yet expired (default is expiration not checked)
 	bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); }
 	
-	// 
+	// Return true if the name is made up from legacy or temporary data
 	bool isDisplayNameDefault() const { return mIsDisplayNameDefault; }
 	
 	// For normal names, returns "James Linden (james.linden)"
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 329871d8eb..15c4f2a207 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -47,18 +47,22 @@ namespace LLAvatarNameCache
 	// current region supports display names.
 	bool sRunning = false;
 	
+	// Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
+	// For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
+	bool sUsePeopleAPI = true;
+	
 	// Base lookup URL for name service.
 	// On simulator, loaded from indra.xml
 	// On viewer, usually a simulator capability (at People API team's request)
 	// Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
 	std::string sNameLookupURL;
 
-	// accumulated agent IDs for next query against service
+	// Accumulated agent IDs for next query against service
 	typedef std::set<LLUUID> ask_queue_t;
 	ask_queue_t sAskQueue;
 
-	// agent IDs that have been requested, but with no reply
-	// maps agent ID to frame time request was made
+	// Agent IDs that have been requested, but with no reply.
+	// Maps agent ID to frame time request was made.
 	typedef std::map<LLUUID, F64> pending_queue_t;
 	pending_queue_t sPendingQueue;
 
@@ -69,21 +73,21 @@ namespace LLAvatarNameCache
 	typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
 	signal_map_t sSignalMap;
 
-	// names we know about
+	// The cache at last, i.e. avatar names we know about.
 	typedef std::map<LLUUID, LLAvatarName> cache_t;
 	cache_t sCache;
 
-	// Send bulk lookup requests a few times a second at most
-	// only need per-frame timing resolution
+	// Send bulk lookup requests a few times a second at most.
+	// Only need per-frame timing resolution.
 	LLFrameTimer sRequestTimer;
 
-    /// Maximum time an unrefreshed cache entry is allowed
+    // Maximum time an unrefreshed cache entry is allowed.
     const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
 
-    /// Time when unrefreshed cached names were checked last
+    // Time when unrefreshed cached names were checked last.
     static F64 sLastExpireCheck;
 
-	/// Time-to-live for a temp cache entry.
+	// Time-to-live for a temp cache entry.
 	const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
 
 	//-----------------------------------------------------------------------
@@ -91,26 +95,18 @@ namespace LLAvatarNameCache
 	//-----------------------------------------------------------------------
 
 	// Handle name response off network.
-	// Optionally skip adding to cache, used when this is a fallback to the
-	// legacy name system.
 	void processName(const LLUUID& agent_id,
-					 const LLAvatarName& av_name,
-					 bool add_to_cache);
+					 const LLAvatarName& av_name);
 
 	void requestNamesViaCapability();
 
 	// Legacy name system callback
 	void legacyNameCallback(const LLUUID& agent_id,
 							const std::string& full_name,
-							bool is_group
-							);
+							bool is_group);
 
 	void requestNamesViaLegacy();
 
-	// Fill in an LLAvatarName with the legacy name data
-	void buildLegacyName(const std::string& full_name,
-						 LLAvatarName* av_name);
-
 	// Do a single callback to a given slot
 	void fireSignal(const LLUUID& agent_id,
 					const callback_slot_t& slot,
@@ -209,7 +205,7 @@ public:
 			av_name.dump();
 			
 			// cache it and fire signals
-			LLAvatarNameCache::processName(agent_id, av_name, true);
+			LLAvatarNameCache::processName(agent_id, av_name);
 		}
 
 		// Same logic as error response case
@@ -271,7 +267,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
     }
 	else
     {
-        // we have a chached (but probably expired) entry - since that would have
+        // we have a cached (but probably expired) entry - since that would have
         // been returned by the get method, there is no need to signal anyone
 
         // Clear this agent from the pending list
@@ -281,22 +277,20 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
         LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL;
 		av_name.dump();
 
-		av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
+		 // Reset expiry time so we don't constantly rerequest.
+		av_name.setExpires(TEMP_CACHE_ENTRY_LIFETIME);
     }
 }
 
-void LLAvatarNameCache::processName(const LLUUID& agent_id,
-									const LLAvatarName& av_name,
-									bool add_to_cache)
+void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
-	if (add_to_cache)
-	{
-		sCache[agent_id] = av_name;
-	}
+	// Add to the cache
+	sCache[agent_id] = av_name;
 
+	// Suppress request from the queue
 	sPendingQueue.erase(agent_id);
 
-	// signal everyone waiting on this name
+	// Signal everyone waiting on this name
 	signal_map_t::iterator sig_it =	sSignalMap.find(agent_id);
 	if (sig_it != sSignalMap.end())
 	{
@@ -373,22 +367,20 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
 										   const std::string& full_name,
 										   bool is_group)
 {
-	// Construct a dummy record for this name.  By convention, SLID is blank
-	// Never expires, but not written to disk, so lasts until end of session.
-	LLAvatarName av_name;
 	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback "
 							 << "agent " << agent_id << " "
 							 << "full name '" << full_name << "'"
 							 << ( is_group ? " [group]" : "" )
 							 << LL_ENDL;
-	buildLegacyName(full_name, &av_name);
+	
+	// Construct an av_name record from this name.
+	LLAvatarName av_name;
+	av_name.fromString(full_name);
+	av_name.dump();
 
 	// Add to cache, because if we don't we'll keep rerequesting the
-	// same record forever.  buildLegacyName should always guarantee
-	// that these records expire reasonably soon
-	// (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due
-	// to something temporary we will eventually request and get the right data.
-	processName(agent_id, av_name, true);
+	// same record forever.
+	processName(agent_id, av_name);
 }
 
 void LLAvatarNameCache::requestNamesViaLegacy()
@@ -410,18 +402,19 @@ void LLAvatarNameCache::requestNamesViaLegacy()
 		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL;
 
 		gCacheName->get(agent_id, false,  // legacy compatibility
-			boost::bind(&LLAvatarNameCache::legacyNameCallback,
-				_1, _2, _3));
+			boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3));
 	}
 }
 
-void LLAvatarNameCache::initClass(bool running)
+void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
 {
 	sRunning = running;
+	sUsePeopleAPI = usePeopleAPI;
 }
 
 void LLAvatarNameCache::cleanupClass()
 {
+	sCache.clear();
 }
 
 void LLAvatarNameCache::importFile(std::istream& istr)
@@ -481,6 +474,11 @@ bool LLAvatarNameCache::hasNameLookupURL()
 	return !sNameLookupURL.empty();
 }
 
+bool LLAvatarNameCache::usePeopleAPI()
+{
+	return hasNameLookupURL() && sUsePeopleAPI;
+}
+
 void LLAvatarNameCache::idle()
 {
 	// By convention, start running at first idle() call
@@ -497,13 +495,12 @@ void LLAvatarNameCache::idle()
 
 	if (!sAskQueue.empty())
 	{
-        if (hasNameLookupURL())
+        if (usePeopleAPI())
         {
             requestNamesViaCapability();
         }
         else
         {
-            // ...fall back to legacy name cache system
             requestNamesViaLegacy();
         }
 	}
@@ -563,18 +560,6 @@ void LLAvatarNameCache::eraseUnrefreshed()
 	}
 }
 
-void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
-										LLAvatarName* av_name)
-{
-	llassert(av_name);
-	av_name->fromString(full_name,TEMP_CACHE_ENTRY_LIFETIME);
-	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
-							 << full_name
-							 << LL_ENDL;
-	// DEBUG ONLY!!! DO NOT COMMIT!!!
-	av_name->dump();
-}
-
 // fills in av_name if it has it in the cache, even if expired (can check expiry time)
 // returns bool specifying  if av_name was filled, false otherwise
 bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
@@ -582,38 +567,24 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
 	if (sRunning)
 	{
 		// ...only do immediate lookups when cache is running
-		if (hasNameLookupURL())
+		std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+		if (it != sCache.end())
 		{
-			// ...use display names cache
-			std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
-			if (it != sCache.end())
-			{
-				*av_name = it->second;
+			*av_name = it->second;
 
-				// re-request name if entry is expired
-				if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
+			// re-request name if entry is expired
+			if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
+			{
+				if (!isRequestPending(agent_id))
 				{
-					if (!isRequestPending(agent_id))
-					{
-						LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
-												 << "refresh agent " << agent_id
-												 << LL_ENDL;
-						sAskQueue.insert(agent_id);
-					}
+					LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
+											 << "refresh agent " << agent_id
+											 << LL_ENDL;
+					sAskQueue.insert(agent_id);
 				}
-				
-				return true;
-			}
-		}
-		else
-		{
-			// ...use legacy names cache
-			std::string full_name;
-			if (gCacheName->getFullName(agent_id, full_name))
-			{
-				buildLegacyName(full_name, av_name);
-				return true;
 			}
+				
+			return true;
 		}
 	}
 
@@ -644,30 +615,14 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
 	if (sRunning)
 	{
 		// ...only do immediate lookups when cache is running
-		if (hasNameLookupURL())
-		{
-			// ...use new cache
-			std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
-			if (it != sCache.end())
-			{
-				const LLAvatarName& av_name = it->second;
-				
-				if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
-				{
-					// ...name already exists in cache, fire callback now
-					fireSignal(agent_id, slot, av_name);
-					return connection;
-				}
-			}
-		}
-		else
+		std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+		if (it != sCache.end())
 		{
-			// ...use old name system
-			std::string full_name;
-			if (gCacheName->getFullName(agent_id, full_name))
+			const LLAvatarName& av_name = it->second;
+			
+			if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
 			{
-				LLAvatarName av_name;
-				buildLegacyName(full_name, &av_name);
+				// ...name already exists in cache, fire callback now
 				fireSignal(agent_id, slot, av_name);
 				return connection;
 			}
@@ -709,11 +664,6 @@ void LLAvatarNameCache::setUseDisplayNames(bool use)
 	}
 }
 
-void LLAvatarNameCache::flushCache()
-{
-	sCache.clear();
-}
-
 void LLAvatarNameCache::erase(const LLUUID& agent_id)
 {
 	sCache.erase(agent_id);
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index e172601432..2a8eb46187 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -37,33 +37,33 @@ class LLUUID;
 
 namespace LLAvatarNameCache
 {
-		
 	typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
 
 	// Until the cache is set running, immediate lookups will fail and
 	// async lookups will be queued.  This allows us to block requests
 	// until we know if the first region supports display names.
-	void initClass(bool running);
+	void initClass(bool running, bool usePeopleAPI);
 	void cleanupClass();
 
+	// Import/export the name cache to file.
 	void importFile(std::istream& istr);
 	void exportFile(std::ostream& ostr);
 
-	// On the viewer, usually a simulator capabilitity
-	// If empty, name cache will fall back to using legacy name
-	// lookup system
+	// On the viewer, usually a simulator capabilitity.
+	// If empty, name cache will fall back to using legacy name lookup system.
 	void setNameLookupURL(const std::string& name_lookup_url);
 
-	// Do we have a valid lookup URL, hence are we trying to use the
-	// new display name lookup system?
+	// Do we have a valid lookup URL, i.e. are we trying to use the
+	// more recent display name lookup system?
 	bool hasNameLookupURL();
+	bool usePeopleAPI();
 	
 	// Periodically makes a batch request for display names not already in
-	// cache.  Call once per frame.
+	// cache. Called once per frame.
 	void idle();
 
 	// If name is in cache, returns true and fills in provided LLAvatarName
-	// otherwise returns false
+	// otherwise returns false.
 	bool get(const LLUUID& agent_id, LLAvatarName *av_name);
 
 	// Callback types for get() below
@@ -73,23 +73,19 @@ namespace LLAvatarNameCache
 	typedef callback_signal_t::slot_type callback_slot_t;
 	typedef boost::signals2::connection callback_connection_t;
 
-	// Fetches name information and calls callback.
-	// If name information is in cache, callback will be called immediately.
+	// Fetches name information and calls callbacks.
+	// If name information is in cache, callbacks will be called immediately.
 	callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
 
-	// Allow display names to be explicitly disabled for testing.
+	// Set display name: flips the switch and triggers the callbacks.
 	void setUseDisplayNames(bool use);
-	bool useDisplayNames();
-
-	void flushCache();
 	
+	void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
 	void erase(const LLUUID& agent_id);
 
-    /// Provide some fallback for agents that return errors
+    /// Provide some fallback for agents that return errors.
 	void handleAgentError(const LLUUID& agent_id);
 
-	void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
-
 	// Compute name expiration time from HTTP Cache-Control header,
 	// or return default value, in seconds from epoch.
 	F64 nameExpirationFromHeaders(LLSD headers);
diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h
index b108e37157..d238c3a247 100644
--- a/indra/llmessage/llcachename.h
+++ b/indra/llmessage/llcachename.h
@@ -40,7 +40,7 @@ typedef boost::signals2::signal<void (const LLUUID& id,
                                       bool is_group)> LLCacheNameSignal;
 typedef LLCacheNameSignal::slot_type LLCacheNameCallback;
 
-// Old callback with user data for compatability
+// Old callback with user data for compatibility
 typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*);
 
 // Here's the theory:
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index f8797fd257..5d3f9ac327 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -46,11 +46,6 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
 	return connection;
 }
 
-bool LLAvatarNameCache::useDisplayNames()
-{
-	return false;
-}
-
 //
 // Stub implementation for LLCacheName
 //
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ece711a128..423e5a00df 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12648,6 +12648,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+  <key>UsePeopleAPI</key>
+  <map>
+    <key>Comment</key>
+    <string>Use the people API cap for avatar name fetching, use old legacy protocol if false. Requires restart.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
     <key>UseStartScreen</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 34259658ea..66a2e6dbda 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2806,7 +2806,7 @@ void LLStartUp::initNameCache()
 
 	// Start cache in not-running state until we figure out if we have
 	// capabilities for display name lookup
-	LLAvatarNameCache::initClass(false);
+	LLAvatarNameCache::initClass(false,gSavedSettings.getBOOL("UsePeopleAPI"));
 	LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
 }
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 5284d2650e..7ae717cb42 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -8080,7 +8080,7 @@ class LLWorldPostProcess : public view_listener_t
 
 void handle_flush_name_caches()
 {
-	LLAvatarNameCache::flushCache();
+	LLAvatarNameCache::cleanupClass();
 	if (gCacheName) gCacheName->clear();
 }
 
-- 
cgit v1.2.3


From 935b3326254f75af876b6c9aeb1648ac3a9802cf Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 7 Dec 2012 15:03:32 +0200
Subject: CHUI-427 FIXED Voice button is added to Conversations floater.

---
 indra/newview/llfloaterimcontainer.cpp                    | 13 +++++++++++++
 indra/newview/llfloaterimcontainer.h                      |  2 ++
 indra/newview/llfloaterimsessiontab.cpp                   |  3 ++-
 .../newview/skins/default/xui/en/floater_im_container.xml | 15 ++++++++++++++-
 4 files changed, 31 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index b8a37da3fa..bd99e88a9d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -206,6 +206,7 @@ BOOL LLFloaterIMContainer::postBuild()
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onExpandCollapseButtonClicked, this));
 	mStubCollapseBtn = getChild<LLButton>("stub_collapse_btn");
 	mStubCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMContainer::onStubCollapseButtonClicked, this));
+	getChild<LLButton>("speak_btn")->setClickedCallback(boost::bind(&LLFloaterIMContainer::onSpeakButtonClicked, this));
 
 	childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this));
 
@@ -341,6 +342,11 @@ void LLFloaterIMContainer::onStubCollapseButtonClicked()
 	collapseMessagesPane(true);
 }
 
+void LLFloaterIMContainer::onSpeakButtonClicked()
+{
+	LLAgent::toggleMicrophone("speak");
+	updateSpeakBtnState();
+}
 void LLFloaterIMContainer::onExpandCollapseButtonClicked()
 {
 	if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()
@@ -1672,6 +1678,13 @@ void LLFloaterIMContainer::reSelectConversation()
 	}
 }
 
+void LLFloaterIMContainer::updateSpeakBtnState()
+{
+	LLButton* mSpeakBtn = getChild<LLButton>("speak_btn");
+	mSpeakBtn->setToggleState(LLVoiceClient::getInstance()->getUserPTTState());
+	mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak"));
+}
+
 void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
 {
     //Finds the conversation line item to flash using the session_id
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index c9987bffe8..92985c036a 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -117,6 +117,7 @@ private:
 	void onExpandCollapseButtonClicked();
 	void onStubCollapseButtonClicked();
 	void processParticipantsStyleUpdate();
+	void onSpeakButtonClicked();
 
 	void collapseConversationsPane(bool collapse);
 
@@ -172,6 +173,7 @@ public:
 	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
 	void setNearbyDistances();
 	void reSelectConversation();
+	void updateSpeakBtnState();
 	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
 
 private:
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index b50b8c2d32..0567ea3d8a 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -698,7 +698,8 @@ void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)
 	voiceButton->setToolTip(
 			callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip"));
 
-    enableDisableCallBtn();
+	LLFloaterIMContainer::getInstance()->updateSpeakBtnState();
+	enableDisableCallBtn();
 
 }
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 152c897120..a3648f3c9d 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -73,13 +73,26 @@
                      image_hover_unselected="Toolbar_Middle_Over"
                      image_overlay="Conv_toolbar_plus"
                      image_selected="Toolbar_Middle_Selected"
-                      image_unselected="Toolbar_Middle_Off"
+                     image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
                      top="5"
                      left_pad="4"
                      name="add_btn"
                      tool_tip="Start a new conversation"
                      width="31"/>
+                    <button
+                     follows="top|left"
+                     height="25"
+                     image_hover_unselected="Toolbar_Middle_Over"
+                     image_overlay="Command_Speak_Icon"
+                     image_selected="Toolbar_Middle_Selected"
+                     image_unselected="Toolbar_Middle_Off"
+                     layout="topleft"
+                     top="5"
+                     left_pad="4"
+                     name="speak_btn"
+                     tool_tip="Speak with people using your microphone"
+                     width="31"/>	
                 </layout_panel>
                 <layout_panel
                  auto_resize="false"
-- 
cgit v1.2.3


From b3e667cc0e3c0c08fc8caed1408ceaa2798875b1 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 7 Dec 2012 15:13:26 +0200
Subject: CHUI-582 : fixed : Resizing conversation floater initially only
 resizes conversation list width.

---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index a3648f3c9d..9f6503d799 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -32,7 +32,7 @@
      top="0"
      width="450">
         <layout_panel
-         auto_resize="true"
+         auto_resize="false"
          user_resize="true"        
          height="430"
          name="conversations_layout_panel"
-- 
cgit v1.2.3


From 979360340fe05e83948fb1680b2e87292a333094 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 7 Dec 2012 15:42:33 +0200
Subject: CHUI-530 FIXED Changed selectConversation() to reSelectConversation()

---
 indra/newview/llfloaterimcontainer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index bd99e88a9d..c36128b0bd 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1656,7 +1656,7 @@ void LLFloaterIMContainer::openNearbyChat()
 		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,LLUUID()));
 		if (nearby_chat)
 		{
-			selectConversation(LLUUID());
+			reSelectConversation();
 			nearby_chat->setOpen(TRUE);
 		}
 	}
-- 
cgit v1.2.3


From fb5417b7166742b081d61d33871d13ef76719fa4 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 7 Dec 2012 17:53:17 +0200
Subject: CHUI-564 : Fixed : (Conversation floater always opens when new IM is
 received) : Remove obsolete code: control of an visibility of container was
 delegated to on_new_message() [see llimview.cpp]

---
 indra/newview/llfloaterimsessiontab.cpp | 5 -----
 1 file changed, 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 0567ea3d8a..7d6ba093eb 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -168,11 +168,6 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
 				floater_container->addFloater(conversp, FALSE, LLTabContainer::END);
-
-				if (!floater_container->getVisible())
-				{
-					LLFloaterReg::toggleInstanceOrBringToFront("im_container");			
-				}
 			}
 			else
 			{
-- 
cgit v1.2.3


From 6122f000cb249dd2f8cbc0d16e664bb1b00d5864 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 7 Dec 2012 17:43:05 +0200
Subject: CHUI-547 : Fixed : (Clicking IM toast does not select message panel
 in conversation floater) : select new session floater when a container is
 hidden

---
 indra/newview/llfloaterimsessiontab.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 7d6ba093eb..8e4e4e809a 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -167,7 +167,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 			if (!conversp->isNearbyChat()
 					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
-				floater_container->addFloater(conversp, FALSE, LLTabContainer::END);
+				floater_container->addFloater(conversp, !floater_container->getVisible(), LLTabContainer::END);
 			}
 			else
 			{
-- 
cgit v1.2.3


From cd20d3dc2b02754ca14b314a9cab505535ff8e8d Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Fri, 7 Dec 2012 19:56:16 +0200
Subject: CHUI-512 FIXED New incoming conversations take focus in message panel
 only and do not show toasts

---
 indra/newview/llfloaterimsessiontab.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 8e4e4e809a..4c6d8fa5a0 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -167,7 +167,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 			if (!conversp->isNearbyChat()
 					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
-				floater_container->addFloater(conversp, !floater_container->getVisible(), LLTabContainer::END);
+				floater_container->addFloater(conversp, !floater_container->getVisible(), LLTabContainer::RIGHT_OF_CURRENT);
 			}
 			else
 			{
-- 
cgit v1.2.3


From 0037b1e2c75d49481aee6fffd24395a79fbf6699 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 7 Dec 2012 14:44:15 -0800
Subject: CHUI-579: Post code review. Renamed variables to make easier to read.

---
 indra/newview/llfloaterimnearbychathandler.cpp |  5 ++-
 indra/newview/llimview.cpp                     | 43 +++++++++++++-------------
 2 files changed, 25 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 903c903381..f64cfd0245 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -557,7 +557,10 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
 	// Send event on to LLEventStream
 	sChatWatcher->post(chat);
 
-	if( nearby_chat->isInVisibleChain()
+    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+
+	if( nearby_chat->hasFocus() 
+        || im_box->hasFocus()
 		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") )
 		|| mChannel.isDead()
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 6ffc3b610b..ab2f275711 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -159,10 +159,11 @@ void on_new_message(const LLSD& msg)
     LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
-    bool sessionFloaterInActive = session_floater
-                                    && (!session_floater->isInVisibleChain()) //conversation floater not displayed
-                                        || 
-                                        (session_floater->isInVisibleChain() && session_floater->hasFocus() == false); //conversation floater is displayed but doesn't have focus
+    //session floater not focused (visible or not)
+    bool sessionFloaterNotFocused = session_floater && !session_floater->hasFocus(); 
+
+    //conversation floater not focused (visible or not)
+    bool conversationFloaterNotFocused = im_box && !im_box->hasFocus();
 
     if ("toast" == action)
     {
@@ -185,43 +186,41 @@ void on_new_message(const LLSD& msg)
             return;
         }
 
-        //Show IM toasts (upper right toasts)
-        if(session_id.notNull())
-        {
-            LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
-        }
-
-        //Session floater has focus, so don't need to show notification flashes
-        if(sessionFloaterInActive)
+        //User is not focused on conversation containing the message
+        if(sessionFloaterNotFocused)
         {
-            //Flash converstation line item anytime that conversation doesn't have focus
             im_box->flashConversationItemWidget(session_id, true);
 
-            //Only flash the 'Chat' FUI button when the conversation floater isn't focused (implies not front most floater)
-            if(!im_box->hasFocus())
+            //The conversation floater isn't focused/open
+            if(conversationFloaterNotFocused)
             {
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
+
+                //Show IM toasts (upper right toasts)
+                LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
             }
         }
     }
     else if ("flash" == action)
     {
-        if(sessionFloaterInActive && !im_box->hasFocus())
+        //User is not focused on conversation containing the message
+        if(sessionFloaterNotFocused && conversationFloaterNotFocused)
         {
-            gToolBarView->flashCommand(LLCommandId("chat"), true); // flashing of the FUI button "Chat"
+            gToolBarView->flashCommand(LLCommandId("chat"), true); 
         }
-        else if(sessionFloaterInActive)
+        //conversation floater is open but a different conversation is focused
+        else if(sessionFloaterNotFocused)
         {
-            im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
+            im_box->flashConversationItemWidget(session_id, true);
         }
     }
     else if("openconversations" == action)
     {
-        //Don't flash and show conversation floater when conversation already active (has focus)
-        if(sessionFloaterInActive)
+        //User is not focused on conversation containing the message
+        if(sessionFloaterNotFocused)
         {
             //Flash line item
-            im_box->flashConversationItemWidget(session_id, true); // flashing of the conversation's item
+            im_box->flashConversationItemWidget(session_id, true);
 
             //Surface conversations floater
             LLFloaterReg::showInstance("im_container");
-- 
cgit v1.2.3


From 2965cdf5dbca4810e216315644f0981417415e9c Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 7 Dec 2012 15:03:12 -0800
Subject: CHUI-579: Found a small bug in my last commit causing nearby chat
 im's to show two toast messages. Now the upper right toast (im toasts) will
 only show when the session id is non NULL (Nearby chat has a session value
 that is NULL).

---
 indra/newview/llimview.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index ab2f275711..278384cd08 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -197,7 +197,10 @@ void on_new_message(const LLSD& msg)
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
 
                 //Show IM toasts (upper right toasts)
-                LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+                if(session_id.notNull())
+                {
+                    LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+                }
             }
         }
     }
-- 
cgit v1.2.3


From b1b4b78d5c97659d82ff67b38db4d4188967efbb Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 7 Dec 2012 17:38:36 -0800
Subject: CHUI-417: Problem: Speaking indicator icons were out of position
 because they were not taking into account the reduced width when a vertical
 scrollbar appeared. Resolution: Now when the ::arrange() function is called,
 this implies that the width of a conversation line item has changed...so
 within this function call updateChildren(). updateChildren() will reposition
 the speaker icon and info button based upon the adjusted width.

---
 indra/newview/llconversationview.cpp | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index b964cee09f..f088a8c084 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -472,6 +472,9 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
                         mAvatarIcon->getRect().mBottom);
     mAvatarIcon->setShape(avatarRect);
 
+    //Since dimensions changed, adjust the children (info button, speaker indicator)
+    updateChildren();
+
     return arranged;
 }
 
-- 
cgit v1.2.3


From a6f1690128b510977cfe86071f80f81967b9d0c7 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 7 Dec 2012 18:58:52 -0800
Subject: CHUI-580, CHUI-406 : Fixed : Finished avatar name caching, also fixed
 the display of (waiting) when names don't come (mostly in legacy mode).

---
 indra/llmessage/llavatarnamecache.cpp | 39 ++++++++++++++++++++++++-----------
 indra/newview/llconversationmodel.cpp |  1 +
 2 files changed, 28 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 15c4f2a207..9d6aa15ed1 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -100,11 +100,14 @@ namespace LLAvatarNameCache
 
 	void requestNamesViaCapability();
 
-	// Legacy name system callback
+	// Legacy name system callbacks
 	void legacyNameCallback(const LLUUID& agent_id,
 							const std::string& full_name,
 							bool is_group);
-
+	void legacyNameFetch(const LLUUID& agent_id,
+						 const std::string& full_name,
+						 bool is_group);
+	
 	void requestNamesViaLegacy();
 
 	// Do a single callback to a given slot
@@ -262,8 +265,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
         LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
 								<< agent_id << LL_ENDL;
         gCacheName->get(agent_id, false,  // legacy compatibility
-                        boost::bind(&LLAvatarNameCache::legacyNameCallback,
-                                    _1, _2, _3));
+                        boost::bind(&LLAvatarNameCache::legacyNameFetch, _1, _2, _3));
     }
 	else
     {
@@ -367,19 +369,32 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
 										   const std::string& full_name,
 										   bool is_group)
 {
-	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback "
-							 << "agent " << agent_id << " "
+	// Put the received data in the cache
+	legacyNameFetch(agent_id, full_name, is_group);
+	
+	// Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy
+	// protocol, we do not get an expiration date for each name and there's no reason to ask the 
+	// data again and again so we set the expiration time to the largest value admissible.
+	std::map<LLUUID,LLAvatarName>::iterator av_record = sCache.find(agent_id);
+	LLAvatarName& av_name = av_record->second;
+	av_name.setExpires(MAX_UNREFRESHED_TIME);
+}
+
+void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id,
+										const std::string& full_name,
+										bool is_group)
+{
+	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameFetch "
+	                         << "agent " << agent_id << " "
 							 << "full name '" << full_name << "'"
-							 << ( is_group ? " [group]" : "" )
-							 << LL_ENDL;
+	                         << ( is_group ? " [group]" : "" )
+	                         << LL_ENDL;
 	
 	// Construct an av_name record from this name.
 	LLAvatarName av_name;
 	av_name.fromString(full_name);
-	av_name.dump();
-
-	// Add to cache, because if we don't we'll keep rerequesting the
-	// same record forever.
+	
+	// Add to cache: we're still using the new cache even if we're using the old (legacy) protocol.
 	processName(agent_id, av_name);
 }
 
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 1f6022decb..99dd35a9e8 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -393,6 +393,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 	mDistToAgent(-1.0),
 	mAvatarNameCacheConnection()
 {
+	mDisplayName = display_name;
 	mConvType = CONV_PARTICIPANT;
 }
 
-- 
cgit v1.2.3


From 53471178fed23f32fbb967b6d001c58d8612e450 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 7 Dec 2012 20:06:30 -0800
Subject: CHUI-509, CHUI-585 : Fixed : Add font color parameters to received
 items and other inventory elements created

---
 indra/newview/llpanelmarketplaceinboxinventory.cpp | 10 ++++++++++
 indra/newview/llpanelobjectinventory.cpp           | 11 +++++++++++
 2 files changed, 21 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 68aefa7fb7..adfb2dee86 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -40,6 +40,8 @@
 
 #define DEBUGGING_FRESHNESS	0
 
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
 //
 // statics
 //
@@ -62,18 +64,24 @@ LLInboxInventoryPanel::~LLInboxInventoryPanel()
 
 LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
 {
+	LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
 	LLInboxFolderViewFolder::Params params;
 	
 	params.name = bridge->getDisplayName();
 	params.root = mFolderRoot;
 	params.listener = bridge;
 	params.tool_tip = params.name;
+	params.font_color = item_color;
+	params.font_highlight_color = item_color;
 	
 	return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params);
 }
 
 LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
 {
+	LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
 	LLInboxFolderViewItem::Params params;
 
 	params.name = bridge->getDisplayName();
@@ -82,6 +90,8 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
 	params.listener = bridge;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
+	params.font_color = item_color;
+	params.font_highlight_color = item_color;
 
 	return LLUICtrlFactory::create<LLInboxFolderViewItem>(params);
 }
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index de12826452..a2aabb50b5 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -66,6 +66,7 @@
 #include "llviewerobjectlist.h"
 #include "llviewermessage.h"
 
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
 
 ///----------------------------------------------------------------------------
 /// Class LLTaskInvFVBridge
@@ -1719,11 +1720,15 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
 	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
 	if(bridge)
 	{
+		LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
 		LLFolderViewFolder::Params p;
 		p.name = inventory_root->getName();
 		p.tool_tip = p.name;
 		p.root = mFolders;
 		p.listener = bridge;
+		p.font_color = item_color;
+		p.font_highlight_color = item_color;
 
 		LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
 		new_folder->addToFolder(mFolders);
@@ -1742,6 +1747,8 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 											  LLInventoryObject* parent,
 											  LLFolderViewFolder* folder)
 {
+	LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
 	// Find all in the first pass
 	LLDynamicArray<obj_folder_pair*> child_categories;
 	LLTaskInvFVBridge* bridge;
@@ -1767,6 +1774,8 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 				p.root = mFolders;
 				p.listener = bridge;
 				p.tool_tip = p.name;
+				p.font_color = item_color;
+				p.font_highlight_color = item_color;
 				view = LLUICtrlFactory::create<LLFolderViewFolder>(p);
 				child_categories.put(new obj_folder_pair(obj,
 														 (LLFolderViewFolder*)view));
@@ -1780,6 +1789,8 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 				params.listener(bridge);
 				params.rect(LLRect());
 				params.tool_tip = params.name;
+				params.font_color = item_color;
+				params.font_highlight_color = item_color;
 				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 			}
 			view->addToFolder(folder);
-- 
cgit v1.2.3


From 08a7f4193b18ca5c0bbaf144232eeb2678205eae Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Mon, 10 Dec 2012 15:30:46 +0200
Subject: CHUI-457 FIXED Brought back the checking

---
 indra/newview/llfloaterimcontainer.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c36128b0bd..9e13875d20 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -919,7 +919,10 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
 		}
 		else if ("im" == command)
 		{
-			LLAvatarActions::startIM(userID);
+			if (gAgent.getID() != userID)
+			{
+				LLAvatarActions::startIM(userID);
+			}
 		}
 		else if ("offer_teleport" == command)
 		{
-- 
cgit v1.2.3


From f49d47b3041c6b36b36a23b67eec609e95494acc Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Mon, 10 Dec 2012 17:22:56 +0200
Subject: CHUI-394 (Group moderation tools missing in right click menus)

---
 indra/newview/llconversationmodel.cpp              | 14 ++++----
 indra/newview/llconversationmodel.h                |  2 ++
 indra/newview/llfloaterimcontainer.cpp             | 38 +++++++++++++---------
 .../skins/default/xui/en/menu_conversation.xml     | 13 ++------
 4 files changed, 36 insertions(+), 31 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 99dd35a9e8..d03ad92fbc 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -46,7 +46,8 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u
 	mUUID(uuid),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
-	mLastActiveTime(0.0)
+	mLastActiveTime(0.0),
+	mDisplayModeratorOptions(false)
 {
 }
 
@@ -56,7 +57,8 @@ LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInte
 	mUUID(uuid),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
-	mLastActiveTime(0.0)
+	mLastActiveTime(0.0),
+	mDisplayModeratorOptions(false)
 {
 }
 
@@ -66,7 +68,8 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 	mUUID(),
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
-	mLastActiveTime(0.0)
+	mLastActiveTime(0.0),
+	mDisplayModeratorOptions(false)
 {
 }
 
@@ -117,14 +120,13 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t&   items)
     items.push_back(std::string("block_unblock"));
     items.push_back(std::string("MuteText"));
 
-	if(this->getType() != CONV_SESSION_1_ON_1)
+	if(this->getType() != CONV_SESSION_1_ON_1 && mDisplayModeratorOptions)
 	{
 		items.push_back(std::string("Moderator Options Separator"));
 		items.push_back(std::string("Moderator Options"));
 		items.push_back(std::string("AllowTextChat"));
 		items.push_back(std::string("moderate_voice_separator"));
-		items.push_back(std::string("ModerateVoiceMuteSelected"));
-		items.push_back(std::string("ModerateVoiceUnMuteSelected"));
+		items.push_back(std::string("ModerateVoiceToggleMuteSelected"));
 		items.push_back(std::string("ModerateVoiceMute"));
 		items.push_back(std::string("ModerateVoiceUnmute"));
 	}
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index dd849210a8..7177d3a414 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -138,6 +138,7 @@ protected:
 	EConversationType mConvType;	// Type of conversation item
 	bool mNeedsRefresh;	// Flag signaling to the view that something changed for this item
 	F64  mLastActiveTime;
+	bool mDisplayModeratorOptions;
 };
 
 class LLConversationItemSession : public LLConversationItem
@@ -198,6 +199,7 @@ public:
 	LLConversationItemSession* getParentSession();
 
 	void dumpDebugData();
+	void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; }
 
 private:
 	void onAvatarNameCache(const LLAvatarName& av_name);
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c36128b0bd..e900f583b3 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -509,6 +509,22 @@ void LLFloaterIMContainer::draw()
 		// still needs the conversation list. Simply collapse the message pane in that case.
 		collapseMessagesPane(true);
 	}
+	
+	//Update moderator options visibility
+	const LLConversationItem *current_session = getCurSelectedViewModelItem();
+	if (current_session)
+	{
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+			participant_model->setModeratorOptionsVisible(isGroupModerator() && participant_model->getUUID() != gAgentID);
+
+			current_participant_model++;
+		}
+	}
+
 	LLFloater::draw();
 }
 
@@ -1156,7 +1172,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
     {
 		return LLAvatarActions::canOfferTeleport(uuids);
     }
-	else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item))
+	else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute_unmute" == item))
 	{
 		// *TODO : get that out of here...
 		return enableModerateContextMenuItem(item);
@@ -1246,11 +1262,11 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 		}
     }
 
-		// Set the focus on the selected floater
-		if (!session_floater->hasFocus())
-		{
-			session_floater->setFocus(TRUE);
-		}
+	// Set the focus on the selected floater
+	if (!session_floater->hasFocus())
+	{
+		session_floater->setFocus(TRUE);
+	}
 
     return handled;
 }
@@ -1463,18 +1479,10 @@ bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& user
 
 	bool voice_channel = speakerp->isInVoiceChannel();
 
-	if ("can_moderate_voice" == userdata)
+	if ("can_moderate_voice" == userdata || "can_mute_unmute" == userdata)
 	{
 		return voice_channel;
 	}
-	else if ("can_mute" == userdata)
-	{
-		return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
-	}
-	else if ("can_unmute" == userdata)
-	{
-		return voice_channel && isMuted(getCurSelectedViewModelItem()->getUUID());
-	}
 
 	// The last invoke is used to check whether the "can_allow_text_chat" will enabled
 	return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 01ef8ebdb5..e0edf384d6 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -156,18 +156,11 @@
 		</menu_item_check>
 		<menu_item_separator layout="topleft" name="moderate_voice_separator" />
 		<menu_item_call
-		 label="Mute this participant"
+		 label="Toggle mute this participant"
 		 layout="topleft"
-		 name="ModerateVoiceMuteSelected">
+		 name="ModerateVoiceToggleMuteSelected">
 			<on_click function="Avatar.DoToSelected" parameter="selected" />
-			<on_enable function="Avatar.EnableItem" parameter="can_mute" />
-		</menu_item_call>
-		<menu_item_call
-		 label="Unmute this participant"
-		 layout="topleft"
-		 name="ModerateVoiceUnMuteSelected">
-			<on_click function="Avatar.DoToSelected" parameter="selected" />
-			<on_enable function="Avatar.EnableItem" parameter="can_unmute" />
+			<on_enable function="Avatar.EnableItem" parameter="can_mute_unmute" />
 		</menu_item_call>
 		<menu_item_call
 		 label="Mute everyone"
-- 
cgit v1.2.3


From 4d3590ae9c0040d010badc026b755634e7b3ac77 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Mon, 10 Dec 2012 19:14:37 -0800
Subject: Correcting a mac build error.

---
 indra/newview/llnotificationhandler.h | 2 --
 indra/newview/llviewerwindow.cpp      | 2 --
 indra/newview/llviewerwindow.h        | 9 ++++-----
 3 files changed, 4 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 98b0eecd0d..a78f0c067b 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -225,8 +225,6 @@ protected:
 	virtual void initChannel() {};
 };
 
-typedef boost::intrusive_ptr<LLViewerAlertHandler> LLViewerAlertHandlerPtr;
-
 /**
  * Handler for offers notices.
  * It manages life time of offer notices.
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 7b1cf6e180..eae5112b03 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1561,8 +1561,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
 	mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
 
-	//mAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
-	//mModalAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
 	bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications");
 	LLNotifications::instance().setIgnoreAllNotifications(ignore);
 	if (ignore)
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index b828a05384..5a0d9652b8 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -44,7 +44,6 @@
 #include "llstat.h"
 #include "llmousehandler.h"
 #include "llnotifications.h"
-#include "llnotificationhandler.h"
 #include "llhandle.h"
 #include "llinitparam.h"
 
@@ -419,10 +418,10 @@ private:
 	bool			mActive;
 	bool			mUIVisible;
 
-	LLNotificationChannelPtr                    mSystemChannel;
-	LLNotificationChannelPtr                    mCommunicationChannel;
-	LLNotificationsUI::LLViewerAlertHandlerPtr  mAlertsChannel;
-	LLNotificationsUI::LLViewerAlertHandlerPtr  mModalAlertsChannel;
+	LLNotificationChannelPtr mSystemChannel;
+	LLNotificationChannelPtr mCommunicationChannel;
+	LLNotificationChannelPtr mAlertsChannel;
+	LLNotificationChannelPtr mModalAlertsChannel;
 
 	LLRect			mWindowRectRaw;				// whole window, including UI
 	LLRect			mWindowRectScaled;			// whole window, scaled by UI size
-- 
cgit v1.2.3


From 6b1ab1b81c6b23a1947d0038686e294b6344eddb Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 11 Dec 2012 15:20:46 +0200
Subject: CHUI-587 FIXED Disable menu item if "KeepConversationLogTranscripts"
 is false.

---
 indra/newview/llfloaterimcontainer.cpp             | 5 +++++
 indra/newview/llfloaterimcontainer.h               | 1 +
 indra/newview/llviewermenu.cpp                     | 2 ++
 indra/newview/skins/default/xui/en/menu_viewer.xml | 2 ++
 4 files changed, 10 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index a76714950d..cc053ca658 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1696,6 +1696,11 @@ void LLFloaterIMContainer::updateSpeakBtnState()
 	mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak"));
 }
 
+bool LLFloaterIMContainer::isConversationLoggingAllowed()
+{
+	return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+}
+
 void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
 {
     //Finds the conversation line item to flash using the session_id
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 92985c036a..3818645037 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -174,6 +174,7 @@ public:
 	void setNearbyDistances();
 	void reSelectConversation();
 	void updateSpeakBtnState();
+	static bool isConversationLoggingAllowed();
 	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
 
 private:
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 7ae717cb42..fe9c00cc27 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -59,6 +59,7 @@
 #include "llbuycurrencyhtml.h"
 #include "llfloatergodtools.h"
 #include "llfloaterinventory.h"
+#include "llfloaterimcontainer.h"
 #include "llfloaterland.h"
 #include "llfloaterpathfindingcharacters.h"
 #include "llfloaterpathfindinglinksets.h"
@@ -8238,6 +8239,7 @@ void initialize_menus()
 
 
 	commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory));
+	enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
 
 	// Agent
 	commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b1e3a2d41f..3e7329c0b5 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -261,6 +261,8 @@
             <menu_item_check.on_check
              function="Floater.Visible"
              parameter="conversation" />
+            <menu_item_check.on_enable
+             function="Conversation.IsConversationLoggingAllowed" />
             <menu_item_check.on_click
              function="Floater.Toggle"
              parameter="conversation" />
-- 
cgit v1.2.3


From 13956ab25d76ef3373d2a06795b92b24364f63cf Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 11 Dec 2012 17:16:32 +0200
Subject: CHUI-572 FIXED Changed initial position for floaters according to
 screenshot.

---
 indra/newview/skins/default/xui/en/floater_camera.xml       | 4 ++--
 indra/newview/skins/default/xui/en/floater_destinations.xml | 3 +--
 indra/newview/skins/default/xui/en/floater_im_container.xml | 3 ++-
 indra/newview/skins/default/xui/en/floater_moveview.xml     | 4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index 4b4821a383..521389d7b3 100644
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
  positioning="specified"
- left="643"
- bottom="-80"
+ right="-460"
+ bottom="-50"
  follows="left|bottom"
  legacy_header_height="18"
  can_minimize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_destinations.xml b/indra/newview/skins/default/xui/en/floater_destinations.xml
index 41b57530fc..94ebaa9cb2 100644
--- a/indra/newview/skins/default/xui/en/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/en/floater_destinations.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
+ positioning="cascading"	
  ignore_ui_scale="false"
  legacy_header_height="225"
  can_minimize="true"
@@ -11,8 +12,6 @@
  height="230"
  layout="topleft"
  name="Destinations"
- right="-10"
- bottom="-80"
  single_instance="true"
  help_topic="destinations"
  save_rect="true"
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 9f6503d799..1128b8fef6 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -13,7 +13,8 @@
  single_instance="true"
  reuse_instance="true"
  title="CONVERSATIONS"
- bottom="-80"
+ bottom="-50"
+ right="-5"
  width="450">
     <string
      name="collapse_icon"
diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml
index 02d9805ddf..5e84283ab0 100644
--- a/indra/newview/skins/default/xui/en/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/en/floater_moveview.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
  positioning="specified"
- left="505"
- bottom="-80"
+ right="-693"
+ bottom="-50"
  legacy_header_height="18"
  can_dock="false"
  can_minimize="true"
-- 
cgit v1.2.3


From 80bc7e13e128c4b94028fe74755a5999f08e24ce Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Wed, 12 Dec 2012 03:05:32 +0200
Subject: CHUI-557 (Cannot expand conversation from minimized state by clicking
 on selected conversation)

---
 indra/newview/llconversationview.cpp | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index f088a8c084..527c0ad233 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -223,10 +223,11 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
 
     //This node (conversation) was selected and a child (participant) was not
     if(result && getRoot()->getCurSelectedItem() == this)
-    {
-        (LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
-            selectConversationPair(session_id, false);
-    }
+	{
+		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+		im_container->selectConversationPair(session_id, false);
+		im_container->collapseMessagesPane(false);
+	}
 
 	return result;
 }
-- 
cgit v1.2.3


From 34558181c7fad95c235bca1e29c282ca09d136ba Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 11 Dec 2012 17:49:43 -0800
Subject: CHUI-545: Problem: Sometimes the speaker indicator icons were not
 visible in the conversations panel. Resolution: The problem was that the
 visibility was set incorrectly. When the speaking indicator was not in the
 visible chain the state of the visiblity would be stored in a pending
 variable. If the visiblity changed before the pending variable was used, then
 this meant the pending variable overrode the most recent visibiltiy changes.
 So as a solution, if the visiblity changes then prevent the pending visiblity
 from being used.

---
 indra/newview/lloutputmonitorctrl.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index e4621a7fc3..27c552b626 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -333,7 +333,9 @@ void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
 		LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL;
 		setVisible((BOOL)switch_on);
 		notifyParentVisibilityChanged();
-	}
+	    //Visibility has just been updated so make sure not to use the pending visibility when ::draw executes (if one is pending)
+        mIsSwitchDirty = false;
+    }
 
 	// otherwise remember necessary state and mark itself as dirty.
 	// State will be applied in next draw when parents chain becomes visible.
-- 
cgit v1.2.3


From b5db4952590321acef60a4ff8726eb4162305c9f Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 11 Dec 2012 18:48:29 -0800
Subject: CHUI-494: Toggling the behavior of the communication notification
 channel filter as it should be true when not in DND mode and false when in
 DND mode.

---
 indra/newview/llviewerwindow.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index eae5112b03..fcd65f7df2 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1557,7 +1557,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mViewerWindowListener.reset(new LLViewerWindowListener(this));
 
 	mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
-	mCommunicationChannel.reset(new LLNotificationChannel("Communication", "Visible", boost::bind(&LLAgent::isDoNotDisturb, &gAgent)));
+	mCommunicationChannel.reset(new LLNotificationChannel("Communication", "Visible", !boost::bind(&LLAgent::isDoNotDisturb, &gAgent)));
 	mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
 	mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
 
-- 
cgit v1.2.3


From 9c145d88a667c20a550884d75b6616b11ebc8104 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Wed, 12 Dec 2012 05:46:56 +0200
Subject: CHUI-589 (Conversation floater displays wrong IM floater when
 receiving a new message)

---
 indra/newview/llfloaterimcontainer.cpp | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index cc053ca658..054379c064 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -101,6 +101,16 @@ void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::str
 {
 	addConversationListItem(session_id);
 	LLFloaterIMSessionTab::addToHost(session_id);
+
+	// If session was added while floater is not visible, conversation should not change
+	if (!isVisible(this))
+	{
+		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+		if (session_floater->getHost())
+		{
+			selectFloater(session_floater);
+		}
+	}
 }
 
 void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
@@ -1229,7 +1239,7 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
 void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
 {
     selectConversationPair(session_id, true);
-	}
+}
 
 // Synchronous select the conversation item and the conversation floater
 BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
-- 
cgit v1.2.3


From 79cb158e118d14bfaf7050f79e5ece1fa2052471 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 11 Dec 2012 20:03:05 -0800
Subject: Removing cruft code.

---
 indra/newview/llchatbar.cpp | 44 --------------------------------------------
 1 file changed, 44 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 27138e6c06..7d0331757b 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -669,47 +669,3 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
 		mGestureCombo->setFocus(FALSE);
 	}
 }
-
-
-/* Cruft - global gChatHandler declared below has been commented out,
-   so this class is never used.  See similar code in llfloaterimnearbychatbar.cpp
-class LLChatHandler : public LLCommandHandler
-{
-public:
-	// not allowed from outside the app
-	LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
-    // Your code here
-	bool handle(const LLSD& tokens, const LLSD& query_map,
-				LLMediaCtrl* web)
-	{
-		bool retval = false;
-		// Need at least 2 tokens to have a valid message.
-		if (tokens.size() < 2) 
-		{
-			retval = false;
-		}
-		else
-		{
-		S32 channel = tokens[0].asInteger();
-			// VWR-19499 Restrict function to chat channels greater than 0.
-			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
-			{
-				retval = true;
-				// Say mesg on channel
-		std::string mesg = tokens[1].asString();
-		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
-			}
-			else
-			{
-				retval = false;
-				// Tell us this is an unsupported SLurl.
-			}
-		}
-		return retval;
-	}
-};
-
-// Creating the object registers with the dispatcher.
-//LLChatHandler gChatHandler;
-cruft */
-- 
cgit v1.2.3


From 3636b10d479043c6e7386bc60af3228bd856f737 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 11 Dec 2012 20:46:10 -0800
Subject: CHUI-494: Removing the creation of a new session while receiving an
 IM in DND mode.

---
 indra/newview/llimview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 4e2ac09dd8..5bbe14a8b9 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2499,7 +2499,7 @@ void LLIMMgr::addMessage(
 	}
 
 	bool new_session = !hasSession(new_session_id);
-	if (new_session)
+	if (new_session && !gAgent.isDoNotDisturb())
 	{
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
-- 
cgit v1.2.3


From 3d7aaaada853d950888a2fd0fe3e2f375bd5bbb0 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 12 Dec 2012 13:14:52 +0200
Subject: CHUI-427 FIXED Added callback to track changing in mUserPTTState.
 It's needed to synchronize both buttons

---
 indra/newview/llfloaterimcontainer.cpp  | 7 ++++++-
 indra/newview/llfloaterimcontainer.h    | 1 +
 indra/newview/llfloaterimsessiontab.cpp | 1 -
 indra/newview/llvoiceclient.cpp         | 1 +
 indra/newview/llvoiceclient.h           | 6 ++++++
 5 files changed, 14 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index cc053ca658..75b311eecf 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -88,6 +88,11 @@ LLFloaterIMContainer::~LLFloaterIMContainer()
 	mNewMessageConnection.disconnect();
 	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
 
+	if (mMicroChangedSignal.connected())
+	{
+		mMicroChangedSignal.disconnect();
+	}
+
 	gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed());
 	gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
 
@@ -213,7 +218,7 @@ BOOL LLFloaterIMContainer::postBuild()
 	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
 	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
 	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
-
+	mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
 	if (! mMessagesPane->isCollapsed())
 	{
 		S32 list_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 3818645037..4f1bb96d9b 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -176,6 +176,7 @@ public:
 	void updateSpeakBtnState();
 	static bool isConversationLoggingAllowed();
 	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
+	boost::signals2::connection mMicroChangedSignal;
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 4c6d8fa5a0..0eb0289f49 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -693,7 +693,6 @@ void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)
 	voiceButton->setToolTip(
 			callIsActive? getString("end_call_button_tooltip") : getString("start_call_button_tooltip"));
 
-	LLFloaterIMContainer::getInstance()->updateSpeakBtnState();
 	enableDisableCallBtn();
 
 }
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 730f022c50..dd529d74e9 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -551,6 +551,7 @@ void LLVoiceClient::setUserPTTState(bool ptt)
 {
 	mUserPTTState = ptt;
 	updateMicMuteLogic();
+	mMicroChangedSignal();
 }
 
 bool LLVoiceClient::getUserPTTState()
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index c9aeea35a9..714dd6a9f2 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -303,6 +303,9 @@ public:
 	LLVoiceClient();	
 	~LLVoiceClient();
 
+	typedef boost::signals2::signal<void(void)> micro_changed_signal_t;
+	micro_changed_signal_t mMicroChangedSignal;
+
 	void init(LLPumpIO *pump);	// Call this once at application startup (creates connector)
 	void terminate();	// Call this to clean up during shutdown
 	
@@ -401,6 +404,8 @@ public:
 	void keyUp(KEY key, MASK mask);
 	void middleMouseState(bool down);
 	
+	boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); }
+
 	
 	/////////////////////////////
 	// Accessors for data related to nearby speakers
@@ -456,6 +461,7 @@ protected:
 	LLVoiceModuleInterface* mVoiceModule;
 	LLPumpIO *m_servicePump;
 
+
 	LLCachedControl<bool> mVoiceEffectEnabled;
 	LLCachedControl<std::string> mVoiceEffectDefault;
 
-- 
cgit v1.2.3


From 9275379e3ce20f6a27341e595481ce57c3a6b954 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 12 Dec 2012 18:59:24 +0200
Subject: CHUI-584 : WIP : Viewer crash when clicking on view/sort options drop
 down in conversation floater: Renaming of local vfriables in accordance with
 the code convention

---
 indra/newview/llfloaterimcontainer.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 75b311eecf..5d41f46b3f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -891,37 +891,37 @@ void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
 
 const LLConversationItem * LLFloaterIMContainer::getCurSelectedViewModelItem()
 {
-    LLConversationItem * conversationItem = NULL;
+    LLConversationItem * conversation_item = NULL;
 
     if(mConversationsRoot && 
         mConversationsRoot->getCurSelectedItem() && 
         mConversationsRoot->getCurSelectedItem()->getViewModelItem())
     {
-		LLFloaterIMSessionTab *selectedSession = LLFloaterIMSessionTab::getConversation(mSelectedSession);
-		if (selectedSession && selectedSession->isTornOff())
+		LLFloaterIMSessionTab *selected_session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+		if (selected_session_floater && !selected_session_floater->getHost())
 		{
-			conversationItem = selectedSession->getCurSelectedViewModelItem();
+			conversation_item = selected_session_floater->getCurSelectedViewModelItem();
 		}
 		else
 		{
-			conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
+			conversation_item = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
 		}
 	}
 
-    return conversationItem;
+    return conversation_item;
 }
 
 void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
 {
     //Find the conversation floater associated with the selected id
-    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+    const LLConversationItem * conversation_item = getCurSelectedViewModelItem();
 
     if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
     {
         getSelectedUUIDs(selected_uuids);
     }
     //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
-    else if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+    else if(conversation_item->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
     {
         LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(conversationItem->getUUID());
         LLUUID participantID = conversationFloater->getOtherParticipantUUID();
-- 
cgit v1.2.3


From 322fb006306524481ee09e88a079457b86fcd95a Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 12 Dec 2012 19:05:40 +0200
Subject: CHUI-584 : Fixed : Viewer crash when clicking on view/sort options
 drop down in conversation floater: Protection from a lack of the current
 selection. It need for the newly created floater, which still is not finished
 adding the first conversation item.

---
 indra/newview/llfloaterimcontainer.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 5d41f46b3f..82bcd8efa4 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -916,7 +916,12 @@ void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
     //Find the conversation floater associated with the selected id
     const LLConversationItem * conversation_item = getCurSelectedViewModelItem();
 
-    if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
+	if (NULL == conversation_item)
+	{
+		return;
+	}
+
+    if (conversation_item->getType() == LLConversationItem::CONV_PARTICIPANT)
     {
         getSelectedUUIDs(selected_uuids);
     }
-- 
cgit v1.2.3


From 4c20cc3e46d0392c63ecec304858493c8f59059b Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 12 Dec 2012 18:53:06 +0200
Subject: CHUI-584 : Addit. fix : Viewer crash when clicking on view/sort
 options drop down in conversation floater: Cancelled unconditional receiving
 a instance of the floater (LLFloaterReg::getInstance()) from
 LLFloaterIMContainer::selectConversationPair(), because in some situations
 this method is called from LLFloaterIMNearbyChat::postBuild() - In other
 words, while the unfinished process of creation of this floater

---
 indra/newview/llfloaterimcontainer.cpp | 57 ++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 82bcd8efa4..3a5f2ae854 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -928,9 +928,9 @@ void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
     //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
     else if(conversation_item->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
     {
-        LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(conversationItem->getUUID());
-        LLUUID participantID = conversationFloater->getOtherParticipantUUID();
-        selected_uuids.push_back(participantID);
+        LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(conversation_item->getUUID());
+        LLUUID participant_id = conversation_floaterp->getOtherParticipantUUID();
+        selected_uuids.push_back(participant_id);
     }    
 }
 
@@ -1239,13 +1239,13 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
 void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
 {
     selectConversationPair(session_id, true);
-	}
+}
 
 // Synchronous select the conversation item and the conversation floater
 BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
 {
     BOOL handled = TRUE;
-    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
 
     /* widget processing */
     if (select_widget)
@@ -1259,26 +1259,29 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 
     /* floater processing */
 
-    if (session_id != getSelectedSession())
-    {
-        // Store the active session
-        setSelectedSession(session_id);
+	if (NULL != session_floater)
+	{
+		if (session_id != getSelectedSession())
+		{
+			// Store the active session
+			setSelectedSession(session_id);
 
 		
 
-		if (session_floater->getHost())
-		{
-			// Always expand the message pane if the panel is hosted by the container
-			collapseMessagesPane(false);
-			// Switch to the conversation floater that is being selected
-			selectFloater(session_floater);
+			if (session_floater->getHost())
+			{
+				// Always expand the message pane if the panel is hosted by the container
+				collapseMessagesPane(false);
+				// Switch to the conversation floater that is being selected
+				selectFloater(session_floater);
+			}
 		}
-    }
 
-	// Set the focus on the selected floater
-	if (!session_floater->hasFocus())
-	{
-		session_floater->setFocus(TRUE);
+		// Set the focus on the selected floater
+		if (!session_floater->hasFocus())
+		{
+			session_floater->setFocus(TRUE);
+		}
 	}
 
     return handled;
@@ -1388,12 +1391,14 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 	// set the widget to minimized mode if conversations pane is collapsed
 	widget->toggleCollapsedMode(mConversationsPane->isCollapsed());
 
-    if (isWidgetSelected)
-    {
-        selectConversation(uuid);
-        // scroll to newly added item
-        mConversationsRoot->scrollToShowSelection();
-    }
+	if (isWidgetSelected || 0 == mConversationsRoot->getSelectedCount())
+	{
+		selectConversationPair(uuid, true);
+		widget->requestArrange();
+
+		// scroll to newly added item
+		mConversationsRoot->scrollToShowSelection();
+	}
 
 	return item;
 }
-- 
cgit v1.2.3


From e90bd165c8f41ac4a670d6c52a7ee2d7b3728991 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Wed, 12 Dec 2012 23:35:52 +0200
Subject: CHUI-589 (Conversation floater displays wrong IM floater when
 receiving a new message) additional fix

---
 indra/newview/llfloaterimcontainer.cpp  | 10 ----------
 indra/newview/llfloaterimsessiontab.cpp |  2 +-
 2 files changed, 1 insertion(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 054379c064..3b98c6d98c 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -101,16 +101,6 @@ void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::str
 {
 	addConversationListItem(session_id);
 	LLFloaterIMSessionTab::addToHost(session_id);
-
-	// If session was added while floater is not visible, conversation should not change
-	if (!isVisible(this))
-	{
-		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
-		if (session_floater->getHost())
-		{
-			selectFloater(session_floater);
-		}
-	}
 }
 
 void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 4c6d8fa5a0..4d923913fb 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -167,7 +167,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 			if (!conversp->isNearbyChat()
 					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
-				floater_container->addFloater(conversp, !floater_container->getVisible(), LLTabContainer::RIGHT_OF_CURRENT);
+				floater_container->addFloater(conversp, false, LLTabContainer::RIGHT_OF_CURRENT);
 			}
 			else
 			{
-- 
cgit v1.2.3


From 89671fa1ad4ef13acb264d0e047fb24b9ee5d8a4 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 12 Dec 2012 16:59:57 -0800
Subject: CHUI-545: Adjusted fix because the old implementation of
 ::switchIndicator was not very clean and relied on the visiblity of the
 OutputMonitorCtrl to have a visibility of true even when it wasn't. The fix
 implemented makes it so that the visibility of OutputMonitorCtrl is always
 correct and the parent of this ctrl can use this information to adjust
 children adjacent to OutputMonitorCtrl.

---
 indra/newview/llavatarlistitem.cpp    | 11 +++++++
 indra/newview/llavatarlistitem.h      |  1 +
 indra/newview/lloutputmonitorctrl.cpp | 61 +++++++++++------------------------
 indra/newview/lloutputmonitorctrl.h   |  6 ++--
 4 files changed, 34 insertions(+), 45 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 84e177d4a4..e52677925e 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -141,6 +141,17 @@ BOOL  LLAvatarListItem::postBuild()
 	return TRUE;
 }
 
+void LLAvatarListItem::handleVisibilityChange ( BOOL new_visibility )
+{
+    //Adjust positions of icons (info button etc) when 
+    //speaking indicator visibility was changed/toggled while panel was closed (not visible)
+    if(new_visibility && mSpeakingIndicator->getIndicatorToggled())
+    {
+        updateChildren();
+        mSpeakingIndicator->setIndicatorToggled(false);
+    }
+}
+
 void LLAvatarListItem::fetchAvatarName()
 {
 	if (mAvatarNameCacheConnection.connected())
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 41853b6b51..96aed20016 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -84,6 +84,7 @@ public:
 	/**
 	 * Processes notification from speaker indicator to update children when indicator's visibility is changed.
 	 */
+    virtual void handleVisibilityChange ( BOOL new_visibility );
 	virtual S32	notifyParent(const LLSD& info);
 	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
 	virtual void onMouseEnter(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 27c552b626..88a52caf27 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -73,8 +73,7 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
 	mAutoUpdate(p.auto_update),
 	mSpeakerId(p.speaker_id),
 	mIsAgentControl(false),
-	mIsSwitchDirty(false),
-	mShouldSwitchOn(false),
+	mIndicatorToggled(false),
 	mShowParticipantsSpeaking(false)
 {
 	//static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
@@ -116,26 +115,6 @@ void LLOutputMonitorCtrl::setPower(F32 val)
 
 void LLOutputMonitorCtrl::draw()
 {
-	// see also switchIndicator()
-	if (mIsSwitchDirty)
-	{
-		mIsSwitchDirty = false;
-		if (mShouldSwitchOn)
-		{
-			// just notify parent visibility may have changed
-			notifyParentVisibilityChanged();
-		}
-		else
-		{
-			// make itself invisible and notify parent about this
-			setVisible(FALSE);
-			notifyParentVisibilityChanged();
-
-			// no needs to render for invisible element
-			return;
-		}
-	}
-
 	// Copied from llmediaremotectrl.cpp
 	// *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then
 	// call directly into LLVoiceClient::getInstance() to ask if that agent-id is muted, is
@@ -323,28 +302,26 @@ void LLOutputMonitorCtrl::onChange()
 // virtual
 void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
 {
-	// ensure indicator is visible in case it is not in visible chain
-	// to be called when parent became visible next time to notify parent that visibility is changed.
-	setVisible(TRUE);
 
-	// if parent is in visible chain apply switch_on state and notify it immediately
-	if (getParent() && getParent()->isInVisibleChain())
-	{
-		LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL;
-		setVisible((BOOL)switch_on);
-		notifyParentVisibilityChanged();
-	    //Visibility has just been updated so make sure not to use the pending visibility when ::draw executes (if one is pending)
-        mIsSwitchDirty = false;
-    }
+    if(getVisible() != (BOOL)switch_on)
+    {
+        setVisible(switch_on);
+        
+        //Let parent adjust positioning of icons adjacent to speaker indicator
+        //(when speaker indicator hidden, adjacent icons move to right and when speaker
+        //indicator visible, adjacent icons move to the left) 
+        if (getParent() && getParent()->isInVisibleChain())
+        {
+            notifyParentVisibilityChanged();
+        }
+        else
+        {
+            //Makes sure to only adjust adjacent icons when parent becomes visible
+            //(!mIndicatorToggled ensures that changes of TFT and FTF are discarded, real state changes are TF or FT)
+            mIndicatorToggled = !mIndicatorToggled;
+        }
 
-	// otherwise remember necessary state and mark itself as dirty.
-	// State will be applied in next draw when parents chain becomes visible.
-	else
-	{
-		LL_DEBUGS("SpeakingIndicator") << "Indicator is not in visible chain, parent won't be notified: " << mSpeakerId << LL_ENDL;
-		mIsSwitchDirty = true;
-		mShouldSwitchOn = switch_on;
-	}
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 1fa6ef41f8..7671a736d6 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -108,6 +108,8 @@ public:
 	 * It will be applied in next draw and parent will be notified.
 	 */
 	virtual void	switchIndicator(bool switch_on);
+    bool getIndicatorToggled() { return mIndicatorToggled;}
+    void setIndicatorToggled(bool value) { mIndicatorToggled = value;}
 
 private:
 
@@ -148,9 +150,7 @@ private:
 	/** uuid of a speaker being monitored */
 	LLUUID			mSpeakerId;
 
-	/** indicates if the instance is dirty and should notify parent */
-	bool			mIsSwitchDirty;
-	bool			mShouldSwitchOn;
+    bool mIndicatorToggled;
 };
 
 #endif
-- 
cgit v1.2.3


From 37e95e837968935fba1744ec59b3fdd32b7034bf Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 12 Dec 2012 17:43:15 -0800
Subject: CHUI-545: Minor logic fix, inside ::switchIndicator(), make sure that
 in the case that the parent is visible and the parent makes the visibility
 changes...that mIndicatorToggled becomes false because the parent has already
 made the visiblity changes.

---
 indra/newview/lloutputmonitorctrl.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 88a52caf27..02841e9831 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -313,6 +313,8 @@ void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
         if (getParent() && getParent()->isInVisibleChain())
         {
             notifyParentVisibilityChanged();
+            //Ignore toggled state in case it was set when parent visibility was hidden
+            mIndicatorToggled = false;
         }
         else
         {
-- 
cgit v1.2.3


From b6f3c4d07e96f3529f048a93863aa9b0f28cbad4 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 12 Dec 2012 18:02:13 -0800
Subject: CHUI-526: Slight bug fix. Problem was that the 'Teleport Offer' sound
 was turn on by default when the user cleared their settings. Resolution:
 Inside settings.xml changed the PlaySoundTeleportOffer to no longer have an
 intial value of 1 (true). Now it is 0 (false).

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 3e0de834b4..24fa0a0cd4 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6909,7 +6909,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>1</integer>
+      <integer>0</integer>
     </map>
     <key>PluginAttachDebuggerToPlugins</key>
     <map>
-- 
cgit v1.2.3


From 5df9d52d48b56a5d8f36a45ced0393c99473f536 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Wed, 12 Dec 2012 18:49:07 -0800
Subject: CHUI-499: Refactoring the persistent notification storage so that I
 can reuse the functionality for do-not-disturb mode.

---
 indra/llui/llnotifications.h                      |   2 +-
 indra/newview/CMakeLists.txt                      |   2 +
 indra/newview/llchannelmanager.cpp                |   2 +-
 indra/newview/llnotificationstorage.cpp           | 203 ++++-----------------
 indra/newview/llnotificationstorage.h             |  34 ++--
 indra/newview/llpersistentnotificationstorage.cpp | 210 ++++++++++++++++++++++
 indra/newview/llpersistentnotificationstorage.h   |  63 +++++++
 7 files changed, 322 insertions(+), 194 deletions(-)
 create mode 100644 indra/newview/llpersistentnotificationstorage.cpp
 create mode 100644 indra/newview/llpersistentnotificationstorage.h

(limited to 'indra')

diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 056a316d40..8bb79b57e3 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -1026,7 +1026,7 @@ protected:
 
 // Stores only persistent notifications.
 // Class users can use connectChanged() to process persistent notifications
-// (see LLNotificationStorage for example).
+// (see LLPersistentNotificationStorage for example).
 class LLPersistentNotificationChannel : public LLNotificationChannel
 {
 	LOG_CLASS(LLPersistentNotificationChannel);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c9176d71fb..da1d96414b 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -448,6 +448,7 @@ set(viewer_SOURCE_FILES
     llpathfindingobject.cpp
     llpathfindingobjectlist.cpp
     llpathfindingpathtool.cpp
+    llpersistentnotificationstorage.cpp
     llphysicsmotion.cpp
     llphysicsshapebuilderutil.cpp
     llplacesinventorybridge.cpp
@@ -1021,6 +1022,7 @@ set(viewer_HEADER_FILES
     llpathfindingobject.h
     llpathfindingobjectlist.h
     llpathfindingpathtool.h
+    llpersistentnotificationstorage.h
     llphysicsmotion.h
     llphysicsshapebuilderutil.h
     llplacesinventorybridge.h
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 987651fc80..79e2d376ea 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -29,7 +29,7 @@
 #include "llchannelmanager.h"
 
 #include "llappviewer.h"
-#include "llnotificationstorage.h"
+#include "llpersistentnotificationstorage.h"
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
 #include "llrootview.h"
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index a31b95811e..d25a212059 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -25,207 +25,68 @@
 */
 
 #include "llviewerprecompiledheaders.h" // must be first include
+
 #include "llnotificationstorage.h"
 
-#include "llxmlnode.h" // for linux compilers
+#include <string>
 
-#include "llchannelmanager.h"
-#include "llscreenchannel.h"
-#include "llscriptfloater.h"
+#include "llerror.h"
+#include "llfile.h"
+#include "llpointer.h"
+#include "llsd.h"
 #include "llsdserialize.h"
-#include "llviewermessage.h"
-
-//////////////////////////////////////////////////////////////////////////
-
-class LLResponderRegistry
-{
-public:
-
-	static void registerResponders();
-
-	static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
-
-private:
-
-	template<typename RESPONDER_TYPE>
-	static LLNotificationResponderInterface* create(const LLSD& params)
-	{
-		RESPONDER_TYPE* responder = new RESPONDER_TYPE();
-		responder->fromLLSD(params);
-		return responder;
-	}
-
-	typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
-
-	static void add(const std::string& notification_name, const responder_constructor_t& ctr);
-
-private:
-
-	typedef std::map<std::string, responder_constructor_t> build_map_t;
-
-	static build_map_t sBuildMap;
-};
 
-//////////////////////////////////////////////////////////////////////////
 
-LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+LLNotificationStorage::LLNotificationStorage(std::string pFileName)
+	: mFileName(pFileName)
 {
-	mFileName = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
 }
 
-bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+LLNotificationStorage::~LLNotificationStorage()
 {
-	// we ignore "load" messages, but rewrite the persistence file on any other
-	const std::string sigtype = payload["sigtype"].asString();
-	if ("load" != sigtype)
-	{
-		saveNotifications();
-	}
-	return false;
 }
 
-static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
-
-void LLPersistentNotificationStorage::saveNotifications()
+bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) const
 {
-	LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
-
-	llofstream notify_file(mFileName.c_str());
-	if (!notify_file.is_open())
-	{
-		llwarns << "Failed to open " << mFileName << llendl;
-		return;
-	}
 
-	LLSD output;
-	LLSD& data = output["data"];
+	llofstream notifyFile(mFileName.c_str());
+	bool didFileOpen = notifyFile.is_open();
 
-	boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
-	if (!history_channel)
+	if (!didFileOpen)
 	{
-		return;
+		LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
 	}
-
-	for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
-		it != end_it;
-		++it)
+	else
 	{
-		LLNotificationPtr notification = *it;
-
-		// After a notification was placed in Persist channel, it can become
-		// responded, expired or canceled - in this case we are should not save it
-		if(notification->isRespondedTo() || notification->isCancelled()
-			|| notification->isExpired())
-		{
-			continue;
-		}
-
-		data.append(notification->asLLSD());
+		LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+		formatter->format(pNotificationData, notifyFile, LLSDFormatter::OPTIONS_PRETTY);
 	}
 
-	LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
-	formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
+	return didFileOpen;
 }
 
-static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
-
-void LLPersistentNotificationStorage::loadNotifications()
+bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
 {
-	LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
-	LLResponderRegistry::registerResponders();
+	bool didFileRead;
 
-	LLNotifications::instance().getChannel("Persistent")->
-		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+	pNotificationData.clear();
 
-	llifstream notify_file(mFileName.c_str());
-	if (!notify_file.is_open())
+	llifstream notifyFile(mFileName.c_str());
+	didFileRead = notifyFile.is_open();
+	if (!didFileRead)
 	{
-		llwarns << "Failed to open " << mFileName << llendl;
-		return;
+		LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
 	}
-
-	LLSD input;
-	LLPointer<LLSDParser> parser = new LLSDXMLParser();
-	if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
+	else
 	{
-		llwarns << "Failed to parse open notifications" << llendl;
-		return;
-	}
-
-	if (input.isUndefined())
-	{
-		return;
-	}
-
-	LLSD& data = input["data"];
-	if (data.isUndefined())
-	{
-		return;
-	}
-
-	using namespace LLNotificationsUI;
-	LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
-		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-
-	LLNotifications& instance = LLNotifications::instance();
-
-	for (LLSD::array_const_iterator notification_it = data.beginArray();
-		notification_it != data.endArray();
-		++notification_it)
-	{
-		LLSD notification_params = *notification_it;
-		LLNotificationPtr notification(new LLNotification(notification_params));
-
-		LLNotificationResponderPtr responder(LLResponderRegistry::
-			createResponder(notification_params["name"], notification_params["responder"]));
-		notification->setResponseFunctor(responder);
-
-		instance.add(notification);
-
-		// hide script floaters so they don't confuse the user and don't overlap startup toast
-		LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
-
-		if(notification_channel)
+		LLPointer<LLSDParser> parser = new LLSDXMLParser();
+		didFileRead = (parser->parse(notifyFile, pNotificationData, LLSDSerialize::SIZE_UNLIMITED) >= 0);
+		if (!didFileRead)
 		{
-			// hide saved toasts so they don't confuse the user
-			notification_channel->hideToast(notification->getID());
+			LL_WARNS("LLNotificationStorage") << "Failed to parse open notifications from file '" << mFileName 
+				<< "'" << LL_ENDL;
 		}
 	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
 
-LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
-
-void LLResponderRegistry::registerResponders()
-{
-	sBuildMap.clear();
-
-	add("ObjectGiveItem", &create<LLOfferInfo>);
-	add("UserGiveItem", &create<LLOfferInfo>);
-}
-
-LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
-{
-	build_map_t::const_iterator it = sBuildMap.find(notification_name);
-	if(sBuildMap.end() == it)
-	{
-		return NULL;
-	}
-	responder_constructor_t ctr = it->second;
-	return ctr(params);
+	return didFileRead;
 }
-
-void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
-{
-	if(sBuildMap.find(notification_name) != sBuildMap.end())
-	{
-		llwarns << "Responder is already registered : " << notification_name << llendl;
-		llassert(!"Responder already registered");
-	}
-	sBuildMap[notification_name] = ctr;
-}
-
-// EOF
diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h
index 8635c797c0..ab4da4e73f 100644
--- a/indra/newview/llnotificationstorage.h
+++ b/indra/newview/llnotificationstorage.h
@@ -27,32 +27,24 @@
 #ifndef LL_NOTIFICATIONSTORAGE_H
 #define LL_NOTIFICATIONSTORAGE_H
 
-#include "llnotifications.h"
-
-// Class that saves not responded(unread) notifications.
-// Unread notifications are saved in open_notifications.xml in SL account folder
-//
-// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
-// Notifications using functor responders are saved automatically (see llviewermessage.cpp
-// lure_callback_reg for example).
-// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
-// be a) serializable(implement LLNotificationResponderInterface),
-// b) registered with LLResponderRegistry (found in llnotificationstorage.cpp).
-class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>
-{
-	LOG_CLASS(LLPersistentNotificationStorage);
-public:
+#include <string>
 
-	LLPersistentNotificationStorage();
+#include "llerror.h"
 
-	void saveNotifications();
+class LLSD;
 
-	void loadNotifications();
-
-private:
+class LLNotificationStorage
+{
+	LOG_CLASS(LLNotificationStorage);
+public:
+	LLNotificationStorage(std::string pFileName);
+	~LLNotificationStorage();
 
-	bool onPersistentChannelChanged(const LLSD& payload);
+protected:
+	bool writeNotifications(const LLSD& pNotificationData) const;
+	bool readNotifications(LLSD& pNotificationData) const;
 
+private:
 	std::string mFileName;
 };
 
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
new file mode 100644
index 0000000000..7aaad64fd7
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -0,0 +1,210 @@
+/** 
+* @file llpersistentnotificationstorage.cpp
+* @brief Implementation of llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpersistentnotificationstorage.h"
+
+#include "llchannelmanager.h"
+#include "llnotificationstorage.h"
+#include "llscreenchannel.h"
+#include "llscriptfloater.h"
+#include "llviewermessage.h"
+
+class LLResponderRegistry
+{
+public:
+
+	static void registerResponders();
+
+	static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
+
+protected:
+
+private:
+	template<typename RESPONDER_TYPE>
+	static LLNotificationResponderInterface* create(const LLSD& params)
+	{
+		RESPONDER_TYPE* responder = new RESPONDER_TYPE();
+		responder->fromLLSD(params);
+		return responder;
+	}
+
+	typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
+
+	static void add(const std::string& notification_name, const responder_constructor_t& ctr);
+
+	typedef std::map<std::string, responder_constructor_t> build_map_t;
+
+	static build_map_t sBuildMap;
+};
+
+LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+	: LLSingleton<LLPersistentNotificationStorage>()
+	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"))
+{
+}
+
+LLPersistentNotificationStorage::~LLPersistentNotificationStorage()
+{
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
+
+void LLPersistentNotificationStorage::saveNotifications()
+{
+	LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
+
+	boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
+	if (!history_channel)
+	{
+		return;
+	}
+
+	LLSD output = LLSD::emptyMap();
+	LLSD& data = output["data"];
+
+	for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
+		it != end_it;
+		++it)
+	{
+		LLNotificationPtr notification = *it;
+
+		// After a notification was placed in Persist channel, it can become
+		// responded, expired or canceled - in this case we are should not save it
+		if(notification->isRespondedTo() || notification->isCancelled()
+			|| notification->isExpired())
+		{
+			continue;
+		}
+
+		data.append(notification->asLLSD());
+	}
+
+	writeNotifications(output);
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
+
+void LLPersistentNotificationStorage::loadNotifications()
+{
+	LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
+	LLResponderRegistry::registerResponders();
+
+	LLNotifications::instance().getChannel("Persistent")->
+		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+
+	LLSD input;
+	if (!readNotifications(input) ||input.isUndefined())
+	{
+		return;
+	}
+
+	LLSD& data = input["data"];
+	if (data.isUndefined())
+	{
+		return;
+	}
+
+	using namespace LLNotificationsUI;
+	LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
+		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+	LLNotifications& instance = LLNotifications::instance();
+
+	for (LLSD::array_const_iterator notification_it = data.beginArray();
+		notification_it != data.endArray();
+		++notification_it)
+	{
+		LLSD notification_params = *notification_it;
+		LLNotificationPtr notification(new LLNotification(notification_params));
+
+		LLNotificationResponderPtr responder(LLResponderRegistry::
+			createResponder(notification_params["name"], notification_params["responder"]));
+		notification->setResponseFunctor(responder);
+
+		instance.add(notification);
+
+		// hide script floaters so they don't confuse the user and don't overlap startup toast
+		LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
+
+		if(notification_channel)
+		{
+			// hide saved toasts so they don't confuse the user
+			notification_channel->hideToast(notification->getID());
+		}
+	}
+}
+
+bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+{
+	// we ignore "load" messages, but rewrite the persistence file on any other
+	const std::string sigtype = payload["sigtype"].asString();
+	if ("load" != sigtype)
+	{
+		saveNotifications();
+	}
+	return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
+
+void LLResponderRegistry::registerResponders()
+{
+	sBuildMap.clear();
+
+	add("ObjectGiveItem", &create<LLOfferInfo>);
+	add("UserGiveItem", &create<LLOfferInfo>);
+}
+
+LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
+{
+	build_map_t::const_iterator it = sBuildMap.find(notification_name);
+	if(sBuildMap.end() == it)
+	{
+		return NULL;
+	}
+	responder_constructor_t ctr = it->second;
+	return ctr(params);
+}
+
+void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
+{
+	if(sBuildMap.find(notification_name) != sBuildMap.end())
+	{
+		llwarns << "Responder is already registered : " << notification_name << llendl;
+		llassert(!"Responder already registered");
+	}
+	sBuildMap[notification_name] = ctr;
+}
+
+// EOF
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
new file mode 100644
index 0000000000..98a825d2c1
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -0,0 +1,63 @@
+/** 
+* @file   llpersistentnotificationstorage.h
+* @brief  Header file for llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+#define LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+// Class that saves not responded(unread) notifications.
+// Unread notifications are saved in open_notifications.xml in SL account folder
+//
+// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
+// Notifications using functor responders are saved automatically (see llviewermessage.cpp
+// lure_callback_reg for example).
+// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
+// be a) serializable(implement LLNotificationResponderInterface),
+// b) registered with LLResponderRegistry (found in llpersistentnotificationstorage.cpp).
+
+class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>, public LLNotificationStorage
+{
+	LOG_CLASS(LLPersistentNotificationStorage);
+public:
+	LLPersistentNotificationStorage();
+	~LLPersistentNotificationStorage();
+
+	void saveNotifications();
+	void loadNotifications();
+
+protected:
+
+private:
+	bool onPersistentChannelChanged(const LLSD& payload);
+};
+
+#endif // LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
-- 
cgit v1.2.3


From be6f3286f4a969a4de73d8f3af7b8262fe70bfb9 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 13 Dec 2012 18:43:52 +0200
Subject: Fixed path for correct assembly of the project

---
 indra/newview/llavatariconctrl.h     | 2 +-
 indra/newview/llconversationmodel.h  | 4 ++--
 indra/newview/llconversationview.h   | 4 ++--
 indra/newview/llfloaterimcontainer.h | 6 +++---
 indra/newview/llimview.h             | 2 +-
 indra/newview/lloutputmonitorctrl.h  | 4 ++--
 indra/newview/llviewermenu.h         | 2 +-
 7 files changed, 12 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index f55967926a..4929efb7d0 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -29,7 +29,7 @@
 
 #include <boost/signals2.hpp>
 
-#include "lliconctrl.h"
+#include "../llui/lliconctrl.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llviewermenu.h"
 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 7177d3a414..743a6ba40b 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -30,8 +30,8 @@
 #include <boost/signals2.hpp>
 
 #include "llavatarname.h"
-#include "llfolderviewitem.h"
-#include "llfolderviewmodel.h"
+#include "../llui/llfolderviewitem.h"
+#include "../llui/llfolderviewmodel.h"
 #include "llviewerfoldertype.h"
 
 // Implementation of conversations list
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index a6f408403b..fb2834f26a 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -27,10 +27,10 @@
 #ifndef LL_LLCONVERSATIONVIEW_H
 #define LL_LLCONVERSATIONVIEW_H
 
-#include "llfolderviewitem.h"
+#include "../llui/llfolderviewitem.h"
 
 #include "llavatariconctrl.h"
-#include "llbutton.h"
+#include "../llui/llbutton.h"
 #include "lloutputmonitorctrl.h"
 
 class LLTextBox;
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 4f1bb96d9b..1a3e64f759 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -32,11 +32,11 @@
 
 #include "llimview.h"
 #include "llevents.h"
-#include "llfloater.h"
-#include "llmultifloater.h"
+#include "../llui/llfloater.h"
+#include "../llui/llmultifloater.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llgroupmgr.h"
-#include "lltrans.h"
+#include "../llui/lltrans.h"
 #include "llconversationmodel.h"
 #include "llconversationview.h"
 
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 19b738069c..9dbbd7738a 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLIMVIEW_H
 #define LL_LLIMVIEW_H
 
-#include "lldockablefloater.h"
+#include "../llui/lldockablefloater.h"
 #include "lleventtimer.h"
 #include "llinstantmessage.h"
 
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 1fa6ef41f8..c3d3c35fd5 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -28,10 +28,10 @@
 #define LL_LLOUTPUTMONITORCTRL_H
 
 #include "v4color.h"
-#include "llview.h"
+#include "../llui/llview.h"
 #include "llmutelist.h"
 #include "llspeakingindicatormanager.h"
-#include "lluiimage.h"
+#include "../llui/lluiimage.h"
 
 class LLTextBox;
 class LLUICtrlFactory;
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 139f898b76..c0376ba114 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLVIEWERMENU_H
 #define LL_LLVIEWERMENU_H
 
-#include "llmenugl.h"
+#include "../llui/llmenugl.h"
 #include "llsafehandle.h"
 
 class LLMessageSystem;
-- 
cgit v1.2.3


From 179ab5c7353150ebaeac6e32fa55f96670c3c256 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Thu, 13 Dec 2012 15:54:49 -0800
Subject: CHUI-595, CHU-554: Updating the people panel to new specs.

---
 indra/newview/skins/default/xui/en/floater_people.xml | 2 +-
 indra/newview/skins/default/xui/en/panel_people.xml   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index 8e143623ab..5f475baa93 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -7,7 +7,7 @@
   height="570"
   help_topic="sidebar_people"
   min_height="440"
-  min_width="390"
+  min_width="260"
   layout="topleft"
   name="floater_people"
   save_rect="true"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 7433ad828d..7ce2627be9 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -229,7 +229,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          bg_opaque_color="DkGray"
          bottom="-1"
          follows="all"
-         label="MY FRIENDS"
+         label="FRIENDS"
          layout="topleft"
          left="0"
          help_topic="people_friends_tab"
@@ -385,7 +385,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          bg_opaque_color="DkGray"
          bottom="-1"
          follows="all"
-         label="MY GROUPS"
+         label="GROUPS"
          layout="topleft"
          left="0"
          help_topic="people_groups_tab"
-- 
cgit v1.2.3


From 569701cfc898091a414dad0650f89471b1962d49 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 13 Dec 2012 17:15:18 -0800
Subject: CHUI-574, CHUI-575 : Fixed inventory regressions : select the first
 filtered item when searching the inventory, simply made the folder selection
 secondary to item selection.

---
 indra/llui/llfolderview.h              | 16 ++++++++++++++--
 indra/newview/llinventoryfunctions.cpp | 10 ++++------
 2 files changed, 18 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 525efe425a..d4a1434c73 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -341,16 +341,28 @@ public:
 	virtual void doItem(LLFolderViewItem* item) = 0;
 };
 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLSelectFirstFilteredItem
+//
+// This will select the first *item* found in the hierarchy. If no item can be
+// selected, the first matching folder will.
+// Since doFolder() is done first but we prioritize item selection, we let the 
+// first filtered folder set the selection and raise a folder flag.
+// The selection might be overridden by the first filtered item in doItem()  
+// which checks an item flag. Since doFolder() checks the item flag too, the first
+// item will still be selected if items were to be done first and folders second.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLSelectFirstFilteredItem : public LLFolderViewFunctor
 {
 public:
-	LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
+	LLSelectFirstFilteredItem() : mItemSelected(FALSE), mFolderSelected(FALSE) {}
 	virtual ~LLSelectFirstFilteredItem() {}
 	virtual void doFolder(LLFolderViewFolder* folder);
 	virtual void doItem(LLFolderViewItem* item);
-	BOOL wasItemSelected() { return mItemSelected; }
+	BOOL wasItemSelected() { return mItemSelected || mFolderSelected; }
 protected:
 	BOOL mItemSelected;
+	BOOL mFolderSelected;
 };
 
 class LLOpenFilteredFolders : public LLFolderViewFunctor
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 1426567196..6474d56414 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1031,14 +1031,12 @@ void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
 
 void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
 {
-	if (folder->LLFolderViewItem::passedFilter() && !mItemSelected)
+	// Skip if folder or item already found, if not filtered or if no parent (root folder is not selectable)
+	if (!mFolderSelected && !mItemSelected && folder->LLFolderViewItem::passedFilter() && folder->getParentFolder())
 	{
 		folder->getRoot()->setSelection(folder, FALSE, FALSE);
-		if (folder->getParentFolder())
-		{
-			folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
-		}
-		mItemSelected = TRUE;
+		folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+		mFolderSelected = TRUE;
 	}
 }
 
-- 
cgit v1.2.3


From 08cc82ec483fab8299d52ba979f04df95e525acb Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 13 Dec 2012 22:45:47 -0800
Subject: CHUI-599 : Fixed : Avatar name provides now a method to get the
 regular account name.

---
 indra/llcommon/llavatarname.h     | 3 +++
 indra/newview/llavataractions.cpp | 8 ++------
 2 files changed, 5 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index 2f8c534974..4827353018 100644
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -74,6 +74,9 @@ public:
 	// Also used for backwards compatibility with systems like voice and muting
 	std::string getUserName() const;
 	
+	// Returns "james.linden" or the legacy name for very old names
+	std::string getAccountName() const { return mUsername; }
+
 	// Debug print of the object
 	void dump() const;
 	
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 59b862503c..23d528901a 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -315,15 +315,11 @@ static const char* get_profile_floater_name(const LLUUID& avatar_id)
 
 static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
-	std::string username = av_name.getUserName();
-	
-	llinfos << "opening web profile for " << username << llendl;		
-	std::string url = getProfileURL(username);
+	std::string url = getProfileURL(av_name.getAccountName());
 
 	// PROFILES: open in webkit window
 	LLFloaterWebContent::Params p;
-	p.url(url).
-		id(agent_id.asString());
+	p.url(url).id(agent_id.asString());
 	LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
 }
 
-- 
cgit v1.2.3


From 22c2fff4ba4198b8dca8367ae3f03d189e815770 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 14 Dec 2012 19:56:05 +0200
Subject: CHUI-566 Flashing and color on Conversations FUI button and
 conversation line item

---
 indra/llui/llbutton.cpp                            | 36 +++++++------------
 indra/newview/llimview.cpp                         | 42 ++++++++++++++--------
 indra/newview/skins/default/colors.xml             |  3 ++
 .../skins/default/xui/en/widgets/toolbar.xml       | 12 +++----
 4 files changed, 48 insertions(+), 45 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index f82cdc64a9..99384439d2 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -613,29 +613,11 @@ void LLButton::draw()
 	static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
 	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
 
-	bool flash = false;
 	if (mFlashingTimer)
 	{
 		mFlashing = mFlashingTimer->isFlashingInProgress();
-		flash = mFlashing && (!sEnableButtonFlashing || mFlashingTimer->isCurrentlyHighlighted());
-	}
-	else 
-	{
-		if(mFlashing)
-		{
-			if ( sEnableButtonFlashing)
-			{
-				F32 elapsed = mFrameTimer.getElapsedTimeF32();
-				S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
-				// flash on or off?
-				flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
-			}
-			else
-			{ // otherwise just highlight button in flash color
-				flash = true;
-			}
-		}
 	}
+	bool flash = mFlashing && sEnableButtonFlashing;
 
 	bool pressed_by_keyboard = FALSE;
 	if (hasFocus())
@@ -660,7 +642,8 @@ void LLButton::draw()
 	bool selected = getToggleState();
 	
 	bool use_glow_effect = FALSE;
-	LLColor4 glow_color = LLColor4::white;
+	LLColor4 highlighting_color = LLColor4::white;
+	LLColor4 glow_color;
 	LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
 	LLUIImage* imagep = NULL;
 	if (pressed && mDisplayPressedState)
@@ -733,10 +716,15 @@ void LLButton::draw()
 			LLColor4 flash_color = mFlashBgColor.get();
 			use_glow_effect = TRUE;
 			glow_type = LLRender::BT_ALPHA; // blend the glow
-			if (mNeedsHighlight) // highlighted AND flashing
-				glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
-			else
+
+			if (mFlashingTimer->isCurrentlyHighlighted())
+			{
 				glow_color = flash_color;
+			}
+			else if (mNeedsHighlight)
+			{
+                glow_color = highlighting_color;
+			}
 		}
 	}
 
@@ -785,7 +773,7 @@ void LLButton::draw()
 	if (use_glow_effect)
 	{
 		mCurGlowStrength = lerp(mCurGlowStrength,
-					mFlashing ? (flash? 1.0 : 0.0)
+					mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || mNeedsHighlight? 1.0 : 0.0)
 					: mHoverGlowStrength,
 					LLCriticalDamp::getInterpolant(0.05f));
 	}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 7e02915b43..5b4d5466a1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -160,10 +160,16 @@ void on_new_message(const LLSD& msg)
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
     //session floater not focused (visible or not)
-    bool sessionFloaterNotFocused = session_floater && !session_floater->hasFocus(); 
+    bool session_floater_not_focused = session_floater && !session_floater->hasFocus();
+    //conv. floater is closed
+    bool conversation_floater_is_closed =
+    		!(  im_box
+    		    && im_box->isInVisibleChain()
+                && !im_box->isMinimized());
 
     //conversation floater not focused (visible or not)
-    bool conversationFloaterNotFocused = im_box && !im_box->hasFocus();
+    bool conversation_floater_not_focused =
+    		conversation_floater_is_closed || !im_box->hasFocus();
 
     if ("toast" == action)
     {
@@ -187,12 +193,12 @@ void on_new_message(const LLSD& msg)
         }
 
         //User is not focused on conversation containing the message
-        if(sessionFloaterNotFocused)
+        if(session_floater_not_focused)
         {
             im_box->flashConversationItemWidget(session_id, true);
 
             //The conversation floater isn't focused/open
-            if(conversationFloaterNotFocused)
+            if(conversation_floater_not_focused)
             {
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
 
@@ -204,23 +210,29 @@ void on_new_message(const LLSD& msg)
             }
         }
     }
+
     else if ("flash" == action)
     {
-        //User is not focused on conversation containing the message
-        if(sessionFloaterNotFocused && conversationFloaterNotFocused)
-        {
-            gToolBarView->flashCommand(LLCommandId("chat"), true); 
-        }
-        //conversation floater is open but a different conversation is focused
-        else if(sessionFloaterNotFocused)
-        {
-            im_box->flashConversationItemWidget(session_id, true);
-        }
+    	if (session_floater_not_focused)
+    	{
+    		//User is not focused on conversation containing the message
+
+            if(conversation_floater_not_focused)
+            {
+                gToolBarView->flashCommand(LLCommandId("chat"), true);
+            }
+            //conversation floater is open but a different conversation is focused
+            else
+            {
+                im_box->flashConversationItemWidget(session_id, true);
+            }
+    	}
     }
+
     else if("openconversations" == action)
     {
         //User is not focused on conversation containing the message
-        if(sessionFloaterNotFocused)
+        if(session_floater_not_focused)
         {
             //Flash line item
             im_box->flashConversationItemWidget(session_id, true);
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 05230b8bd5..afd8ee4ba1 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -11,6 +11,9 @@
 	<color
 	 name="EmphasisColor_35"
 	 value="0.38 0.694 0.573 0.35" />
+    <color
+    name="BeaconColor"
+    value="1 .67 .2 1" />	 
 	<color
 	 name="White"
 	 value="1 1 1 1" />
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 053b213ef4..0ace37a5dc 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -30,9 +30,9 @@
                         image_overlay_alignment="left"
                         use_ellipses="true"
                         auto_resize="true"
-                        button_flash_count="3"
-                        button_flash_rate="0.25"
-                        flash_color="EmphasisColor"/>
+                        button_flash_count="4"
+                        button_flash_rate="0.5"
+                        flash_color="BeaconColor"/>
   <button_icon pad_left="10"
                pad_right="10"
                image_bottom_pad="10"
@@ -51,7 +51,7 @@
                chrome="true"
                use_ellipses="true"
                auto_resize="true"
-               button_flash_count="3"
-               button_flash_rate="0.25"
-               flash_color="EmphasisColor"/>
+               button_flash_count="4"
+               button_flash_rate="0.5"
+               flash_color="BeaconColor"/>
 </toolbar>
-- 
cgit v1.2.3


From bede028c51a30d2c0d3b3077e2b6d0ffdaf769da Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 14 Dec 2012 14:17:53 -0800
Subject: CHUI-595: Updating the people panel according to specs.

---
 indra/newview/skins/default/xui/en/floater_people.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index 5f475baa93..fe3aeeb038 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -14,13 +14,13 @@
   single_instance="true"
   reuse_instance="true"
   title="PEOPLE"
-  width="390">
+  width="370">
     <panel_container
       default_panel_name="panel_people"
       follows="all"
       height="570"
       name="main_panel"
-      width="390">
+      width="370">
       <panel
         class="panel_people"
         name="panel_people"
-- 
cgit v1.2.3


From 9b556fb3fea0a97f5773d8fd435a428b0fafacbf Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 14 Dec 2012 14:19:17 -0800
Subject: CHUI-599 : Use the account name in all places that are not UI related
 but use avatar names to index, search and other code only uses.

---
 indra/llmessage/llavatarnamecache.cpp |  2 +-
 indra/llui/llscrolllistctrl.cpp       |  2 +-
 indra/llui/llurlentry.cpp             |  2 +-
 indra/newview/llfavoritesbar.cpp      | 10 +++++-----
 indra/newview/llfriendcard.cpp        |  2 +-
 indra/newview/llpanelblockedlist.cpp  |  2 +-
 indra/newview/llpanelgroupinvite.cpp  |  4 ++--
 indra/newview/llpanelgrouproles.cpp   |  4 ++--
 indra/newview/llvoicevivox.cpp        |  2 +-
 9 files changed, 15 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 9d6aa15ed1..9163262cc0 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -561,7 +561,7 @@ void LLAvatarNameCache::eraseUnrefreshed()
             {
                 const LLUUID& agent_id = it->first;
                 LL_DEBUGS("AvNameCache") << agent_id 
-                                         << " user '" << av_name.getUserName() << "' "
+                                         << " user '" << av_name.getAccountName() << "' "
                                          << "expired " << now - av_name.mExpires << " secs ago"
                                          << LL_ENDL;
                 sCache.erase(it++);
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 2bd2294ea2..8b9fb47d5c 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1841,7 +1841,7 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
 	{
 		LLAvatarName av_name;
 		LLAvatarNameCache::get(LLUUID(id), &av_name);
-		name = av_name.getUserName();
+		name = av_name.getAccountName();
 	}
 	LLUrlAction::copyURLToClipboard(name);
 }
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index fd2635c73a..47a780b7dc 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -613,7 +613,7 @@ LLUrlEntryAgentUserName::LLUrlEntryAgentUserName()
 
 std::string LLUrlEntryAgentUserName::getName(const LLAvatarName& avatar_name)
 {
-	return avatar_name.getUserName();
+	return avatar_name.getAccountName();
 }
 
 //
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index ff0e01a200..ba3d4036c9 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -1520,8 +1520,8 @@ void LLFavoritesOrderStorage::saveFavoritesSLURLs()
 
 	LLAvatarName av_name;
 	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Saved favorites for " << av_name.getUserName() << llendl;
-	fav_llsd[av_name.getUserName()] = user_llsd;
+	lldebugs << "Saved favorites for " << av_name.getAccountName() << llendl;
+	fav_llsd[av_name.getAccountName()] = user_llsd;
 
 	llofstream file;
 	file.open(filename);
@@ -1539,10 +1539,10 @@ void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
 
 	LLAvatarName av_name;
 	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Removed favorites for " << av_name.getUserName() << llendl;
-	if (fav_llsd.has(av_name.getUserName()))
+	lldebugs << "Removed favorites for " << av_name.getAccountName() << llendl;
+	if (fav_llsd.has(av_name.getAccountName()))
 	{
-		fav_llsd.erase(av_name.getUserName());
+		fav_llsd.erase(av_name.getAccountName());
 	}
 
 	llofstream out_file;
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 0e72fab32c..a4dfd94496 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -533,7 +533,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
 	bool shouldBeAdded = true;
 	LLAvatarName av_name;
 	LLAvatarNameCache::get(avatarID, &av_name);
-	const std::string& name = av_name.getUserName();
+	const std::string& name = av_name.getAccountName();
 
 	lldebugs << "Processing buddy name: " << name 
 		<< ", id: " << avatarID
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index b4deb7a920..ecab7d2167 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -224,7 +224,7 @@ void LLPanelBlockedList::onFilterEdit(const std::string& search_string)
 void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
 {
 	if (names.empty() || ids.empty()) return;
-	LLMute mute(ids[0], names[0].getUserName(), LLMute::AGENT);
+	LLMute mute(ids[0], names[0].getAccountName(), LLMute::AGENT);
 	LLMuteList::getInstance()->add(mute);
 	showPanelAndSelect(mute.mID);
 }
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index a2bbc5400c..3f0c6c4613 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -482,7 +482,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
 				}
 				else
 				{
-					names.push_back(av_name.getUserName());
+					names.push_back(av_name.getAccountName());
 				}
 			}
 		}
@@ -495,7 +495,7 @@ void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& a
 	std::vector<std::string> names;
 	uuid_vec_t agent_ids;
 	agent_ids.push_back(id);
-	names.push_back(av_name.getUserName());
+	names.push_back(av_name.getAccountName());
 
 	mImplementation->addUsers(names, agent_ids);
 }
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 7368477905..98e4cded6c 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1613,7 +1613,7 @@ void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemb
 	}
 	
 	// trying to avoid unnecessary hash lookups
-	if (matchesSearchFilter(av_name.getUserName()))
+	if (matchesSearchFilter(av_name.getAccountName()))
 	{
 		addMemberToList(member);
 		if(!mMembersList->getEnabled())
@@ -1667,7 +1667,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
 		{
-			if (matchesSearchFilter(av_name.getUserName()))
+			if (matchesSearchFilter(av_name.getAccountName()))
 			{
 				addMemberToList(mMemberProgress->second);
 			}
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 6fdda12a1c..cd93b3da28 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -2668,7 +2668,7 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)
 		// *NOTE: For now, we feed legacy names to Vivox because I don't know
 		// if their service can support a mix of new and old clients with
 		// different sorts of names.
-		std::string name = av_name.getUserName();
+		std::string name = av_name.getAccountName();
 
 		const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id);
 		bool canSeeMeOnline = false;
-- 
cgit v1.2.3


From 56b23a8727af34d950e217affa784d322b737cc3 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 14 Dec 2012 14:25:49 -0800
Subject: CHUI-554: Updating the people panel according to specs.

---
 indra/newview/skins/default/xui/en/floater_people.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index fe3aeeb038..701233ba4a 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -6,7 +6,7 @@
   can_resize="true"
   height="570"
   help_topic="sidebar_people"
-  min_height="440"
+  min_height="220"
   min_width="260"
   layout="topleft"
   name="floater_people"
-- 
cgit v1.2.3


From 68b61bdec620014f30d6e9c63726d96fa7f4382a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 14 Dec 2012 16:01:14 -0800
Subject: CHUI-520: Now when have a P2P conversation torn off a voice indicator
 icon will be displayed allowing the user to adjust the voice volume when
 clicked. Also did a code cleanup on conversationview.h/cpp which was showing
 the speaking indicator icon too soon when joining another voice session. This
 was due to calling switchIndicator(..) directly inside
 ::onCurrentVoiceSessionChanged. The proper solution is to wait for
 SpeeakingIndicatorManager::switchSpeakerIndicators() call switchIndicators().

---
 indra/newview/llconversationview.cpp               | 24 ----------------------
 indra/newview/llconversationview.h                 |  1 -
 indra/newview/llfloaterimsession.cpp               | 18 ++++++++++++++++
 indra/newview/llfloaterimsession.h                 |  1 +
 indra/newview/llfloaterimsessiontab.cpp            |  3 +++
 indra/newview/llfloaterimsessiontab.h              |  1 +
 indra/newview/lloutputmonitorctrl.cpp              |  2 ++
 .../skins/default/xui/en/floater_im_session.xml    | 12 +++++++++++
 8 files changed, 37 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 527c0ad233..71d668d047 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -341,14 +341,6 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
 	if (vmi)
 	{
 		bool is_active = vmi->getUUID() == session_id;
-		bool is_nearby = vmi->getType() == LLConversationItem::CONV_SESSION_NEARBY;
-
-		if (is_nearby)
-		{
-			mSpeakingIndicator->setSpeakerId(is_active ? gAgentID : LLUUID::null);
-		}
-
-		mSpeakingIndicator->switchIndicator(is_active);
 		mCallIconLayoutPanel->setVisible(is_active);
 	}
 }
@@ -409,7 +401,6 @@ BOOL LLConversationViewParticipant::postBuild()
 	mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
 	mInfoBtn->setVisible(false);
 
-	mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewParticipant::onCurrentVoiceSessionChanged, this, _1));
 	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
 
     if (!sStaticInitialized)
@@ -479,21 +470,6 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
     return arranged;
 }
 
-void LLConversationViewParticipant::onCurrentVoiceSessionChanged(const LLUUID& session_id)
-{
-	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
-	
-	if (participant_model)
-	{
-		LLConversationItemSession* parent_session = participant_model->getParentSession();
-		if (parent_session)
-		{
-			bool is_active = (parent_session->getUUID() == session_id);
-			mSpeakingIndicator->switchIndicator(is_active);
-		}
-	}
-}
-
 void LLConversationViewParticipant::refresh()
 {
 	// Refresh the participant view from its model data
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index fb2834f26a..a9333020e9 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -146,7 +146,6 @@ protected:
 	void onInfoBtnClick();
 
 private:
-	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
 
     LLAvatarIconCtrl* mAvatarIcon;
 	LLButton * mInfoBtn;
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 3001029968..a0ca7286f1 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -101,6 +101,24 @@ void LLFloaterIMSession::refresh()
 	}
 }
 
+// virtual
+void LLFloaterIMSession::onTearOffClicked()
+{
+    LLFloaterIMSessionTab::onTearOffClicked();
+
+    if(mIsP2PChat)
+    {
+        if(isTornOff())
+        {
+            mSpeakingIndicator->setSpeakerId(mOtherParticipantUUID, mSessionID);
+        }
+        else
+        {
+            mSpeakingIndicator->setSpeakerId(LLUUID::null);
+        }
+    }
+}
+
 // virtual
 void LLFloaterIMSession::onClickCloseBtn()
 {
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 72a320041f..1d8957b1d9 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -135,6 +135,7 @@ private:
 
 	/*virtual*/ void refresh();
 
+    /*virtual*/ void onTearOffClicked();
 	/*virtual*/ void onClickCloseBtn();
 
 	// Update the window title and input field help text
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 0eb0289f49..ab588e489f 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -54,6 +54,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
   ,  mSessionID(session_id.asUUID())
   , mConversationsRoot(NULL)
   , mScroller(NULL)
+  , mSpeakingIndicator(NULL)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
   , mInputEditorTopPad(0)
@@ -206,6 +207,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
 	mScroller->setFollowsAll();
 	
+    mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
+
 	// Insert that scroller into the panel widgets hierarchy
 	mParticipantListPanel->addChild(mScroller);	
 	
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 4851904074..cd0bcd481c 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -149,6 +149,7 @@ protected:
 	LLFolderView* mConversationsRoot;
 	LLScrollContainer* mScroller;
 
+    LLOutputMonitorCtrl* mSpeakingIndicator;
 	LLChatHistory* mChatHistory;
 	LLChatEntry* mInputEditor;
 	int mInputEditorTopPad; // padding between input field and chat history
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 02841e9831..f6e3c0cac0 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -260,6 +260,8 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
 	if (speaker_id.isNull() && mSpeakerId.notNull())
 	{
 		LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
+        switchIndicator(false);
+        mSpeakerId = speaker_id;
 	}
 
 	if (speaker_id.isNull() || (speaker_id == mSpeakerId))
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index faf54774f6..e4b127b7b9 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -106,6 +106,18 @@
                  name="voice_call_btn"
                  tool_tip="Open voice connection"
                  width="31"/>
+              <output_monitor
+                  auto_update="true"
+                  follows="top|left"
+                  draw_border="false"
+                  height="16"
+                  layout="topleft"
+                  top="10"
+                  left_pad="10"
+                  mouse_opaque="true"
+                  name="speaking_indicator"
+                  visible="false"
+                  width="20" />       
              <button
                  follows="right|top"
                  height="25"
-- 
cgit v1.2.3


From d0dbdac41dffa8afbebaecb25d0e57e044bf61e6 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Fri, 14 Dec 2012 17:00:00 -0800
Subject: CHUI-549: Updating the conversations floater according to specs.

---
 indra/newview/llfloaterimcontainer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 3a5f2ae854..54cfe88140 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1476,7 +1476,7 @@ LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParti
 	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
 	params.tool_tip = params.name;
 	params.participant_id = item->getUUID();
-    params.folder_indentation = 42;
+    params.folder_indentation = 27;
 
 	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
 }
-- 
cgit v1.2.3


From d0d8ee87e7648e80b83b125202d6270495e955b6 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 14 Dec 2012 21:20:43 -0800
Subject: CHUI-596 : Added a new flash state so we can keep a conversation
 highlighted after the flash time ends. Clears the flash state for all
 conversation on select.

---
 indra/newview/llconversationview.cpp   | 10 ++++++++--
 indra/newview/llconversationview.h     |  3 ++-
 indra/newview/llfloaterimcontainer.cpp | 22 ++++++++++++----------
 3 files changed, 22 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 527c0ad233..1943174872 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -98,14 +98,20 @@ LLConversationViewSession::~LLConversationViewSession()
 	mFlashTimer->unset();
 }
 
+void LLConversationViewSession::setFlashState(bool flash_state)
+{
+	mFlashStateOn = flash_state;
+	(flash_state ? mFlashTimer->startFlashing() : mFlashTimer->stopFlashing());
+}
+
 bool LLConversationViewSession::isHighlightAllowed()
 {
-	return mFlashTimer->isFlashingInProgress() || mIsSelected;
+	return mFlashStateOn || mIsSelected;
 }
 
 bool LLConversationViewSession::isHighlightActive()
 {
-	return mFlashTimer->isFlashingInProgress() ? mFlashTimer->isCurrentlyHighlighted() : mIsCurSelection;
+	return (mFlashStateOn ? (mFlashTimer->isFlashingInProgress() ? mFlashTimer->isCurrentlyHighlighted() : true) : mIsCurSelection);
 }
 
 BOOL LLConversationViewSession::postBuild()
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index fb2834f26a..3e65823a23 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -83,7 +83,7 @@ public:
 
 	virtual void refresh();
 
-	LLFlashTimer * getFlashTimer() { return mFlashTimer; }
+	void setFlashState(bool flash_state);
 
 private:
 
@@ -94,6 +94,7 @@ private:
 	LLTextBox*				mSessionTitle;
 	LLOutputMonitorCtrl*	mSpeakingIndicator;
 	LLFlashTimer*			mFlashTimer;
+	bool					mFlashStateOn;
 
 	bool					mCollapsedMode;
     bool                    mHasArrow;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 3a5f2ae854..aaf43bdda0 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1247,6 +1247,17 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     BOOL handled = TRUE;
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
 
+	// On selection, stop the flash state on all conversation widgets
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+			widget->setFlashState(false);
+		}
+	}
+	
     /* widget processing */
     if (select_widget)
     {
@@ -1723,16 +1734,7 @@ void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id,
 
 	if (widget)
 	{
-        //Start flash
-		if (is_flashes)
-		{
-	        widget->getFlashTimer()->startFlashing();
-		}
-        //Stop flash
-		else
-		{
-			widget->getFlashTimer()->stopFlashing();
-		}
+		widget->setFlashState(is_flashes);
 	}
 }
 
-- 
cgit v1.2.3


From 64dffe46118f9c435115edd2b714a0314242e752 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Sat, 15 Dec 2012 20:37:18 +0200
Subject: CHUI-598 : Fixed : Conversation log file created even when keep
 conversation log preference is off : Checked the status of the another
 ("KeepConversationLogTranscripts") setting too.

---
 indra/newview/llconversationlog.cpp        | 3 ++-
 indra/newview/llfloaterconversationlog.cpp | 3 ++-
 indra/newview/llimview.cpp                 | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index a0765f5e16..1171b3db41 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -191,7 +191,8 @@ LLConversationLog::LLConversationLog()
 	if (ctrl)
 	{
 		ctrl->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
-		if (ctrl->getValue().asBoolean())
+		if (ctrl->getValue().asBoolean()
+				&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
 		{
 			enableLogging(true);
 		}
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index 089aec1905..a40a000bab 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -67,7 +67,8 @@ BOOL LLFloaterConversationLog::postBuild()
 	if (ctrl)
 	{
 		ctrl->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
-		onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean());
+		onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean()
+				&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"));
 	}
 
 	return LLFloater::postBuild();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 4e2ac09dd8..cdd08ededf 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -857,7 +857,8 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 
 bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")
+			&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
 	{	
 		std::string from_name = from;
 
-- 
cgit v1.2.3


From 56973ed9a4e3bba8529071a5e37e576f17490296 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Sat, 15 Dec 2012 17:35:24 +0200
Subject: CHUI-505 : Fixed : Don't open Call Log on login if the user doesn't
 want a Call Log: Checked the setting status

---
 indra/newview/llimview.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cdd08ededf..da3d2e89bf 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2478,8 +2478,8 @@ void LLIMMgr::addMessage(
 		new_session_id = computeSessionID(dialog, other_participant_id);
 	}
 
-	// Open conversation log if offline messages are present
-	if (is_offline_msg)
+	// Open conversation log if offline messages are present and user allows a Call Log
+	if (is_offline_msg && gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
 	{
 		LLFloaterConversationLog* floater_log =
 				LLFloaterReg::getTypedInstance<LLFloaterConversationLog>("conversation");
-- 
cgit v1.2.3


From 01bdfb3ecb88ce71078494274a8d7835d181c50e Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Sat, 15 Dec 2012 21:28:38 +0200
Subject: CHUI-591 FIXED Issues with resizing conversations floater

---
 indra/llui/lllayoutstack.cpp                       |  6 +++-
 indra/llui/lllayoutstack.h                         |  2 ++
 indra/llui/llmultifloater.cpp                      |  4 +--
 indra/llui/llresizebar.cpp                         |  8 ++++-
 indra/llui/llresizebar.h                           |  2 ++
 indra/llui/llview.cpp                              | 21 +++++++++++--
 indra/newview/llfloaterimcontainer.cpp             | 35 +++++++++-------------
 indra/newview/llfloaterimcontainer.h               |  3 +-
 indra/newview/llfloaterimnearbychat.cpp            | 24 +++++++--------
 indra/newview/llfloaterimnearbychat.h              |  4 +--
 .../skins/default/xui/en/floater_im_container.xml  | 31 +++++++++----------
 11 files changed, 79 insertions(+), 61 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 0674275612..e642883991 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -32,7 +32,6 @@
 
 #include "lllocalcliprect.h"
 #include "llpanel.h"
-#include "llresizebar.h"
 #include "llcriticaldamp.h"
 #include "boost/foreach.hpp"
 
@@ -796,6 +795,11 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 				}
 				else
 				{
+					if (new_auto_resize_headroom < 1.f)
+					{
+						new_auto_resize_headroom = 1.f;
+					}
+
 					F32 new_fractional_size = llclamp(total_visible_fraction * (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) 
 														/ new_auto_resize_headroom,
 													MIN_FRACTIONAL_SIZE,
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 883331c792..02c664f1a0 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -29,6 +29,7 @@
 #define LL_LLLAYOUTSTACK_H
 
 #include "llpanel.h"
+#include "llresizebar.h"
 
 
 class LLLayoutPanel;
@@ -178,6 +179,7 @@ public:
 	F32 getAutoResizeFactor() const;
 	F32 getVisibleAmount() const;
 	S32 getVisibleDim() const;
+	LLResizeBar* getResizeBar() { return mResizeBar; }
 
 	bool isCollapsed() const { return mCollapsed;}
 
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index 02ff64dbc6..179b251cdb 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -41,8 +41,8 @@ LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
 	  mTabContainer(NULL),
 	  mTabPos(LLTabContainer::TOP),
 	  mAutoResize(TRUE),
-	  mOrigMinWidth(0),
-	  mOrigMinHeight(0)
+	  mOrigMinWidth(params.min_width),
+	  mOrigMinHeight(params.min_height)
 {
 }
 
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index 87aeb4d7a7..4b9add820f 100644
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -45,7 +45,8 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
 	mSide( p.side ),
 	mSnappingEnabled(p.snapping_enabled),
 	mAllowDoubleClickSnapping(p.allow_double_click_snapping),
-	mResizingView(p.resizing_view)
+	mResizingView(p.resizing_view),
+	mResizeListener(NULL)
 {
 	setFollowsNone();
 	// set up some generically good follow code.
@@ -261,6 +262,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
 		}
 	}
 
+	if (mResizeListener)
+	{
+		mResizeListener(NULL);
+	}
+
 	return handled;
 } // end LLResizeBar::handleHover
 
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index 6daf191918..8190a95a71 100644
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -71,6 +71,7 @@ public:
 	void			setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
 	void			setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
 	bool			canResize() { return getEnabled() && mMaxSize > mMinSize; }
+	void            setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;}
 
 private:
 	S32				mDragLastScreenX;
@@ -84,6 +85,7 @@ private:
 	BOOL			mSnappingEnabled;
 	BOOL			mAllowDoubleClickSnapping;
 	LLView*			mResizingView;
+	boost::function<void(void*)>  mResizeListener;
 };
 
 #endif  // LL_RESIZEBAR_H
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 5bcdae921d..3613a40e2c 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -55,6 +55,8 @@
 #include "lltexteditor.h"
 #include "lltextbox.h"
 
+static const S32 LINE_HEIGHT = 15;
+
 S32		LLView::sDepth = 0;
 bool	LLView::sDebugRects = false;
 bool	LLView::sDebugRectsShowNames = true;
@@ -1203,11 +1205,24 @@ void LLView::drawDebugRect()
 			&& preview_iter == sPreviewHighlightedElements.end()
 			&& sDebugRectsShowNames)
 		{
-			//char temp[256];
 			S32 x, y;
 			gGL.color4fv( border_color.mV );
-			x = debug_rect.getWidth()/2;
-			y = debug_rect.getHeight()/2;
+
+			x = debug_rect.getWidth() / 2;
+
+			S32 rect_height = debug_rect.getHeight();
+			S32 lines = rect_height / LINE_HEIGHT + 1;
+
+			S32 depth = 0;
+			LLView * viewp = this;
+			while (NULL != viewp)
+			{
+				viewp = viewp->getParent();
+				depth++;
+			}
+
+			y = rect_height - LINE_HEIGHT * (depth % lines + 1);
+
 			std::string debug_text = llformat("%s (%d x %d)", getName().c_str(),
 										debug_rect.getWidth(), debug_rect.getHeight());
 			LLFontGL::getFontSansSerifSmall()->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color,
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 3c85f21188..ba5ec363d6 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -51,8 +51,8 @@
 #include "llconversationview.h"
 #include "llcallbacklist.h"
 #include "llworld.h"
-
 #include "llsdserialize.h"
+
 //
 // LLFloaterIMContainer
 //
@@ -171,6 +171,9 @@ BOOL LLFloaterIMContainer::postBuild()
 	// Open IM session with selected participant on double click event
 	mConversationsListPanel->setDoubleClickCallback(boost::bind(&LLFloaterIMContainer::doToSelected, this, LLSD("im")));
 
+	// The resize limits for LLFloaterIMContainer should be updated, based on current values of width of conversation and message panels
+	mConversationsPane->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMContainer::assignResizeLimits, this));
+
 	// Create the root model and view for all conversation sessions
 	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
 
@@ -247,6 +250,7 @@ void LLFloaterIMContainer::onOpen(const LLSD& key)
 {
 	LLMultiFloater::onOpen(key);
 	openNearbyChat();
+	assignResizeLimits();
 }
 
 // virtual
@@ -308,26 +312,6 @@ void LLFloaterIMContainer::onCloseFloater(LLUUID& id)
 	setFocus(TRUE);
 }
 
-// virtual
-void LLFloaterIMContainer::computeResizeLimits(S32& new_min_width, S32& new_min_height)
-{
-	// possibly increase floater's minimum height according to children's minimums
-	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
-	{
-		LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getPanelByIndex(tab_idx));
-		if (floaterp)
-		{
-			new_min_height = llmax(new_min_height, floaterp->getMinHeight());
-		}
-	}
-
-	S32 conversations_pane_min_dim = mConversationsPane->getRelevantMinDim();
-	S32 messages_pane_min_dim = mMessagesPane->getRelevantMinDim();
-
-	// set floater's minimum width according to relevant minimal children's dimensionals
-	new_min_width = conversations_pane_min_dim + messages_pane_min_dim + LLPANEL_BORDER_WIDTH*2;
-}
-
 void LLFloaterIMContainer::onNewMessageReceived(const LLSD& data)
 {
 	LLUUID session_id = data["session_id"].asUUID();
@@ -728,6 +712,15 @@ void LLFloaterIMContainer::updateState(bool collapse, S32 delta_width)
         setResizeLimits(expanded_min_size, expanded_min_size);
 	}
 
+    assignResizeLimits();
+}
+
+void LLFloaterIMContainer::assignResizeLimits()
+{
+	const LLRect& conv_rect = mConversationsPane->isCollapsed() ? LLRect() : mConversationsPane->getRect();
+	S32 msg_limits  = mMessagesPane->isCollapsed() ? 0 : mMessagesPane->getExpandedMinDim();
+	S32 x_limits = conv_rect.getWidth() + msg_limits;
+	setResizeLimits(x_limits + LLPANEL_BORDER_WIDTH * 3, getMinHeight());
 }
 
 void LLFloaterIMContainer::onAddButtonClicked()
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 1a3e64f759..5db1565cea 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -110,7 +110,7 @@ private:
 	avatarID_panel_map_t mSessions;
 	boost::signals2::connection mNewMessageConnection;
 
-	/*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height);
+	/*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height) {}
 
 	void onNewMessageReceived(const LLSD& data);
 
@@ -153,6 +153,7 @@ private:
 	void toggleAllowTextChat(const LLUUID& participant_uuid);
 	void toggleMute(const LLUUID& participant_id, U32 flags);
 	void openNearbyChat();
+	void assignResizeLimits();
 
 	LLButton* mExpandCollapseBtn;
 	LLButton* mStubCollapseBtn;
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index a9a3611970..797d590e1f 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -113,8 +113,8 @@ BOOL LLFloaterIMNearbyChat::postBuild()
     BOOL result = LLFloaterIMSessionTab::postBuild();
 	
 	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
-	mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
-	mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
+	mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
+	mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
 	mInputEditor->setFocusReceivedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusReceived, this));
 	mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle"));
 
@@ -354,13 +354,11 @@ BOOL LLFloaterIMNearbyChat::matchChatTypeTrigger(const std::string& in_str, std:
 	return string_was_found;
 }
 
-void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata)
+void LLFloaterIMNearbyChat::onChatBoxKeystroke()
 {
 	LLFirstUse::otherAvatarChatFirst(false);
 
-	LLFloaterIMNearbyChat* self = (LLFloaterIMNearbyChat *)userdata;
-
-	LLWString raw_text = self->mInputEditor->getWText();
+	LLWString raw_text = mInputEditor->getWText();
 
 	// Can't trim the end, because that will cause autocompletion
 	// to eat trailing spaces that might be part of a gesture.
@@ -386,8 +384,8 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userd
 		// the selection will already be deleted, but we need to trim
 		// off the character before
 		std::string new_text = raw_text.substr(0, length-1);
-		self->mInputEditor->setText( new_text );
-		self->mInputEditor->setCursorToEnd();
+		mInputEditor->setText( new_text );
+		mInputEditor->setCursorToEnd();
 		length = length - 1;
 	}
 	*/
@@ -407,17 +405,17 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userd
 		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
 		{
 			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+			mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
 
 			// Select to end of line, starting from the character
 			// after the last one the user typed.
-			self->mInputEditor->selectNext(rest_of_match, false);
+			mInputEditor->selectNext(rest_of_match, false);
 		}
 		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
 		{
 			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
-			self->mInputEditor->endOfDoc();
+			mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
+			mInputEditor->endOfDoc();
 		}
 
 		//llinfos << "GESTUREDEBUG " << trigger 
@@ -428,7 +426,7 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userd
 }
 
 // static
-void LLFloaterIMNearbyChat::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
+void LLFloaterIMNearbyChat::onChatBoxFocusLost()
 {
 	// stop typing animation
 	gAgent.stopTyping();
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index a38824dc78..f4213eda5a 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -83,8 +83,8 @@ public:
 
 protected:
 	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
-	static void onChatBoxKeystroke(LLTextEditor* caller, void* userdata);
-	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
+	void onChatBoxKeystroke();
+	void onChatBoxFocusLost();
 	void onChatBoxFocusReceived();
 
 	void sendChat( EChatType type );
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 1128b8fef6..37a3b9ac59 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -15,7 +15,7 @@
  title="CONVERSATIONS"
  bottom="-50"
  right="-5"
- width="450">
+ width="500">
     <string
      name="collapse_icon"
      value="Conv_toolbar_collapse"/>
@@ -24,22 +24,21 @@
      value="Conv_toolbar_expand"/>
     <layout_stack
      animate="true" 
+     bottom="-1"
      follows="all"
-     height="230"
      layout="topleft"
      left="0"
      name="conversations_stack"
      orientation="horizontal"
-     top="0"
-     width="450">
+     right="-1"
+     top="0">
         <layout_panel
          auto_resize="false"
          user_resize="true"        
-         height="430"
          name="conversations_layout_panel"
          min_dim="38"
-         width="268"
-         expanded_min_dim="120">
+         width="225"
+         expanded_min_dim="200">
             <layout_stack
              animate="false" 
              follows="left|top|right"
@@ -48,8 +47,8 @@
              left="0"
              name="conversations_pane_buttons_stack"
              orientation="horizontal"
-             top="0"
-             width="268">
+             right="-1"
+             top="0">
                 <layout_panel
                  auto_resize="true"
                  height="35"
@@ -123,32 +122,30 @@
              top_pad="0"
              left="5"
              height="390"
-             width="263"/>
+             right="-1"/>
         </layout_panel>
         <layout_panel
          auto_resize="true"
          user_resize="true"
-         height="430"
          name="messages_layout_panel"
-         width="412"
          expanded_min_dim="225">
             <panel_container
+             bottom="-1"
              follows="all"
-             height="430"
              layout="topleft"
              left="0"
              name="im_box_tab_container"
-             top="0"
-             width="412">
+             right="-1"
+             top="0">
              <panel
+               bottom="-1"
                follows="all"
                layout="topleft"
                name="stub_panel"
                opaque="true"
                top_pad="0"
                left="0"
-               height="430"
-               width="412">
+               right="-1">
                  <button
                  follows="right|top"
                  height="25"
-- 
cgit v1.2.3


From ed52792396c76ead787207b7a7dc3968f4352a1d Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Mon, 17 Dec 2012 15:38:03 +0200
Subject: CHUI-593 FIXED Using callback signal will update Speak button if
 voice chat disabled

---
 indra/newview/llvoiceclient.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index dd529d74e9..b46c55321c 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -541,6 +541,7 @@ void LLVoiceClient::setMuteMic(bool muted)
 {
 	mMuteMic = muted;
 	updateMicMuteLogic();
+	mMicroChangedSignal();
 }
 
 
-- 
cgit v1.2.3


From b4d4fc902ba4d289326c6839e8a2a3e4fb1630e9 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Mon, 17 Dec 2012 15:06:38 -0800
Subject: CHUI-115: Removing code that is ifdef'ed out.

---
 indra/newview/llhudobject.cpp       |  2 --
 indra/newview/llhudobject.h         |  4 ----
 indra/newview/llvoavatar.cpp        | 16 ----------------
 indra/newview/llvoicevisualizer.cpp | 32 --------------------------------
 indra/newview/llvoicevisualizer.h   | 27 ---------------------------
 5 files changed, 81 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 0960846510..95d57d08d8 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -232,11 +232,9 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type)
 	case LL_HUD_EFFECT_LOOKAT:
 		hud_objectp = new LLHUDEffectLookAt(type);
 		break;
-#ifdef XXX_STINSON_CHUI_REWORK
 	case LL_HUD_EFFECT_VOICE_VISUALIZER:
 		hud_objectp = new LLVoiceVisualizer(type);
 		break;
-#endif // XXX_STINSON_CHUI_REWORK
 	case LL_HUD_EFFECT_POINTAT:
 		hud_objectp = new LLHUDEffectPointAt(type);
 		break;
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 32cffe6839..2f7a98c86c 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -39,8 +39,6 @@
 #include "lldrawpool.h"		// TODO: eliminate, unused below
 #include <list>
 
-#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
-
 class LLViewerCamera;
 class LLFontGL;
 class LLFace;
@@ -96,9 +94,7 @@ public:
 		LL_HUD_EFFECT_EDIT,
 		LL_HUD_EFFECT_LOOKAT,
 		LL_HUD_EFFECT_POINTAT,
-#ifdef XXX_STINSON_CHUI_REWORK
 		LL_HUD_EFFECT_VOICE_VISUALIZER,	// Ventrella
-#endif // XXX_STINSON_CHUI_REWORK
 		LL_HUD_NAME_TAG,
 		LL_HUD_EFFECT_BLOB
 	};
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 7cc4e3ed04..19c7eda717 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -34,8 +34,6 @@
 
 #include "llvoavatar.h"
 
-#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
-
 #include <stdio.h>
 #include <ctype.h>
 
@@ -711,13 +709,9 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
 	//VTResume();  // VTune
 	
-#ifdef XXX_STINSON_CHUI_REWORK
 	// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
 	const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
 	mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
-#else // XXX_STINSON_CHUI_REWORK
-	mVoiceVisualizer = new LLVoiceVisualizer();
-#endif // XXX_STINSON_CHUI_REWORK
 
 	lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl;
 
@@ -893,11 +887,7 @@ void LLVOAvatar::markDead()
 		mNameText = NULL;
 		sNumVisibleChatBubbles--;
 	}
-#ifdef XXX_STINSON_CHUI_REWORK
 	mVoiceVisualizer->markDead();
-#else // XXX_STINSON_CHUI_REWORK
-	mVoiceVisualizer->setStopSpeaking();
-#endif // XXX_STINSON_CHUI_REWORK
 	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
 	LLViewerObject::markDead();
 }
@@ -1429,9 +1419,7 @@ void LLVOAvatar::initInstance(void)
 	
 	//VTPause();  // VTune
 	
-#ifdef XXX_STINSON_CHUI_REWORK
 	mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
-#endif // XXX_STINSON_CHUI_REWORK
 
 }
 
@@ -2529,7 +2517,6 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 
 void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 {
-#ifdef XXX_STINSON_CHUI_REWORK
 	bool render_visualizer = voice_enabled;
 	
 	// Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
@@ -2542,7 +2529,6 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 	}
 	
 	mVoiceVisualizer->setVoiceEnabled(render_visualizer);
-#endif // XXX_STINSON_CHUI_REWORK
 	
 	if ( voice_enabled )
 	{		
@@ -2618,7 +2604,6 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 			}
 		}
 		
-#ifdef XXX_STINSON_CHUI_REWORK
 		//--------------------------------------------------------------------------------------------
 		// here we get the approximate head position and set as sound source for the voice symbol
 		// (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
@@ -2636,7 +2621,6 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 			tagPos[VZ] += ( mBodySize[VZ] + 0.125f );
 			mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );
 		}
-#endif // XXX_STINSON_CHUI_REWORK
 	}//if ( voiceEnabled )
 }		
 
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index d380a8672f..b497f80560 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -45,7 +45,6 @@
 //29de489d-0491-fb00-7dab-f9e686d31e83
 
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //--------------------------------------------------------------------------------------
 // sound symbol constants
 //--------------------------------------------------------------------------------------
@@ -61,7 +60,6 @@ const F32	BASE_BRIGHTNESS		= 0.7f;		// gray level of the voice indicator when qu
 const F32	DOT_SIZE			= 0.05f;	// size of the dot billboard texture
 const F32	DOT_OPACITY			= 0.7f;		// how opaque the dot is
 const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a function of speaking amplitude
-#endif // XXX_STINSON_CHUI_REWORK
 
 //--------------------------------------------------------------------------------------
 // gesticulation constants
@@ -69,13 +67,11 @@ const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a
 const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE	= 0.2f; 
 const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f;
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //--------------------------------------------------------------------------------------
 // other constants
 //--------------------------------------------------------------------------------------
 const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. 
 const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
-#endif // XXX_STINSON_CHUI_REWORK
 
 //------------------------------------------------------------------
 // Initialize the statics
@@ -98,28 +94,12 @@ F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
 //-----------------------------------------------
 // constructor
 //-----------------------------------------------
-#ifdef XXX_STINSON_CHUI_REWORK
 LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
 	: LLHUDEffect(type)
-#else // XXX_STINSON_CHUI_REWORK
-LLVoiceVisualizer::LLVoiceVisualizer()
-	: LLRefCount(),
-	mTimer(),
-	mStartTime(0.0),
-	mCurrentlySpeaking(false),
-	mSpeakingAmplitude(0.0f),
-	mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE),
-	mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE)
-#endif // XXX_STINSON_CHUI_REWORK
 {
-#ifdef XXX_STINSON_CHUI_REWORK
 	mCurrentTime					= mTimer.getTotalSeconds();
 	mPreviousTime					= mCurrentTime;
 	mStartTime						= mCurrentTime;
-#else // XXX_STINSON_CHUI_REWORK
-	mStartTime						= mTimer.getTotalSeconds();
-#endif // XXX_STINSON_CHUI_REWORK
-#ifdef XXX_STINSON_CHUI_REWORK
 	mVoiceSourceWorldPosition		= LLVector3( 0.0f, 0.0f, 0.0f );
 	mSpeakingAmplitude				= 0.0f;
 	mCurrentlySpeaking				= false;
@@ -128,11 +108,9 @@ LLVoiceVisualizer::LLVoiceVisualizer()
 	mMaxGesticulationAmplitude		= DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
 	mSoundSymbol.mActive			= true;
 	mSoundSymbol.mPosition			= LLVector3( 0.0f, 0.0f, 0.0f );
-#endif // XXX_STINSON_CHUI_REWORK
 	
 	mTimer.reset();
 	
-#ifdef XXX_STINSON_CHUI_REWORK
 	const char* sound_level_img[] = 
 	{
 		"voice_meter_dot.j2c",
@@ -154,7 +132,6 @@ LLVoiceVisualizer::LLVoiceVisualizer()
 	}
 
 	mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-#endif // XXX_STINSON_CHUI_REWORK
 
 	// The first instance loads the initial state from prefs.
 	if (!sPrefsInitialized)
@@ -174,7 +151,6 @@ LLVoiceVisualizer::LLVoiceVisualizer()
 
 }//---------------------------------------------------
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //---------------------------------------------------
 void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
 {
@@ -195,16 +171,13 @@ void LLVoiceVisualizer::setVoiceEnabled( bool v )
 	mVoiceEnabled = v;
 
 }//---------------------------------------------------
-#endif // XXX_STINSON_CHUI_REWORK
 
 //---------------------------------------------------
 void LLVoiceVisualizer::setStartSpeaking()
 {
 	mStartTime				= mTimer.getTotalSeconds();
 	mCurrentlySpeaking		= true;
-#ifdef XXX_STINSON_CHUI_REWORK
 	mSoundSymbol.mActive	= true;
-#endif // XXX_STINSON_CHUI_REWORK
 		
 }//---------------------------------------------------
 
@@ -359,7 +332,6 @@ void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
 }//---------------------------------------------------
 
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //---------------------------------------------------
 // this method is inherited from HUD Effect
 //---------------------------------------------------
@@ -558,7 +530,6 @@ void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
 	mVoiceSourceWorldPosition	= p;
 
 }//---------------------------------------------------
-#endif // XXX_STINSON_CHUI_REWORK
 
 //---------------------------------------------------
 VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
@@ -589,7 +560,6 @@ LLVoiceVisualizer::~LLVoiceVisualizer()
 }//----------------------------------------------
 
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //---------------------------------------------------
 // "packData" is inherited from HUDEffect
 //---------------------------------------------------
@@ -639,5 +609,3 @@ void LLVoiceVisualizer::markDead()
 
 	LLHUDEffect::markDead();
 }//------------------------------------------------------------------
-
-#endif // XXX_STINSON_CHUI_REWORK
diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h
index 5da592c48e..36c78252d1 100644
--- a/indra/newview/llvoicevisualizer.h
+++ b/indra/newview/llvoicevisualizer.h
@@ -42,12 +42,7 @@
 #ifndef LL_VOICE_VISUALIZER_H
 #define LL_VOICE_VISUALIZER_H
 
-#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
-#ifdef XXX_STINSON_CHUI_REWORK
 #include "llhudeffect.h"
-#else // XXX_STINSON_CHUI_REWORK
-#include "llpointer.h"
-#endif // XXX_STINSON_CHUI_REWORK
 
 //-----------------------------------------------------------------------------------------------
 // The values of voice gesticulation represent energy levels for avatar animation, based on 
@@ -65,45 +60,30 @@ enum VoiceGesticulationLevel
 	NUM_VOICE_GESTICULATION_LEVELS
 };
 
-#ifdef XXX_STINSON_CHUI_REWORK
 const static int NUM_VOICE_SYMBOL_WAVES = 7;
-#endif // XXX_STINSON_CHUI_REWORK
 
 //----------------------------------------------------
 // LLVoiceVisualizer class 
 //----------------------------------------------------
-#ifdef XXX_STINSON_CHUI_REWORK
 class LLVoiceVisualizer : public LLHUDEffect
-#else // XXX_STINSON_CHUI_REWORK
-class LLVoiceVisualizer : public LLRefCount
-#endif // XXX_STINSON_CHUI_REWORK
 {
 	//---------------------------------------------------
 	// public methods 
 	//---------------------------------------------------
 	public:
-#ifdef XXX_STINSON_CHUI_REWORK
 		LLVoiceVisualizer( const U8 type );	//constructor
-#else // XXX_STINSON_CHUI_REWORK
-		LLVoiceVisualizer();	//constructor
-#endif // XXX_STINSON_CHUI_REWORK
 		~LLVoiceVisualizer();					//destructor
 
-#ifdef XXX_STINSON_CHUI_REWORK
 		void					setVoiceSourceWorldPosition( const LLVector3 &p );		// this should be the position of the speaking avatar's head
 		void					setMinGesticulationAmplitude( F32 );					// the lower range of meaningful amplitude for setting gesticulation level 
 		void					setMaxGesticulationAmplitude( F32 );					// the upper range of meaningful amplitude for setting gesticulation level 
-#endif // XXX_STINSON_CHUI_REWORK
 		void					setStartSpeaking();										// tell me when the av starts speaking
-#ifdef XXX_STINSON_CHUI_REWORK
 		void					setVoiceEnabled( bool );								// tell me whether or not the user is voice enabled
-#endif // XXX_STINSON_CHUI_REWORK
 		void					setSpeakingAmplitude( F32 );							// tell me how loud the av is speaking (ranges from 0 to 1)
 		void					setStopSpeaking();										// tell me when the av stops speaking
 		bool					getCurrentlySpeaking();									// the get for the above set
 		VoiceGesticulationLevel	getCurrentGesticulationLevel();							// based on voice amplitude, I'll give you the current "energy level" of avatar speech
 		void					lipSyncOohAah( F32& ooh, F32& aah );
-#ifdef XXX_STINSON_CHUI_REWORK
 		void					render();												// inherited from HUD Effect
 		void 					packData(LLMessageSystem *mesgsys);						// inherited from HUD Effect
 		void 					unpackData(LLMessageSystem *mesgsys, S32 blocknum);		// inherited from HUD Effect
@@ -119,7 +99,6 @@ class LLVoiceVisualizer : public LLRefCount
 		//----------------------------------------------------------------------------------------------
 		void setMaxGesticulationAmplitude(); 
 		void setMinGesticulationAmplitude(); 
-#endif // XXX_STINSON_CHUI_REWORK
 
 	//---------------------------------------------------
 	// private members 
@@ -129,7 +108,6 @@ class LLVoiceVisualizer : public LLRefCount
 		static void				setPreferences( );
 		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
 
-#ifdef XXX_STINSON_CHUI_REWORK
 		struct SoundSymbol
 		{
 			F32						mWaveExpansion			[ NUM_VOICE_SYMBOL_WAVES ];
@@ -140,20 +118,15 @@ class LLVoiceVisualizer : public LLRefCount
 			bool					mActive;
 			LLVector3				mPosition;
 		};
-#endif // XXX_STINSON_CHUI_REWORK
 
 		LLFrameTimer			mTimer;							// so I can ask the current time in seconds
 		F64						mStartTime;						// time in seconds when speaking started
-#ifdef XXX_STINSON_CHUI_REWORK
 		F64						mCurrentTime;					// current time in seconds, captured every step
 		F64						mPreviousTime;					// copy of "current time" from last frame
 		SoundSymbol				mSoundSymbol;					// the sound symbol that appears over the avatar's head
 		bool					mVoiceEnabled;					// if off, no rendering should happen
-#endif // XXX_STINSON_CHUI_REWORK
 		bool					mCurrentlySpeaking;				// is the user currently speaking?
-#ifdef XXX_STINSON_CHUI_REWORK
 		LLVector3				mVoiceSourceWorldPosition;		// give this to me every step - I need it to update the sound symbol
-#endif // XXX_STINSON_CHUI_REWORK
 		F32						mSpeakingAmplitude;				// this should be set as often as possible when the user is speaking
 		F32						mMaxGesticulationAmplitude;		// this is the upper-limit of the envelope of detectable gesticulation leves
 		F32						mMinGesticulationAmplitude;		// this is the lower-limit of the envelope of detectable gesticulation leves
-- 
cgit v1.2.3


From 1bebff84ba56b2ecfc0d24b4246fa417f12c66b6 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Mon, 17 Dec 2012 16:11:52 -0800
Subject: Removing some old code for parsing the response from changing
 maturity level as it is now consistent across the grid.

---
 indra/newview/llagent.cpp | 58 ++++++++++++-----------------------------------
 1 file changed, 14 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 22a21ffaeb..49c570c30b 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -2541,51 +2541,21 @@ void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReas
 
 U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
 {
-	// stinson 05/24/2012 Pathfinding regions have re-defined the response behavior.  In the old server code,
-	// if you attempted to change the preferred maturity to the same value, the response content would be an
-	// undefined LLSD block.  In the new server code with pathfinding, the response content should always be
-	// defined.  Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged
-	// into server trunk and fully deployed.
 	U8 maturity = SIM_ACCESS_MIN;
-	if (pContent.isUndefined())
-	{
-		maturity = mPreferredMaturity;
-	}
-	else
-	{
-		llassert(!pContent.isUndefined());
-		llassert(pContent.isMap());
-	
-		if (!pContent.isUndefined() && pContent.isMap())
-		{
-			// stinson 05/24/2012 Pathfinding regions have re-defined the response syntax.  The if statement catches
-			// the new syntax, and the else statement catches the old syntax.  After pathfinding is merged into
-			// server trunk and fully deployed, we can remove the else statement.
-			if (pContent.has("access_prefs"))
-			{
-				llassert(pContent.has("access_prefs"));
-				llassert(pContent.get("access_prefs").isMap());
-				llassert(pContent.get("access_prefs").has("max"));
-				llassert(pContent.get("access_prefs").get("max").isString());
-				if (pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") &&
-					pContent.get("access_prefs").get("max").isString())
-				{
-					LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
-					LLStringUtil::trim(actualPreference);
-					maturity = LLViewerRegion::shortStringToAccess(actualPreference);
-				}
-			}
-			else if (pContent.has("max"))
-			{
-				llassert(pContent.get("max").isString());
-				if (pContent.get("max").isString())
-				{
-					LLSD::String actualPreference = pContent.get("max").asString();
-					LLStringUtil::trim(actualPreference);
-					maturity = LLViewerRegion::shortStringToAccess(actualPreference);
-				}
-			}
-		}
+
+	llassert(!pContent.isUndefined());
+	llassert(pContent.isMap());
+	llassert(pContent.has("access_prefs"));
+	llassert(pContent.get("access_prefs").isMap());
+	llassert(pContent.get("access_prefs").has("max"));
+	llassert(pContent.get("access_prefs").get("max").isString());
+	if (!pContent.isUndefined() && pContent.isMap() && pContent.has("access_prefs")
+		&& pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max")
+		&& pContent.get("access_prefs").get("max").isString())
+	{
+		LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
+		LLStringUtil::trim(actualPreference);
+		maturity = LLViewerRegion::shortStringToAccess(actualPreference);
 	}
 
 	return maturity;
-- 
cgit v1.2.3


From 138d4f5fcd4567c5d77230b6eadc21c246ceed59 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Mon, 17 Dec 2012 16:15:28 -0800
Subject: Updating a comment.

---
 indra/newview/llflexibleobject.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index aae0990e4b..c2b9c77307 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -444,7 +444,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
 		return ;
 	}
 
-	// stinson 11/12/2012: Need to check with davep on the following.
+	// Fix for MAINT-1894
 	// Skipping the flexible update if render res is negative.  If we were to continue with a negative value,
 	// the subsequent S32 num_render_sections = 1<<mRenderRes; code will specify a really large number of
 	// render sections which will then create a length exception in the std::vector::resize() method.
-- 
cgit v1.2.3


From 6fe7144104cd8b5bd9c7d215f76afdeafe13b7ee Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 17 Dec 2012 18:59:01 -0800
Subject: CHUI-580 : WIP : Protect callback connections passed to
 LLAvatarNameCache::get() where necessary

---
 indra/llui/llnotifications.cpp         | 12 +++++-------
 indra/llui/llscrolllistctrl.cpp        |  1 +
 indra/llui/llurlentry.cpp              | 22 ++++++++++++++--------
 indra/llui/llurlentry.h                | 16 ++++++++++++++++
 indra/newview/llavataractions.cpp      |  8 +++-----
 indra/newview/llavatariconctrl.cpp     |  9 ++++-----
 indra/newview/llavatarlistitem.cpp     |  9 ++++-----
 indra/newview/llcallingcard.cpp        |  4 +---
 indra/newview/llchathistory.cpp        |  9 ++++-----
 indra/newview/llconversationlog.cpp    |  9 +++++++--
 indra/newview/llconversationlog.h      | 10 +++++++++-
 indra/newview/llconversationmodel.cpp  | 11 +++++------
 indra/newview/llfloaterdisplayname.cpp | 10 +++-------
 indra/newview/llfloaterinspect.cpp     | 34 +++++++++++++++++++++-------------
 indra/newview/llfloaterinspect.h       |  7 +++----
 indra/newview/llfloaterreporter.cpp    | 14 ++++++++++++--
 indra/newview/llfloaterreporter.h      |  1 +
 indra/newview/llfloatersellland.cpp    | 15 ++++++++++++---
 indra/newview/llfloatervoicevolume.cpp | 13 +++++++++++--
 indra/newview/llimview.cpp             | 23 +++++++++++++++--------
 indra/newview/llimview.h               | 12 +++++++++++-
 indra/newview/llinspectavatar.cpp      | 16 ++++++++++++----
 indra/newview/llinventorybridge.cpp    |  4 +---
 indra/newview/llnamelistctrl.cpp       | 13 +++++++++----
 indra/newview/llnamelistctrl.h         |  8 ++++++++
 indra/newview/llpanelgroupgeneral.cpp  | 19 +++++++++++++------
 indra/newview/llpanelgroupgeneral.h    |  1 +
 indra/newview/llpanelgroupinvite.cpp   | 32 +++++++++++++++++++++++++++-----
 indra/newview/llpanelgrouproles.cpp    | 15 ++++++++++++---
 indra/newview/llpanelgrouproles.h      |  1 +
 indra/newview/llpanelplaceprofile.cpp  | 23 ++++++++++++++++-------
 indra/newview/llpanelplaceprofile.h    |  4 +++-
 indra/newview/llpathfindingobject.cpp  |  1 +
 indra/newview/lltoolpie.cpp            | 20 ++------------------
 indra/newview/llviewerdisplayname.cpp  |  7 ++++---
 indra/newview/llviewermessage.cpp      | 19 ++++++-------------
 indra/newview/llvoavatar.cpp           |  5 +++--
 indra/newview/llvoicevivox.cpp         | 16 ++++++++++++----
 indra/newview/llvoicevivox.h           |  1 +
 39 files changed, 294 insertions(+), 160 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index fd9bfec203..6b00225605 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1814,15 +1814,13 @@ void LLPostponedNotification::onGroupNameCache(const LLUUID& id,
 
 void LLPostponedNotification::fetchAvatarName(const LLUUID& id)
 {
-	if (mAvatarNameCacheConnection.connected())
-	{
-		mAvatarNameCacheConnection.disconnect();
-	}
-
 	if (id.notNull())
 	{
-		mAvatarNameCacheConnection = LLAvatarNameCache::get(id,
-			boost::bind(&LLPostponedNotification::onAvatarNameCache, this, _1, _2));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLPostponedNotification::onAvatarNameCache, this, _1, _2));
 	}
 }
 
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 7ed7042aff..26aadd056f 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1832,6 +1832,7 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
 	{
 		LLAvatarName av_name;
 		LLAvatarNameCache::get(LLUUID(id), &av_name);
+		// Note: Will return an empty string if the avatar name was not cached for that id. Fine in that case.
 		name = av_name.getUserName();
 	}
 	LLUrlAction::copyURLToClipboard(name);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index fd2635c73a..71db238c94 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -340,7 +340,8 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
 // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
 //
-LLUrlEntryAgent::LLUrlEntryAgent()
+LLUrlEntryAgent::LLUrlEntryAgent() :
+	mAvatarNameCacheConnection()
 {
 	mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+",
 							boost::regex::perl|boost::regex::icase);
@@ -456,9 +457,11 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
 	}
 	else
 	{
-		LLAvatarNameCache::get(agent_id,
-			boost::bind(&LLUrlEntryAgent::onAvatarNameCache,
-				this, _1, _2));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2));
 		addObserver(agent_id_string, url, cb);
 		return LLTrans::getString("LoadingData");
 	}
@@ -515,7 +518,8 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
 // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
 //
-LLUrlEntryAgentName::LLUrlEntryAgentName()
+LLUrlEntryAgentName::LLUrlEntryAgentName() :
+	mAvatarNameCacheConnection()
 {}
 
 void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
@@ -554,9 +558,11 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab
 	}
 	else
 	{
-		LLAvatarNameCache::get(agent_id,
-			boost::bind(&LLUrlEntryAgentCompleteName::onAvatarNameCache,
-				this, _1, _2));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentCompleteName::onAvatarNameCache, this, _1, _2));
 		addObserver(agent_id_string, url, cb);
 		return LLTrans::getString("LoadingData");
 	}
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 5f82721c0f..8c6c32178a 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -171,6 +171,13 @@ class LLUrlEntryAgent : public LLUrlEntryBase
 {
 public:
 	LLUrlEntryAgent();
+	~LLUrlEntryAgent()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
 	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
 	/*virtual*/ std::string getIcon(const std::string &url);
 	/*virtual*/ std::string getTooltip(const std::string &string) const;
@@ -181,6 +188,7 @@ protected:
 	/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
 private:
 	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 ///
@@ -192,6 +200,13 @@ class LLUrlEntryAgentName : public LLUrlEntryBase, public boost::signals2::track
 {
 public:
 	LLUrlEntryAgentName();
+	~LLUrlEntryAgentName()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
 	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
 	/*virtual*/ LLStyle::Params getStyle() const;
 protected:
@@ -199,6 +214,7 @@ protected:
 	virtual std::string getName(const LLAvatarName& avatar_name) = 0;
 private:
 	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 59b862503c..5a185c9571 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -94,7 +94,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin
 	LLRecentPeople::instance().add(id);
 }
 
-void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name)
+static void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name)
 {
 	LLAvatarActions::requestFriendshipDialog(id, av_name.getCompleteName());
 }
@@ -195,8 +195,7 @@ void LLAvatarActions::startIM(const LLUUID& id)
 	if (id.isNull())
 		return;
 
-	LLAvatarNameCache::get(id,
-		boost::bind(&on_avatar_name_cache_start_im, _1, _2));
+	LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_im, _1, _2));
 }
 
 // static
@@ -231,8 +230,7 @@ void LLAvatarActions::startCall(const LLUUID& id)
 	{
 		return;
 	}
-	LLAvatarNameCache::get(id,
-		boost::bind(&on_avatar_name_cache_start_call, _1, _2));
+	LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_call, _1, _2));
 }
 
 // static
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 0db38c947c..60a2c14911 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -261,13 +261,12 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
 
 void LLAvatarIconCtrl::fetchAvatarName()
 {
-	if (mAvatarNameCacheConnection.connected())
-	{
-		mAvatarNameCacheConnection.disconnect();
-	}
-
 	if (mAvatarId.notNull())
 	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
 		mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, this, _1, _2));
 	}
 }
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 84e177d4a4..b4a70008e7 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -143,13 +143,12 @@ BOOL  LLAvatarListItem::postBuild()
 
 void LLAvatarListItem::fetchAvatarName()
 {
-	if (mAvatarNameCacheConnection.connected())
-	{
-		mAvatarNameCacheConnection.disconnect();
-	}
-
 	if (mAvatarId.notNull())
 	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
 		mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
 	}
 }
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 9a295faa73..30306b230f 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -704,9 +704,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
 		if(chat_notify)
 		{
 			// Look up the name of this agent for the notification
-			LLAvatarNameCache::get(agent_id,
-				boost::bind(&on_avatar_name_cache_notify,
-					_1, _2, online, payload));
+			LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload));
 		}
 
 		mModifyMask |= LLFriendObserver::ONLINE;
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 3e25d9c457..764ee4a8ea 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -539,13 +539,12 @@ private:
 
 	void fetchAvatarName()
 	{
-		if (mAvatarNameCacheConnection.connected())
-		{
-			mAvatarNameCacheConnection.disconnect();
-		}
-		
 		if (mAvatarID.notNull())
 		{
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
 			mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID,
 				boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2));
 		}
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index a0765f5e16..f8ccb08e66 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -185,7 +185,8 @@ void LLConversationLogFriendObserver::changed(U32 mask)
 /*             LLConversationLog implementation                         */
 /************************************************************************/
 
-LLConversationLog::LLConversationLog()
+LLConversationLog::LLConversationLog() :
+	mAvatarNameCacheConnection()
 {
 	LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
 	if (ctrl)
@@ -251,7 +252,11 @@ void LLConversationLog::createConversation(const LLIMModel::LLIMSession* session
 
 		if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType)
 		{
-			LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session));
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session));
 		}
 
 		notifyObservers();
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 8f6ac3f5d1..35462ec3a4 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -141,7 +141,14 @@ public:
 private:
 
 	LLConversationLog();
-
+	virtual ~LLConversationLog()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
+	
 	void enableLogging(bool enable);
 
 	/**
@@ -176,6 +183,7 @@ private:
 	LLFriendObserver* mFriendObserver;		// Observer of the LLAvatarTracker instance
 
 	boost::signals2::connection newMessageSignalConnection;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 class LLConversationLogObserver
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index d03ad92fbc..ef9e0e02e5 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -421,16 +421,15 @@ LLConversationItemParticipant::~LLConversationItemParticipant()
 
 void LLConversationItemParticipant::fetchAvatarName()
 {
-	// Disconnect any previous avatar name cache connection
-	if (mAvatarNameCacheConnection.connected())
-	{
-		mAvatarNameCacheConnection.disconnect();
-	}
-
 	// Request the avatar name from the cache
 	llassert(getUUID().notNull());
 	if (getUUID().notNull())
 	{
+		// Disconnect any previous avatar name cache connection
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
 		mAvatarNameCacheConnection = LLAvatarNameCache::get(getUUID(), boost::bind(&LLConversationItemParticipant::onAvatarNameCache, this, _2));
 	}
 }
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
index be1ee77152..e2cef5630b 100644
--- a/indra/newview/llfloaterdisplayname.cpp
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -44,7 +44,7 @@ class LLFloaterDisplayName : public LLFloater
 {
 public:
 	LLFloaterDisplayName(const LLSD& key);
-	virtual ~LLFloaterDisplayName() {};
+	virtual ~LLFloaterDisplayName() { }
 	/*virtual*/	BOOL	postBuild();
 	void onSave();
 	void onReset();
@@ -58,8 +58,8 @@ private:
 										  const LLSD& content);
 };
 
-LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key)
-	: LLFloater(key)
+LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
+	LLFloater(key)
 {
 }
 
@@ -122,10 +122,6 @@ void LLFloaterDisplayName::onCacheSetName(bool success,
 		LLSD args;
 		args["DISPLAY_NAME"] = content["display_name"];
 		LLNotificationsUtil::add("SetDisplayNameSuccess", args);
-
-		// Re-fetch my name, as it may have been sanitized by the service
-		//LLAvatarNameCache::get(getAvatarId(),
-		//	boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2));
 		return;
 	}
 
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index cece8d299c..3636bba355 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -46,7 +46,9 @@
 
 LLFloaterInspect::LLFloaterInspect(const LLSD& key)
   : LLFloater(key),
-	mDirty(FALSE)
+	mDirty(FALSE),
+	mOwnerNameCacheConnection(),
+	mCreatorNameCacheConnection()
 {
 	mCommitCallbackRegistrar.add("Inspect.OwnerProfile",	boost::bind(&LLFloaterInspect::onClickOwnerProfile, this));
 	mCommitCallbackRegistrar.add("Inspect.CreatorProfile",	boost::bind(&LLFloaterInspect::onClickCreatorProfile, this));
@@ -67,6 +69,14 @@ BOOL LLFloaterInspect::postBuild()
 
 LLFloaterInspect::~LLFloaterInspect(void)
 {
+	if (mOwnerNameCacheConnection.connected())
+	{
+		mOwnerNameCacheConnection.disconnect();
+	}
+	if (mCreatorNameCacheConnection.connected())
+	{
+		mCreatorNameCacheConnection.disconnect();
+	}
 	if(!LLFloaterReg::instanceVisible("build"))
 	{
 		if(LLToolMgr::getInstance()->getBaseTool() == LLToolCompInspect::getInstance())
@@ -80,7 +90,6 @@ LLFloaterInspect::~LLFloaterInspect(void)
 	{
 		LLFloaterReg::showInstance("build", LLSD(), TRUE);
 	}
-	//sInstance = NULL;
 }
 
 void LLFloaterInspect::onOpen(const LLSD& key)
@@ -167,15 +176,6 @@ LLUUID LLFloaterInspect::getSelectedUUID()
 	return LLUUID::null;
 }
 
-void LLFloaterInspect::onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr)
-{
-	if (FloaterPtr)
-	{
-		LLFloaterInspect* floater = (LLFloaterInspect*)FloaterPtr;
-		floater->dirty();
-	}
-}
-
 void LLFloaterInspect::refresh()
 {
 	LLUUID creator_id;
@@ -229,7 +229,11 @@ void LLFloaterInspect::refresh()
 		else
 		{
 			owner_name = LLTrans::getString("RetrievingData");
-			LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this));
+			if (mOwnerNameCacheConnection.connected())
+			{
+				mOwnerNameCacheConnection.disconnect();
+			}
+			mOwnerNameCacheConnection = LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::setDirty, this));
 		}
 
 		if (LLAvatarNameCache::get(idCreator, &av_name))
@@ -239,7 +243,11 @@ void LLFloaterInspect::refresh()
 		else
 		{
 			creator_name = LLTrans::getString("RetrievingData");
-			LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this));
+			if (mCreatorNameCacheConnection.connected())
+			{
+				mCreatorNameCacheConnection.disconnect();
+			}
+			mCreatorNameCacheConnection = LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::setDirty, this));
 		}
 		
 		row["id"] = obj->getObject()->getID();
diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h
index 7ee83ccdb4..495f8f0a39 100644
--- a/indra/newview/llfloaterinspect.h
+++ b/indra/newview/llfloaterinspect.h
@@ -55,8 +55,6 @@ public:
 	void onClickOwnerProfile();
 	void onSelectObject();
 
-	static void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr);
-
 	LLScrollListCtrl* mObjectList;
 protected:
 	// protected members
@@ -64,13 +62,14 @@ protected:
 	bool mDirty;
 
 private:
+	void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name);
 	
 	LLFloaterInspect(const LLSD& key);
 	virtual ~LLFloaterInspect(void);
-	// static data
-//	static LLFloaterInspect* sInstance;
 
 	LLSafeHandle<LLObjectSelection> mObjectSelection;
+	boost::signals2::connection mOwnerNameCacheConnection;
+	boost::signals2::connection mCreatorNameCacheConnection;
 };
 
 #endif //LL_LLFLOATERINSPECT_H
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index cf2481f99a..79387747a5 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -103,7 +103,8 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key)
 	mPicking( FALSE), 
 	mPosition(),
 	mCopyrightWarningSeen( FALSE ),
-	mResourceDatap(new LLResourceData())
+	mResourceDatap(new LLResourceData()),
+	mAvatarNameCacheConnection()
 {
 }
 
@@ -187,6 +188,11 @@ BOOL LLFloaterReporter::postBuild()
 // virtual
 LLFloaterReporter::~LLFloaterReporter()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
 	// child views automatically deleted
 	mObjectID 		= LLUUID::null;
 
@@ -313,7 +319,11 @@ void LLFloaterReporter::setFromAvatarID(const LLUUID& avatar_id)
 	std::string avatar_link = LLSLURL("agent", mObjectID, "inspect").getSLURLString();
 	getChild<LLUICtrl>("owner_name")->setValue(avatar_link);
 
-	LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2));
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	mAvatarNameCacheConnection = LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2));
 }
 
 void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name)
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index 7d68431710..d54e7f6ab0 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -137,6 +137,7 @@ private:
 	std::list<LLMeanCollisionData*> mMCDList;
 	std::string		mDefaultSummary;
 	LLResourceData* mResourceDatap;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 #endif
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index c97a6792f3..ec13a6ff1d 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -81,6 +81,7 @@ private:
 	LLUUID					mAuthorizedBuyer;
 	bool					mParcelSoldWithObjects;
 	SelectionObserver 		mParcelSelectionObserver;
+	boost::signals2::connection mAvatarNameCacheConnection;
 	
 	void updateParcelInfo();
 	void refreshUI();
@@ -129,13 +130,18 @@ LLFloater* LLFloaterSellLand::buildFloater(const LLSD& key)
 LLFloaterSellLandUI::LLFloaterSellLandUI(const LLSD& key)
 :	LLFloater(key),
 	mParcelSelectionObserver(this),
-	mRegion(0)
+	mRegion(0),
+	mAvatarNameCacheConnection()
 {
 	LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver);
 }
 
 LLFloaterSellLandUI::~LLFloaterSellLandUI()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 	LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver);
 }
 
@@ -230,8 +236,11 @@ void LLFloaterSellLandUI::updateParcelInfo()
 
 	if(mSellToBuyer)
 	{
-		LLAvatarNameCache::get(mAuthorizedBuyer, 
-			boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(mAuthorizedBuyer, boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2));
 	}
 }
 
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
index a1df73a065..82d366a48e 100644
--- a/indra/newview/llfloatervoicevolume.cpp
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -81,12 +81,14 @@ private:
 	LLUUID				mAvatarID;
 	// Need avatar name information to spawn friend add request
 	LLAvatarName		mAvatarName;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 LLFloaterVoiceVolume::LLFloaterVoiceVolume(const LLSD& sd)
 :	LLInspect(LLSD())		// single_instance, doesn't really need key
 ,	mAvatarID()				// set in onOpen()  *Note: we used to show partner's name but we dont anymore --angela 3rd Dec*
 ,	mAvatarName()
+,   mAvatarNameCacheConnection()
 {
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
 	LLTransientFloater::init(this);
@@ -94,6 +96,10 @@ LLFloaterVoiceVolume::LLFloaterVoiceVolume(const LLSD& sd)
 
 LLFloaterVoiceVolume::~LLFloaterVoiceVolume()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 	LLTransientFloaterMgr::getInstance()->removeControlView(this);
 }
 
@@ -126,8 +132,11 @@ void LLFloaterVoiceVolume::onOpen(const LLSD& data)
 	getChild<LLUICtrl>("avatar_name")->setValue("");
 	updateVolumeControls();
 
-	LLAvatarNameCache::get(mAvatarID,
-		boost::bind(&LLFloaterVoiceVolume::onAvatarNameCache, this, _1, _2));
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterVoiceVolume::onAvatarNameCache, this, _1, _2));
 }
 
 void LLFloaterVoiceVolume::updateVolumeControls()
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 4e2ac09dd8..d3569694f1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -253,7 +253,8 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 	mTextIMPossible(true),
 	mOtherParticipantIsAvatar(true),
 	mStartCallOnInitialize(false),
-	mStartedAsIMCall(voice)
+	mStartedAsIMCall(voice),
+	mAvatarNameCacheConnection()
 {
 	// set P2P type by default
 	mSessionType = P2P_SESSION;
@@ -334,9 +335,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 	// history files have consistent (English) names in different locales.
 	if (isAdHocSessionType() && IM_SESSION_INVITE == mType)
 	{
-		LLAvatarNameCache::get(mOtherParticipantID,
-							   boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache,
-							   this, _2));
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(mOtherParticipantID,boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache,this, _2));
 	}
 }
 
@@ -450,6 +449,11 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 
 LLIMModel::LLIMSession::~LLIMSession()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
 	delete mSpeakers;
 	mSpeakers = NULL;
 
@@ -2056,7 +2060,8 @@ BOOL LLOutgoingCallDialog::postBuild()
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
-LLCallDialog(payload)
+LLCallDialog(payload),
+mAvatarNameCacheConnection()
 {
 }
 
@@ -2126,9 +2131,11 @@ BOOL LLIncomingCallDialog::postBuild()
 	else
 	{
 		// Get the full name information
-		LLAvatarNameCache::get(caller_id,
-			boost::bind(&LLIncomingCallDialog::onAvatarNameCache,
-				this, _1, _2, call_type));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(caller_id, boost::bind(&LLIncomingCallDialog::onAvatarNameCache, this, _1, _2, call_type));
 	}
 
 	setIcon(session_id, caller_id);
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 19b738069c..b46ce33ba6 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -142,6 +142,7 @@ public:
 		void onAdHocNameCache(const LLAvatarName& av_name);
 
 		static LLUUID generateHash(const std::set<LLUUID>& sorted_uuids);
+		boost::signals2::connection mAvatarNameCacheConnection;
 	};
 	
 
@@ -547,7 +548,14 @@ class LLIncomingCallDialog : public LLCallDialog
 {
 public:
 	LLIncomingCallDialog(const LLSD& payload);
-
+	~LLIncomingCallDialog()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
+	
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 
@@ -564,6 +572,8 @@ private:
 		const LLAvatarName& av_name,
 		const std::string& call_type);
 
+	boost::signals2::connection mAvatarNameCacheConnection;
+
 	/*virtual*/ void onLifetimeExpired();
 };
 
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 3507b729be..2136bd289f 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -88,6 +88,7 @@ private:
 	// an in-flight request for avatar properties from LLAvatarPropertiesProcessor
 	// is represented by this object
 	LLFetchAvatarData*	mPropertiesRequest;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -140,7 +141,8 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
 :	LLInspect( LLSD() ),	// single_instance, doesn't really need key
 	mAvatarID(),			// set in onOpen()  *Note: we used to show partner's name but we dont anymore --angela 3rd Dec* 
 	mAvatarName(),
-	mPropertiesRequest(NULL)
+	mPropertiesRequest(NULL),
+	mAvatarNameCacheConnection()
 {
 	// can't make the properties request until the widgets are constructed
 	// as it might return immediately, so do it in onOpen.
@@ -151,6 +153,10 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
 
 LLInspectAvatar::~LLInspectAvatar()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 	// clean up any pending requests so they don't call back into a deleted
 	// view
 	delete mPropertiesRequest;
@@ -226,9 +232,11 @@ void LLInspectAvatar::requestUpdate()
 
 	getChild<LLUICtrl>("avatar_icon")->setValue(LLSD(mAvatarID) );
 
-	LLAvatarNameCache::get(mAvatarID,
-			boost::bind(&LLInspectAvatar::onAvatarNameCache,
-				this, _1, _2));
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID,boost::bind(&LLInspectAvatar::onAvatarNameCache,this, _1, _2));
 }
 
 void LLInspectAvatar::processAvatarData(LLAvatarData* data)
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 1e60b10a68..cb6290368c 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4713,9 +4713,7 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
 		if (item && (item->getCreatorUUID() != gAgent.getID()) &&
 			(!item->getCreatorUUID().isNull()))
 		{
-			std::string callingcard_name;
-			gCacheName->getFullName(item->getCreatorUUID(), callingcard_name);
-			// IDEVO
+			std::string callingcard_name = LLCacheName::getDefaultName();
 			LLAvatarName av_name;
 			if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
 			{
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 855007e403..1ff241ccb8 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -64,7 +64,8 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
 	mNameColumnIndex(p.name_column.column_index),
 	mNameColumn(p.name_column.column_name),
 	mAllowCallingCardDrop(p.allow_calling_card_drop),
-	mShortNames(p.short_names)
+	mShortNames(p.short_names),
+	mAvatarNameCacheConnection()
 {}
 
 // public
@@ -327,9 +328,13 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
 			else
 			{
 				// ...schedule a callback
-				LLAvatarNameCache::get(id,
-					boost::bind(&LLNameListCtrl::onAvatarNameCache,
-						this, _1, _2, item->getHandle()));
+				// This is not correct and will likely lead to partially populated lists in cases where avatar names are not cached.
+				// *TODO : Change this to have 2 callbacks : one callback per list item and one for the whole list.
+				if (mAvatarNameCacheConnection.connected())
+				{
+					mAvatarNameCacheConnection.disconnect();
+				}
+				mAvatarNameCacheConnection = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, item->getHandle()));
 			}
 			break;
 		}
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 3ac0565761..271802d48a 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -111,6 +111,13 @@ public:
 
 protected:
 	LLNameListCtrl(const Params&);
+	virtual ~LLNameListCtrl()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
 	friend class LLUICtrlFactory;
 public:
 	// Add a user to the list by name.  It will be added, the name
@@ -154,6 +161,7 @@ private:
 	std::string		mNameColumn;
 	BOOL			mAllowCallingCardDrop;
 	bool			mShortNames;  // display name only, no SLID
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 51b4d2ea65..69d2c84e8a 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -79,13 +79,18 @@ LLPanelGroupGeneral::LLPanelGroupGeneral()
 	mCtrlReceiveNotices(NULL),
 	mCtrlListGroup(NULL),
 	mActiveTitleLabel(NULL),
-	mComboActiveTitle(NULL)
+	mComboActiveTitle(NULL),
+	mAvatarNameCacheConnection()
 {
 
 }
 
 LLPanelGroupGeneral::~LLPanelGroupGeneral()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 BOOL LLPanelGroupGeneral::postBuild()
@@ -728,9 +733,12 @@ void LLPanelGroupGeneral::updateMembers()
 		else
 		{
 			// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
-			LLAvatarNameCache::get(mMemberProgress->first, 
-									boost::bind(&LLPanelGroupGeneral::onNameCache,
-												this, mUdpateSessionID, member, _1, _2));
+			// *TODO : Use a callback per member, not for the panel group.
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupGeneral::onNameCache, this, mUdpateSessionID, member, _1, _2));
 		}
 	}
 
@@ -770,8 +778,7 @@ void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
 
 void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name)
 {
-	if (!member 
-		|| update_id != mUdpateSessionID)
+	if (!member || update_id != mUdpateSessionID)
 	{
 		return;
 	}
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index b179f78c56..cecf613a7e 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -112,6 +112,7 @@ private:
 	LLComboBox		*mComboMature;
 
 	LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 #endif
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index a2bbc5400c..1951a96c54 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -89,6 +89,8 @@ public:
 	void (*mCloseCallback)(void* data);
 
 	void* mCloseCallbackUserData;
+
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 
@@ -102,12 +104,17 @@ LLPanelGroupInvite::impl::impl(const LLUUID& group_id):
 	mGroupName( NULL ),
 	mConfirmedOwnerInvite( false ),
 	mCloseCallback( NULL ),
-	mCloseCallbackUserData( NULL )
+	mCloseCallbackUserData( NULL ),
+	mAvatarNameCacheConnection()
 {
 }
 
 LLPanelGroupInvite::impl::~impl()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names,
@@ -380,8 +387,24 @@ void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids, voi
 	std::vector<std::string> names;
 	for (S32 i = 0; i < (S32)agent_ids.size(); i++)
 	{
-		LLAvatarNameCache::get(agent_ids[i],
-			boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data));
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(agent_ids[i], &av_name))
+		{
+			LLPanelGroupInvite::impl::onAvatarNameCache(agent_ids[i], av_name, user_data);
+		}
+		else 
+		{
+			impl* selfp = (impl*) user_data;
+			if (selfp)
+			{
+				if (selfp->mAvatarNameCacheConnection.connected())
+				{
+					selfp->mAvatarNameCacheConnection.disconnect();
+				}
+				// *TODO : Add a callback per avatar name being fetched.
+				selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data));
+			}
+		}
 	}	
 	
 }
@@ -473,8 +496,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
 				if (!LLAvatarNameCache::get(agent_id, &av_name))
 				{
 					// actually it should happen, just in case
-					LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(
-							&LLPanelGroupInvite::addUserCallback, this, _1, _2));
+					//LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupInvite::addUserCallback, this, _1, _2));
 					// for this special case!
 					//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence
 					// removed id will be added in callback
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 7ad7e7149b..e6b85386dd 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -743,13 +743,18 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
 	mChanged(FALSE),
 	mPendingMemberUpdate(FALSE),
 	mHasMatch(FALSE),
-	mNumOwnerAdditions(0)
+	mNumOwnerAdditions(0),
+	mAvatarNameCacheConnection()
 {
 	mUdpateSessionID = LLUUID::null;
 }
 
 LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 	if (mMembersList)
 	{
 		gSavedSettings.setString("GroupMembersSortOrder", mMembersList->getSortColumnName());
@@ -1678,8 +1683,12 @@ void LLPanelGroupMembersSubTab::updateMembers()
 		else
 		{
 			// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
-			LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
-																	   this, mUdpateSessionID, mMemberProgress->second, _1, _2));
+			// *TODO : Add one callback per fetched avatar name
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, mUdpateSessionID, mMemberProgress->second, _1, _2));
 		}
 	}
 
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 8b454e020a..29b56f83d8 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -217,6 +217,7 @@ protected:
 	U32 mNumOwnerAdditions;
 
 	LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index ce8057eead..3660169f01 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -79,13 +79,18 @@ LLPanelPlaceProfile::LLPanelPlaceProfile()
 	mForSalePanel(NULL),
 	mYouAreHerePanel(NULL),
 	mSelectedParcelID(-1),
-	mAccordionCtrl(NULL)
+	mAccordionCtrl(NULL),
+	mAvatarNameCacheConnection()
 {}
 
 // virtual
 LLPanelPlaceProfile::~LLPanelPlaceProfile()
 {
 	gIdleCallbacks.deleteFunction(&LLPanelPlaceProfile::updateYouAreHereBanner, this);
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 // virtual
@@ -499,9 +504,11 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 			std::string parcel_owner =
 				LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
 			mParcelOwner->setText(parcel_owner);
-			LLAvatarNameCache::get(region->getOwner(),
-								   boost::bind(&LLPanelPlaceInfo::onAvatarNameCache,
-											   _1, _2, mRegionOwnerText));
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(region->getOwner(), boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mRegionOwnerText));
 		}
 
 		if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus())
@@ -523,9 +530,11 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 		const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
 		if(auth_buyer_id.notNull())
 		{
-			LLAvatarNameCache::get(auth_buyer_id,
-								   boost::bind(&LLPanelPlaceInfo::onAvatarNameCache,
-											   _1, _2, mSaleToText));
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(auth_buyer_id, boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mSaleToText));
 			
 			// Show sales info to a specific person or a group he belongs to.
 			if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id))
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index a33fc12ce4..6d42118d37 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -38,7 +38,7 @@ class LLPanelPlaceProfile : public LLPanelPlaceInfo
 public:
 	LLPanelPlaceProfile();
 	/*virtual*/ ~LLPanelPlaceProfile();
-
+	
 	/*virtual*/ BOOL postBuild();
 
 	/*virtual*/ void resetLocation();
@@ -116,6 +116,8 @@ private:
 	LLTextEditor*		mResaleText;
 	LLTextBox*			mSaleToText;
 	LLAccordionCtrl*	mAccordionCtrl;
+
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 #endif // LL_LLPANELPLACEPROFILE_H
diff --git a/indra/newview/llpathfindingobject.cpp b/indra/newview/llpathfindingobject.cpp
index 858d3203c0..900763eae4 100644
--- a/indra/newview/llpathfindingobject.cpp
+++ b/indra/newview/llpathfindingobject.cpp
@@ -173,6 +173,7 @@ void LLPathfindingObject::fetchOwnerName()
 		mHasOwnerName = LLAvatarNameCache::get(mOwnerUUID, &mOwnerName);
 		if (!mHasOwnerName)
 		{
+			disconnectAvatarNameCacheConnection();
 			mAvatarNameCacheConnection = LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2));
 		}
 	}
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index c81f6ace70..babb5065f7 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -972,24 +972,8 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 			|| !existing_inspector->getVisible()
 			|| existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())
 		{
-			// IDEVO: try to get display name + username
+			// Try to get display name + username
 			std::string final_name;
-			std::string full_name;
-			if (!gCacheName->getFullName(hover_object->getID(), full_name))
-			{
-			LLNameValue* firstname = hover_object->getNVPair("FirstName");
-			LLNameValue* lastname =  hover_object->getNVPair("LastName");
-			if (firstname && lastname)
-			{
-					full_name = LLCacheName::buildFullName(
-						firstname->getString(), lastname->getString());
-				}
-				else
-				{
-					full_name = LLTrans::getString("TooltipPerson");
-				}
-			}
-
 			LLAvatarName av_name;
 			if (LLAvatarNameCache::get(hover_object->getID(), &av_name))
 			{
@@ -997,7 +981,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 			}
 			else
 			{
-				final_name = full_name;
+				final_name = LLTrans::getString("TooltipPerson");;
 			}
 
 			// *HACK: We may select this object, so pretend it was clicked
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
index 4bd38562bc..6bd5631df6 100644
--- a/indra/newview/llviewerdisplayname.cpp
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -53,6 +53,7 @@ namespace LLViewerDisplayName
 		sNameChangedSignal.connect(cb); 
 	}
 
+	void doNothing() { }
 }
 
 class LLSetDisplayNameResponder : public LLHTTPClient::Responder
@@ -139,9 +140,9 @@ public:
 			LLUUID agent_id = gAgent.getID();
 			// Flush stale data
 			LLAvatarNameCache::erase( agent_id );
-			// Queue request for new data
-			LLAvatarName ignored;
-			LLAvatarNameCache::get( agent_id, &ignored );
+			// Queue request for new data: nothing to do on callback though...
+			// Note: no need to disconnect the callback as it never gets out of scope
+			LLAvatarNameCache::get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
 			// Kill name tag, as it is wrong
 			LLVOAvatar::invalidateNameTag( agent_id );
 		}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 5bb7db5c0d..f5da94dc87 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2254,7 +2254,7 @@ static std::string clean_name_from_task_im(const std::string& msg,
 	return msg;
 }
 
-void notification_display_name_callback(const LLUUID& id,
+static void notification_display_name_callback(const LLUUID& id,
 					  const LLAvatarName& av_name,
 					  const std::string& name, 
 					  LLSD& substitutions, 
@@ -2278,7 +2278,7 @@ protected:
 };
 
 // Callback for name resolution of a god/estate message
-void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
+static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
 {	
 	LLSD args;
 	args["NAME"] = av_name.getCompleteName();
@@ -3212,12 +3212,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			args["NAME"] = name;
 			LLSD payload;
 			payload["from_id"] = from_id;
-			LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,
-														 _1,
-														 _2,
-														 "FriendshipAccepted",
-														 args,
-														 payload));
+			LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,_1,_2,"FriendshipAccepted",args,payload));
 		}
 		break;
 
@@ -5651,11 +5646,9 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
 									_1, _2, _3,
 									notification, final_args, payload));
 	}
-	else {
-		LLAvatarNameCache::get(name_id,
-							   boost::bind(&money_balance_avatar_notify,
-										   _1, _2,
-										   notification, final_args, payload));										   
+	else 
+	{
+		LLAvatarNameCache::get(name_id, boost::bind(&money_balance_avatar_notify, _1, _2, notification, final_args, payload));										   
 	}
 }
 
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 7cc4e3ed04..951c145f25 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3193,8 +3193,9 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 			LLAvatarName av_name;
 			if (!LLAvatarNameCache::get(getID(), &av_name))
 			{
-				// ...call this function back when the name arrives and force a rebuild
-				LLAvatarNameCache::get(getID(),boost::bind(&LLVOAvatar::clearNameTag, this));
+				// Force a rebuild at next idle
+				// Note: do not connect a callback on idle().
+				clearNameTag();
 			}
 
 			// Might be blank if name not available yet, that's OK
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 6fdda12a1c..bd7914af6f 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -316,7 +316,9 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 	mCaptureBufferRecording(false),
 	mCaptureBufferRecorded(false),
 	mCaptureBufferPlaying(false),
-	mPlayRequestCount(0)
+	mPlayRequestCount(0),
+
+	mAvatarNameCacheConnection()
 {	
 	mSpeakerVolume = scale_speaker_volume(0);
 
@@ -349,6 +351,10 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 
 LLVivoxVoiceClient::~LLVivoxVoiceClient()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 //---------------------------------------------------
@@ -6192,9 +6198,11 @@ void LLVivoxVoiceClient::notifyFriendObservers()
 
 void LLVivoxVoiceClient::lookupName(const LLUUID &id)
 {
-	LLAvatarNameCache::get(id,
-		boost::bind(&LLVivoxVoiceClient::onAvatarNameCache,
-			this, _1, _2));
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, this, _1, _2));
 }
 
 void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id,
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index f2a3a7d3dd..69f33df94b 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -641,6 +641,7 @@ protected:
 	void lookupName(const LLUUID &id);
 	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
 	void avatarNameResolved(const LLUUID &id, const std::string &name);
+	boost::signals2::connection mAvatarNameCacheConnection;
 
 	/////////////////////////////
 	// Voice fonts
-- 
cgit v1.2.3


From c2d332a89cb29d54df40f1f120304d871278fb76 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 17 Dec 2012 20:16:33 -0800
Subject: CHUI-580 : WIP : Added disconnect of callbacks once they're called to
 prevent filling up the callback queue

---
 indra/llui/llnotifications.cpp         |  2 ++
 indra/llui/llurlentry.cpp              |  8 ++++++--
 indra/newview/llavatariconctrl.cpp     |  2 ++
 indra/newview/llavatarlistitem.cpp     |  2 ++
 indra/newview/llchathistory.cpp        |  2 ++
 indra/newview/llconversationlog.cpp    |  1 +
 indra/newview/llconversationmodel.cpp  |  2 ++
 indra/newview/llfloaterinspect.cpp     | 16 ++++++++++++++--
 indra/newview/llfloaterinspect.h       |  3 ++-
 indra/newview/llfloaterreporter.cpp    |  2 ++
 indra/newview/llfloatersellland.cpp    |  2 ++
 indra/newview/llfloatervoicevolume.cpp |  2 ++
 indra/newview/llimview.cpp             |  3 +++
 indra/newview/llinspectavatar.cpp      |  2 ++
 indra/newview/llnamelistctrl.cpp       |  2 ++
 indra/newview/llpanelgroupgeneral.cpp  |  2 ++
 indra/newview/llpanelgroupinvite.cpp   |  4 ++++
 indra/newview/llpanelgrouproles.cpp    |  2 ++
 indra/newview/llpanelplaceprofile.cpp  | 19 +++----------------
 indra/newview/llpanelplaceprofile.h    |  2 --
 indra/newview/llvoicevivox.cpp         |  1 +
 21 files changed, 58 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 6b00225605..8fb7a9d864 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1827,6 +1827,8 @@ void LLPostponedNotification::fetchAvatarName(const LLUUID& id)
 void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id,
 												const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+	
 	std::string name = av_name.getCompleteName();
 
 	// from PE merge - we should figure out if this is the right thing to do
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 1758218b7d..99ee688888 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -372,7 +372,9 @@ void LLUrlEntryAgent::callObservers(const std::string &id,
 void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
 										const LLAvatarName& av_name)
 {
-	std::string label = av_name.getCompleteName();
+	mAvatarNameCacheConnection.disconnect();
+	
+ 	std::string label = av_name.getCompleteName();
 
 	// received the agent name from the server - tell our observers
 	callObservers(id.asString(), label, mIcon);
@@ -525,6 +527,8 @@ LLUrlEntryAgentName::LLUrlEntryAgentName() :
 void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
 										const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	std::string label = getName(av_name);
 	// received the agent name from the server - tell our observers
 	callObservers(id.asString(), label, mIcon);
@@ -562,7 +566,7 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab
 		{
 			mAvatarNameCacheConnection.disconnect();
 		}
-		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentCompleteName::onAvatarNameCache, this, _1, _2));
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2));
 		addObserver(agent_id_string, url, cb);
 		return LLTrans::getString("LoadingData");
 	}
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 60a2c14911..714bde6f37 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -313,6 +313,8 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
 
 void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	if (agent_id == mAvatarId)
 	{
 		// Most avatar icon controls are next to a UI element that shows
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index f5308563b5..3ed0c7c482 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -459,6 +459,8 @@ void LLAvatarListItem::setNameInternal(const std::string& name, const std::strin
 
 void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	setAvatarName(av_name.getDisplayName());
 	setAvatarToolTip(av_name.getUserName());
 
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 764ee4a8ea..3f959c0510 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -552,6 +552,8 @@ private:
 
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
 	{
+		mAvatarNameCacheConnection.disconnect();
+
 		mFrom = av_name.getDisplayName();
 
 		LLTextBox* user_name = getChild<LLTextBox>("user_name");
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index f8ccb08e66..3b75cd8203 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -518,5 +518,6 @@ void LLConversationLog::onNewMessageReceived(const LLSD& data)
 
 void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session)
 {
+	mAvatarNameCacheConnection.disconnect();
 	updateConversationName(session, av_name.getCompleteName());
 }
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index ef9e0e02e5..b1f45d6d64 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -446,6 +446,8 @@ void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
 
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	mName = av_name.getUserName();
 	mDisplayName = av_name.getDisplayName();
 	mNeedsRefresh = true;
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index 3636bba355..5a1dfc99ab 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -233,7 +233,7 @@ void LLFloaterInspect::refresh()
 			{
 				mOwnerNameCacheConnection.disconnect();
 			}
-			mOwnerNameCacheConnection = LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::setDirty, this));
+			mOwnerNameCacheConnection = LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetOwnerNameCallback, this));
 		}
 
 		if (LLAvatarNameCache::get(idCreator, &av_name))
@@ -247,7 +247,7 @@ void LLFloaterInspect::refresh()
 			{
 				mCreatorNameCacheConnection.disconnect();
 			}
-			mCreatorNameCacheConnection = LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::setDirty, this));
+			mCreatorNameCacheConnection = LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetCreatorNameCallback, this));
 		}
 		
 		row["id"] = obj->getObject()->getID();
@@ -297,6 +297,18 @@ void LLFloaterInspect::dirty()
 	setDirty();
 }
 
+void LLFloaterInspect::onGetOwnerNameCallback()
+{
+	mOwnerNameCacheConnection.disconnect();
+	setDirty();
+}
+
+void LLFloaterInspect::onGetCreatorNameCallback()
+{
+	mCreatorNameCacheConnection.disconnect();
+	setDirty();
+}
+
 void LLFloaterInspect::draw()
 {
 	if (mDirty)
diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h
index 495f8f0a39..44381eac96 100644
--- a/indra/newview/llfloaterinspect.h
+++ b/indra/newview/llfloaterinspect.h
@@ -62,7 +62,8 @@ protected:
 	bool mDirty;
 
 private:
-	void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name);
+	void onGetOwnerNameCallback();
+	void onGetCreatorNameCallback();
 	
 	LLFloaterInspect(const LLSD& key);
 	virtual ~LLFloaterInspect(void);
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 79387747a5..0e4c7406c5 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -328,6 +328,8 @@ void LLFloaterReporter::setFromAvatarID(const LLUUID& avatar_id)
 
 void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	if (mObjectID == avatar_id)
 	{
 		mOwnerName = av_name.getCompleteName();
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index ec13a6ff1d..0cb37dabe7 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -246,6 +246,8 @@ void LLFloaterSellLandUI::updateParcelInfo()
 
 void LLFloaterSellLandUI::onBuyerNameCache(const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	getChild<LLUICtrl>("sell_to_agent")->setValue(av_name.getCompleteName());
 	getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.getUserName());
 }
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
index 82d366a48e..38446e46df 100644
--- a/indra/newview/llfloatervoicevolume.cpp
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -199,6 +199,8 @@ void LLFloaterVoiceVolume::onAvatarNameCache(
 		const LLUUID& agent_id,
 		const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	if (agent_id != mAvatarID)
 	{
 		return;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d3569694f1..9195ea2344 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -341,6 +341,8 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 
 void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	if (!av_name.isValidName())
 	{
 		S32 separator_index = mName.rfind(" ");
@@ -2178,6 +2180,7 @@ void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id,
 											 const LLAvatarName& av_name,
 											 const std::string& call_type)
 {
+	mAvatarNameCacheConnection.disconnect();
 	std::string title = av_name.getCompleteName();
 	setCallerName(title, av_name.getCompleteName(), call_type);
 }
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 2136bd289f..26d3a2bd12 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -269,6 +269,8 @@ void LLInspectAvatar::onAvatarNameCache(
 		const LLUUID& agent_id,
 		const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	if (agent_id == mAvatarID)
 	{
 		getChild<LLUICtrl>("user_name")->setValue(av_name.getDisplayName());
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 1ff241ccb8..7f396b7b7e 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -393,6 +393,8 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
 									   const LLAvatarName& av_name,
 									   LLHandle<LLNameListItem> item)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	std::string name;
 	if (mShortNames)
 		name = av_name.getDisplayName();
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 684c975e2d..0cd93b330a 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -777,6 +777,8 @@ void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
 
 void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
 
 	if (!gdatap
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 77d74a5d1a..133b269c11 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -417,6 +417,10 @@ void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id,
 
 	if (selfp)
 	{
+		if (selfp->mAvatarNameCacheConnection.connected())
+		{
+			selfp->mAvatarNameCacheConnection.disconnect();
+		}
 		std::vector<std::string> names;
 		uuid_vec_t agent_ids;
 		agent_ids.push_back(agent_id);
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 907b02993a..cfdac11d26 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1609,6 +1609,8 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data)
 
 void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
 	if (!gdatap
 		|| gdatap->getMemberVersion() != update_id
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 3660169f01..83b70d9f29 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -79,18 +79,13 @@ LLPanelPlaceProfile::LLPanelPlaceProfile()
 	mForSalePanel(NULL),
 	mYouAreHerePanel(NULL),
 	mSelectedParcelID(-1),
-	mAccordionCtrl(NULL),
-	mAvatarNameCacheConnection()
+	mAccordionCtrl(NULL)
 {}
 
 // virtual
 LLPanelPlaceProfile::~LLPanelPlaceProfile()
 {
 	gIdleCallbacks.deleteFunction(&LLPanelPlaceProfile::updateYouAreHereBanner, this);
-	if (mAvatarNameCacheConnection.connected())
-	{
-		mAvatarNameCacheConnection.disconnect();
-	}
 }
 
 // virtual
@@ -504,11 +499,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 			std::string parcel_owner =
 				LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
 			mParcelOwner->setText(parcel_owner);
-			if (mAvatarNameCacheConnection.connected())
-			{
-				mAvatarNameCacheConnection.disconnect();
-			}
-			mAvatarNameCacheConnection = LLAvatarNameCache::get(region->getOwner(), boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mRegionOwnerText));
+			LLAvatarNameCache::get(region->getOwner(), boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mRegionOwnerText));
 		}
 
 		if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus())
@@ -530,11 +521,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 		const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
 		if(auth_buyer_id.notNull())
 		{
-			if (mAvatarNameCacheConnection.connected())
-			{
-				mAvatarNameCacheConnection.disconnect();
-			}
-			mAvatarNameCacheConnection = LLAvatarNameCache::get(auth_buyer_id, boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mSaleToText));
+			LLAvatarNameCache::get(auth_buyer_id, boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mSaleToText));
 			
 			// Show sales info to a specific person or a group he belongs to.
 			if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id))
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index 6d42118d37..f4c6145881 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -116,8 +116,6 @@ private:
 	LLTextEditor*		mResaleText;
 	LLTextBox*			mSaleToText;
 	LLAccordionCtrl*	mAccordionCtrl;
-
-	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 #endif // LL_LLPANELPLACEPROFILE_H
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index d89ecb6306..5e121bbcee 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -6208,6 +6208,7 @@ void LLVivoxVoiceClient::lookupName(const LLUUID &id)
 void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id,
 										   const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
 	std::string display_name = av_name.getDisplayName();
 	avatarNameResolved(agent_id, display_name);
 }
-- 
cgit v1.2.3


From 355e7a061311df30f019fd722df6072b745b0ef6 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Tue, 18 Dec 2012 12:25:19 +0200
Subject: CHUI-586 (Scroll bar only partially shown initially on torn off
 conversations)

---
 indra/newview/llfloaterimsessiontab.cpp | 17 ++++++++++++++++-
 indra/newview/llfloaterimsessiontab.h   |  2 ++
 2 files changed, 18 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index ea99a1c5bf..07907095f8 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -177,6 +177,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 				// LLFloater::mLastHostHandle = floater_container (a "future" host)
 				conversp->setHost(floater_container);
 				conversp->setHost(NULL);
+				conversp->forceReshape();
 			}
 			// Added floaters share some state (like sort order) with their host
 			conversp->setSortOrder(floater_container->getSortOrder());
@@ -224,7 +225,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
 
 	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 
-	mSaveRect = isTornOff();
+	mSaveRect = isNearbyChat()
+					&&  !gSavedSettings.getBOOL("NearbyChatIsNotTornOff");
 	initRectControl();
 
 	if (isChatMultiTab())
@@ -649,6 +651,15 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 
 	showTranslationCheckbox();
 }
+ 
+void LLFloaterIMSessionTab::forceReshape()
+{
+    LLRect floater_rect = getRect();
+    reshape(llmax(floater_rect.getWidth(), this->getMinWidth()),
+    		llmax(floater_rect.getHeight(), this->getMinHeight()),
+    		true);
+}
+
 
 void LLFloaterIMSessionTab::reshapeChatHistory()
 {
@@ -755,6 +766,10 @@ void LLFloaterIMSessionTab::onTearOffClicked()
     mSaveRect = isTornOff();
     initRectControl();
 	LLFloater::onClickTearOff(this);
+	if (isTornOff())
+	{
+		forceReshape();
+	}
 	refreshConversation();
 }
 
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index cd0bcd481c..9aeda9ddf9 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -96,6 +96,8 @@ public:
 	virtual void updateMessages() {}
 	LLConversationItem* getCurSelectedViewModelItem();
 
+	void forceReshape();
+
 protected:
 
 	// callback for click on any items of the visual states menu
-- 
cgit v1.2.3


From 6b165ce2ade6db7d5e6cb23e039e4949dc71e617 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 18 Dec 2012 15:09:50 +0200
Subject: CHUI-562 FIXED Gear button is added for p2p torn-off floater.

---
 indra/newview/llfloaterimsession.cpp               | 33 ++++++++
 indra/newview/llfloaterimsession.h                 |  3 +
 indra/newview/llfloaterimsessiontab.cpp            | 53 +++++++++++-
 indra/newview/llfloaterimsessiontab.h              |  5 +-
 .../skins/default/xui/en/floater_im_session.xml    | 15 ++++
 .../skins/default/xui/en/menu_im_conversation.xml  | 94 ++++++++++++++++++++++
 6 files changed, 200 insertions(+), 3 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/menu_im_conversation.xml

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a0ca7286f1..f2afe9d7bb 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -83,6 +83,9 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
 	setOverlapsScreenChannel(true);
 
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+    mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&LLFloaterIMSession::enableGearMenuItem, this, _2));
+    mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&LLFloaterIMSession::GearDoToSelected, this, _2));
+    mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&LLFloaterIMSession::checkGearMenuItem, this, _2));
 
 	setDocked(true);
 }
@@ -190,6 +193,36 @@ void LLFloaterIMSession::onSendMsg( LLUICtrl* ctrl, void* userdata )
 	self->setTyping(false);
 }
 
+bool LLFloaterIMSession::enableGearMenuItem(const LLSD& userdata)
+{
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+    selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->enableContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSession::GearDoToSelected(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+    selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	floater_container->doToParticipants(command, selected_uuids);
+}
+
+bool LLFloaterIMSession::checkGearMenuItem(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+	uuid_vec_t selected_uuids;
+	selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->checkContextMenuItem(command, selected_uuids);
+}
+
 void LLFloaterIMSession::sendMsgFromInputEditor()
 {
 	if (gAgent.isGodlike()
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 1d8957b1d9..43d84eb8c0 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -99,6 +99,9 @@ public:
 	void setPositioned(bool b) { mPositioned = b; };
 
 	void onVisibilityChange(const LLSD& new_visibility);
+	bool enableGearMenuItem(const LLSD& userdata);
+	void GearDoToSelected(const LLSD& userdata);
+	bool checkGearMenuItem(const LLSD& userdata);
 
 	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
 	// button when voice is available
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index ea99a1c5bf..267dba562c 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -197,6 +197,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
 
+	mGearBtn = getChild<LLButton>("gear_btn");
+
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
 	
 	// Add a scroller for the folder (participant) view
@@ -239,11 +241,11 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	// Now ready to build the conversation and participants list
 	buildConversationViewParticipant();
 	refreshConversation();
-		
+
 	// Zero expiry time is set only once to allow initial update.
 	mRefreshTimer->setTimerExpirySec(0);
 	mRefreshTimer->start();
-
+	initBtns();
 	return result;
 }
 
@@ -756,6 +758,53 @@ void LLFloaterIMSessionTab::onTearOffClicked()
     initRectControl();
 	LLFloater::onClickTearOff(this);
 	refreshConversation();
+	updateGearBtn();
+}
+
+void LLFloaterIMSessionTab::updateGearBtn()
+{
+
+	bool prevVisibility = mGearBtn->getVisible();
+	mGearBtn->setVisible(checkIfTornOff() && mIsP2PChat);
+
+
+	// Move buttons if Gear button changed visibility
+	if(prevVisibility != mGearBtn->getVisible())
+	{
+		LLRect gear_btn_rect =  mGearBtn->getRect();
+		LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect();
+		LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect();
+		S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+		S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+		if(mGearBtn->getVisible())
+		{
+			// Move buttons to the right to give space for Gear button
+			add_btn_rect.translate(right_shift,0);
+			call_btn_rect.translate(right_shift,0);
+		}
+		else
+		{
+			add_btn_rect.translate(-right_shift,0);
+			call_btn_rect.translate(-right_shift,0);
+		}
+		getChild<LLButton>("add_btn")->setRect(add_btn_rect);
+		getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect);
+	}
+}
+
+void LLFloaterIMSessionTab::initBtns()
+{
+	LLRect gear_btn_rect =  mGearBtn->getRect();
+	LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect();
+	LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect();
+	S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+	S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+
+	add_btn_rect.translate(-right_shift,0);
+	call_btn_rect.translate(-right_shift,0);
+
+	getChild<LLButton>("add_btn")->setRect(add_btn_rect);
+	getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect);
 }
 
 // static
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index cd0bcd481c..b05708059a 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -92,7 +92,8 @@ public:
 
 	void setSortOrder(const LLConversationSort& order);
 	virtual void onTearOffClicked();
-	
+	void updateGearBtn();
+	void initBtns();
 	virtual void updateMessages() {}
 	LLConversationItem* getCurSelectedViewModelItem();
 
@@ -157,6 +158,8 @@ protected:
 	LLButton* mExpandCollapseBtn;
 	LLButton* mTearOffBtn;
 	LLButton* mCloseBtn;
+	LLButton* mGearBtn;
+
 
 private:
 	// Handling selection and contextual menu
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index e4b127b7b9..4dbd52d05e 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -79,6 +79,21 @@
                  tool_tip="View/sort options"
                  top="5"
                  width="31" />
+             <menu_button
+				 menu_filename="menu_im_conversation.xml"
+				 follows="top|left"
+				 height="25"
+				 image_hover_unselected="Toolbar_Middle_Over"
+				 image_overlay="OptionsMenu_Off"
+				 image_selected="Toolbar_Middle_Selected"
+				 image_unselected="Toolbar_Middle_Off"
+				 layout="topleft"
+			 	 top="5"
+			 	 left_pad="4"
+				 name="gear_btn"
+				 visible="false"
+				 tool_tip="Actions on selected person"
+				 width="31"/>
              <button
                  enabled="false"
                  follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
new file mode 100644
index 0000000000..8882d0a7d8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Conversation Gear Menu">
+    <menu_item_call
+     label="View Profile"
+     layout="topleft"
+     name="View Profile">
+        <on_click function="Avatar.GearDoToSelected" parameter="view_profile" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_view_profile" />
+    </menu_item_call>
+    <menu_item_call
+     label="Add Friend"
+     layout="topleft"
+     name="Add Friend">
+        <on_click function="Avatar.GearDoToSelected" parameter="add_friend" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_add" />
+    </menu_item_call>
+    <menu_item_call
+     label="Remove friend"
+     layout="topleft"
+     name="remove_friend">
+        <on_click function="Avatar.GearDoToSelected" parameter="remove_friend" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_delete" />
+    </menu_item_call>
+    <menu_item_call
+     label="Offer teleport"
+     layout="topleft"
+     name="offer_teleport">
+        <on_click function="Avatar.GearDoToSelected" parameter="offer_teleport"/>
+        <on_enable function="Avatar.EnableGearItem" parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Invite to group..."
+     layout="topleft"
+     name="invite_to_group">
+        <on_click function="Avatar.GearDoToSelected" parameter="invite_to_group" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_invite" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"
+     name="View Icons Separator" />
+    <menu_item_call
+     label="Chat history..."
+     layout="topleft"
+     name="chat_history">
+        <on_click function="Avatar.GearDoToSelected" parameter="chat_history"/>
+        <on_enable function="Avatar.EnableGearItem" parameter="can_chat_history"/>
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"/>
+    <menu_item_call
+     label="Map"
+     layout="topleft"
+     name="map">
+        <on_click function="Avatar.GearDoToSelected" parameter="map" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_show_on_map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Share"
+     layout="topleft"
+     name="Share">
+        <on_click function="Avatar.GearDoToSelected" parameter="share" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_share" />
+    </menu_item_call>
+    <menu_item_call
+     label="Pay"
+     layout="topleft"
+     name="Pay">
+        <on_click function="Avatar.GearDoToSelected" parameter="pay" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_pay" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"/>
+    <menu_item_check
+     label="Block Voice"
+     layout="topleft"
+     name="Block/Unblock">
+        <on_check function="Avatar.CheckGearItem" parameter="is_blocked" />
+        <on_click function="Avatar.GearDoToSelected" parameter="block_unblock" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+    </menu_item_check>
+    <menu_item_check
+     label="Block Text"
+     layout="topleft"
+     name="MuteText">
+        <on_check function="Avatar.CheckGearItem" parameter="is_muted" />
+        <on_click function="Avatar.GearDoToSelected" parameter="mute_unmute" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+    </menu_item_check>
+    <menu_item_separator
+     layout="topleft"/>
+</toggleable_menu>
+
-- 
cgit v1.2.3


From 90971d817193b416b580bfb46ed888776a59f972 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 18 Dec 2012 17:41:03 +0200
Subject: Additional fix for CHUI-562

---
 indra/newview/llfloaterimsessiontab.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 267dba562c..01b30305c4 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -764,7 +764,7 @@ void LLFloaterIMSessionTab::onTearOffClicked()
 void LLFloaterIMSessionTab::updateGearBtn()
 {
 
-	bool prevVisibility = mGearBtn->getVisible();
+	BOOL prevVisibility = mGearBtn->getVisible();
 	mGearBtn->setVisible(checkIfTornOff() && mIsP2PChat);
 
 
-- 
cgit v1.2.3


From d2102c9b9f7ad31d3b5061a19f7b955af2f34b9f Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 19 Dec 2012 17:26:55 +0200
Subject: CHUI-601 : Fixed : Crash when dismissing a conversation while a
 participant is selected DeletePointer() for the items was replaced by
 Function LLFolderViewItem::destroyView(): Function
 LLFolderViewItem::destroyView(), before removing the item, immediately
 removes it from the Selection List of the Root Folder. As a result, at the
 time of the call of sanitizeSelection(), will not need to try to handle the
 elements that have already been deleted.

---
 indra/llui/llfolderviewitem.cpp | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 0a06ce66aa..dc7e4777a7 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1481,17 +1481,20 @@ void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
 
 void LLFolderViewFolder::destroyView()
 {
-	std::for_each(mItems.begin(), mItems.end(), DeletePointer());
-	mItems.clear();
+    while (!mItems.empty())
+    {
+    	LLFolderViewItem *itemp = mItems.back();
+    	itemp->destroyView(); // LLFolderViewItem::destroyView() removes entry from mItems
+    }
 
 	while (!mFolders.empty())
 	{
 		LLFolderViewFolder *folderp = mFolders.back();
-		folderp->destroyView(); // removes entry from mFolders
+		folderp->destroyView(); // LLFolderVievFolder::destroyView() removes entry from mFolders
 	}
 
 	LLFolderViewItem::destroyView();
-	}
+}
 
 // extractItem() removes the specified item from the folder, but
 // doesn't delete it.
-- 
cgit v1.2.3


From b34e3a1b40fd72b4c4cdc1553c3f5934e9e9cef5 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 18 Dec 2012 18:30:14 +0200
Subject: Clean up: Removed unnecessary call removeConversationListItem() when
 floater closes (If session's floater will be removed for any reason, then
 will start a removing of the corresponding session and
 removeConversationListItem() will call from a session's observer); Local
 variable are renamed in accordance with the code styling

---
 indra/newview/llfloaterimcontainer.cpp  |  7 ++++---
 indra/newview/llfloaterimsessiontab.cpp | 13 -------------
 indra/newview/llfloaterimsessiontab.h   |  1 -
 3 files changed, 4 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index ba5ec363d6..390eec84f6 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1412,17 +1412,18 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
-	bool isWidgetSelected = false;
+	bool is_widget_selected = false;
 	LLFolderViewItem* new_selection = NULL;
 	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
 	if (widget)
 	{
-		isWidgetSelected = widget->isSelected();
+		is_widget_selected = widget->isSelected();
 		new_selection = mConversationsRoot->getNextFromChild(widget);
 		if(new_selection == NULL)
 		{
 			new_selection = mConversationsRoot->getPreviousFromChild(widget);
 		}
+
 		widget->destroyView();
 	}
 	
@@ -1445,7 +1446,7 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 			}
 		}
 	}
-	return isWidgetSelected;
+	return is_widget_selected;
 }
 
 LLConversationViewSession* LLFloaterIMContainer::createConversationItemWidget(LLConversationItem* item)
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index d6955f37f2..7984034ded 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -748,19 +748,6 @@ void LLFloaterIMSessionTab::onOpen(const LLSD& key)
 	}
 }
 
-// virtual
-void LLFloaterIMSessionTab::onClose(bool app_quitting)
-{
-	// Always suppress the IM from the conversations list on close if present for any reason
-	if (LLFloaterIMSessionTab::isChatMultiTab())
-	{
-		LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
-		if (im_box)
-		{
-            im_box->removeConversationListItem(mKey);
-        }
-    }
-}
 
 void LLFloaterIMSessionTab::onTearOffClicked()
 {
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index a452c77224..0fa99a46be 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -77,7 +77,6 @@ public:
 
 	// LLFloater overrides
 	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
 	/*virtual*/ void setVisible(BOOL visible);
-- 
cgit v1.2.3


From e64c8fdc145c6ae2727173d310a732a471aaf569 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 18 Dec 2012 18:57:13 +0200
Subject: CHUI-583 FIXED Menu items with appropriate links are added

---
 indra/newview/skins/default/xui/en/menu_viewer.xml | 53 +++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 3e7329c0b5..00424e97f6 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1267,7 +1267,58 @@
              function="Floater.Show"
              parameter="hud" />
         </menu_item_call>-->
-
+		<menu_item_separator/>
+		
+		<menu_item_call
+             label="User’s guide"
+             name="User’s guide">
+             <menu_item_call.on_click
+                 function="Advanced.WebBrowserTest"
+                 parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-User-s-Guide/ta-p/1244857"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Knowledge Base"
+             name="Knowledge Base">
+             <menu_item_call.on_click
+                 function="Advanced.WebBrowserTest"
+                 parameter="http://community.secondlife.com/t5/tkb/communitypage"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Wiki"
+             name="Wiki">
+             <menu_item_call.on_click
+                 function="Advanced.WebBrowserTest"
+                 parameter="http://wiki.secondlife.com"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Community Forums"
+             name="Community Forums">
+             <menu_item_call.on_click
+                 function="Advanced.WebBrowserTest"
+                 parameter="http://community.secondlife.com/t5/Forums/ct-p/Forums"/>
+        </menu_item_call>         
+        <menu_item_call
+             label="Support portal"
+             name="Support portal">
+             <menu_item_call.on_click
+                 function="Advanced.WebBrowserTest"
+                 parameter="https://support.secondlife.com/"/>         
+        </menu_item_call>
+        <menu_item_separator/>
+        <menu_item_call
+             label="[SECOND_LIFE] News"
+             name="Second Life News">
+             <menu_item_call.on_click
+                 function="Advanced.WebBrowserTest"
+                 parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>  
+        </menu_item_call>
+        <menu_item_call
+             label="[SECOND_LIFE] Blogs"
+             name="Second Life Blogs">
+             <menu_item_call.on_click
+                 function="Advanced.WebBrowserTest"
+                 parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+        </menu_item_call>
         <menu_item_separator/>
 
         <menu_item_call
-- 
cgit v1.2.3


From 610b25ad3a070c984cb303250428a4a9b8301c6f Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 18 Dec 2012 18:33:16 +0200
Subject: CHUI-591 FIXED Issues with resizing conversations floater

---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 37a3b9ac59..1837100c28 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -38,7 +38,7 @@
          name="conversations_layout_panel"
          min_dim="38"
          width="225"
-         expanded_min_dim="200">
+         expanded_min_dim="156">
             <layout_stack
              animate="false" 
              follows="left|top|right"
@@ -108,7 +108,7 @@
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
                      top="5"
-                     left="5"
+                     left="1"
                      name="expand_collapse_btn"
                      tool_tip="Collapse/Expand this list"
                      width="31" />
@@ -128,7 +128,7 @@
          auto_resize="true"
          user_resize="true"
          name="messages_layout_panel"
-         expanded_min_dim="225">
+         expanded_min_dim="186">
             <panel_container
              bottom="-1"
              follows="all"
-- 
cgit v1.2.3


From fc89db6ca4f0cc41e9b20e52a2735ff1db143314 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 19 Dec 2012 00:09:47 +0200
Subject: CHUI-591 FIXED Issues with resizing conversations floater: small
 correction of size in right panel of conversation floater;

---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 1837100c28..3475c7da33 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -128,7 +128,7 @@
          auto_resize="true"
          user_resize="true"
          name="messages_layout_panel"
-         expanded_min_dim="186">
+         expanded_min_dim="222">
             <panel_container
              bottom="-1"
              follows="all"
-- 
cgit v1.2.3


From cc900b732dd1af2790248485a270197a4006e0f7 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 19 Dec 2012 02:44:48 +0200
Subject: CHUI-592 FIXED Unread notifications are not being saved in
 notification chiclet

---
 indra/newview/llchiclet.cpp                        | 216 ++++++++++++++++++++-
 indra/newview/llchiclet.h                          | 208 +++++++++++++++++++-
 indra/newview/llchicletbar.cpp                     |   3 +
 indra/newview/llsyswellwindow.cpp                  |  15 ++
 indra/newview/llsyswellwindow.h                    |   7 +
 indra/newview/skins/default/textures/textures.xml  |   2 +
 .../xui/da/menu_notification_well_button.xml       |   4 +
 .../xui/de/menu_notification_well_button.xml       |   4 +
 .../xui/en/menu_notification_well_button.xml       |  16 ++
 .../skins/default/xui/en/panel_chiclet_bar.xml     |  44 +++++
 .../xui/es/menu_notification_well_button.xml       |   4 +
 .../xui/fr/menu_notification_well_button.xml       |   4 +
 .../xui/it/menu_notification_well_button.xml       |   4 +
 .../xui/ja/menu_notification_well_button.xml       |   4 +
 .../xui/pl/menu_notification_well_button.xml       |   4 +
 .../xui/pt/menu_notification_well_button.xml       |   4 +
 .../xui/ru/menu_notification_well_button.xml       |   4 +
 .../xui/tr/menu_notification_well_button.xml       |   4 +
 .../xui/zh/menu_notification_well_button.xml       |   4 +
 19 files changed, 546 insertions(+), 9 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/da/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/de/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/es/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/it/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
 create mode 100644 indra/newview/skins/default/xui/zh/menu_notification_well_button.xml

(limited to 'indra')

diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 1acbdd32b7..2fdcb17570 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -27,15 +27,17 @@
 #include "llviewerprecompiledheaders.h" // must be first include
 #include "llchiclet.h"
 
+#include "llchicletbar.h"
 #include "llfloaterimsession.h"
 #include "llfloaterimcontainer.h"
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
-#include "llnotifications.h"
 #include "llscriptfloater.h"
 #include "llsingleton.h"
+#include "llsyswellwindow.h"
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
+static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
 static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
 static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer");
 
@@ -46,6 +48,195 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
+LLSysWellChiclet::Params::Params()
+	: button("button")
+	, unread_notifications("unread_notifications")
+	, max_displayed_count("max_displayed_count", 99)
+{
+	button.name = "button";
+	button.tab_stop = FALSE;
+	button.label = LLStringUtil::null;
+}
+
+LLSysWellChiclet::LLSysWellChiclet(const Params& p)
+	: LLChiclet(p)
+	, mButton(NULL)
+	, mCounter(0)
+	, mMaxDisplayedCount(p.max_displayed_count)
+	, mIsNewMessagesState(false)
+	, mFlashToLitTimer(NULL)
+	, mContextMenu(NULL)
+{
+	LLButton::Params button_params = p.button;
+	mButton = LLUICtrlFactory::create<LLButton>(button_params);
+	addChild(mButton);
+
+	mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1));
+}
+
+LLSysWellChiclet::~LLSysWellChiclet()
+{
+	delete mFlashToLitTimer;
+}
+
+void LLSysWellChiclet::setCounter(S32 counter)
+{
+	// do nothing if the same counter is coming. EXT-3678.
+	if (counter == mCounter) return;
+
+	// note same code in LLChicletNotificationCounterCtrl::setCounter(S32 counter)
+	std::string s_count;
+	if(counter != 0)
+	{
+		static std::string more_messages_exist("+");
+		std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
+		s_count = llformat("%d%s"
+			, llmin(counter, mMaxDisplayedCount)
+			, more_messages.c_str()
+			);
+	}
+
+	mButton->setLabel(s_count);
+
+	mCounter = counter;
+}
+
+boost::signals2::connection LLSysWellChiclet::setClickCallback(
+	const commit_callback_t& cb)
+{
+	return mButton->setClickedCallback(cb);
+}
+
+void LLSysWellChiclet::setToggleState(BOOL toggled) {
+	mButton->setToggleState(toggled);
+}
+
+void LLSysWellChiclet::changeLitState(bool blink)
+{
+	setNewMessagesState(!mIsNewMessagesState);
+}
+
+void LLSysWellChiclet::setNewMessagesState(bool new_messages)
+{
+	/*
+	Emulate 4 states of button by background images, see detains in EXT-3147
+	xml attribute           Description
+	image_unselected        "Unlit" - there are no new messages
+	image_selected          "Unlit" + "Selected" - there are no new messages and the Well is open
+	image_pressed           "Lit" - there are new messages
+	image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well is open
+	*/
+	mButton->setForcePressedState(new_messages);
+
+	mIsNewMessagesState = new_messages;
+}
+
+void LLSysWellChiclet::updateWidget(bool is_window_empty)
+{
+	mButton->setEnabled(!is_window_empty);
+
+	if (LLChicletBar::instanceExists())
+	{
+		LLChicletBar::getInstance()->showWellButton(getName(), !is_window_empty);
+	}
+}
+// virtual
+BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	if(!mContextMenu)
+	{
+		createMenu();
+	}
+	if (mContextMenu)
+	{
+		mContextMenu->show(x, y);
+		LLMenuGL::showPopup(this, mContextMenu, x, y);
+	}
+	return TRUE;
+}
+
+/************************************************************************/
+/*               LLNotificationChiclet implementation                   */
+/************************************************************************/
+LLNotificationChiclet::LLNotificationChiclet(const Params& p)
+:	LLSysWellChiclet(p),
+	mUreadSystemNotifications(0)
+{
+	mNotificationChannel.reset(new ChicletNotificationChannel(this));
+	// ensure that notification well window exists, to synchronously
+	// handle toast add/delete events.
+	LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
+}
+
+void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
+{
+	std::string action = user_data.asString();
+	if("close all" == action)
+	{
+		LLNotificationWellWindow::getInstance()->closeAll();
+	}
+}
+
+bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data)
+{
+	std::string item = user_data.asString();
+	if (item == "can close all")
+	{
+		return mUreadSystemNotifications != 0;
+	}
+	return true;
+}
+
+void LLNotificationChiclet::createMenu()
+{
+	if(mContextMenu)
+	{
+		llwarns << "Menu already exists" << llendl;
+		return;
+	}
+
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	registrar.add("NotificationWellChicletMenu.Action",
+		boost::bind(&LLNotificationChiclet::onMenuItemClicked, this, _2));
+
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+	enable_registrar.add("NotificationWellChicletMenu.EnableItem",
+		boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
+
+	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
+		("menu_notification_well_button.xml",
+		 LLMenuGL::sMenuContainer,
+		 LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+/*virtual*/
+void LLNotificationChiclet::setCounter(S32 counter)
+{
+	LLSysWellChiclet::setCounter(counter);
+	updateWidget(getCounter() == 0);
+	
+}
+
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
+{
+	if (notification->getName() == "ScriptDialog")
+	{
+		return false;
+	}
+
+	if( !(notification->canLogToIM() && notification->hasFormElements())
+		&& (!notification->getPayload().has("give_inventory_notification")
+			|| notification->getPayload()["give_inventory_notification"]))
+	{
+		return true;
+	}
+	return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
 LLChiclet::Params::Params()
  : show_counter("show_counter", true)
  , enable_counter("enable_counter", false)
@@ -57,12 +248,6 @@ LLChiclet::LLChiclet(const Params& p)
 , mSessionId(LLUUID::null)
 , mShowCounter(p.show_counter)
 {
-
-}
-
-LLChiclet::~LLChiclet()
-{
-
 }
 
 boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
@@ -125,6 +310,15 @@ BOOL LLIMChiclet::postBuild()
 	return TRUE;
 }
 
+void LLIMChiclet::enableCounterControl(bool enable) 
+{
+	mCounterEnabled = enable;
+	if(!enable)
+	{
+		LLChiclet::setShowCounter(false);
+	}
+}
+
 void LLIMChiclet::setRequiredWidth()
 {
 	S32 required_width = mDefaultWidth;
@@ -791,13 +985,19 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
+LLChicletNotificationCounterCtrl::Params::Params()
+	: max_displayed_count("max_displayed_count", 99)
+{
+}
 
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
 LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
  : LLAvatarIconCtrl(p)
 {
 }
 
-
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index bd6c1a3e71..efaf03384a 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -29,10 +29,70 @@
 
 #include "llavatariconctrl.h"
 #include "llbutton.h"
+#include "llnotifications.h"
+#include "lltextbox.h"
 
 class LLMenuGL;
 class LLFloaterIMSession;
 
+/**
+ * Class for displaying amount of messages/notifications(unread).
+ */
+class LLChicletNotificationCounterCtrl : public LLTextBox
+{
+public:
+
+	struct Params :	public LLInitParam::Block<Params, LLTextBox::Params>
+	{
+		/**
+		 * Contains maximum displayed count of unread messages. Default value is 9.
+		 *
+		 * If count is less than "max_unread_count" will be displayed as is.
+		 * Otherwise 9+ will be shown (for default value).
+		 */
+		Optional<S32> max_displayed_count;
+
+		Params();
+	};
+
+	/**
+	 * Sets number of notifications
+	 */
+	virtual void setCounter(S32 counter);
+
+	/**
+	 * Returns number of notifications
+	 */
+	virtual S32 getCounter() const { return mCounter; }
+
+	/**
+	 * Returns width, required to display amount of notifications in text form.
+	 * Width is the only valid value.
+	 */
+	/*virtual*/ LLRect getRequiredRect();
+
+	/**
+	 * Sets number of notifications using LLSD
+	 */
+	/*virtual*/ void setValue(const LLSD& value);
+
+	/**
+	 * Returns number of notifications wrapped in LLSD
+	 */
+	/*virtual*/ LLSD getValue() const;
+
+protected:
+
+	LLChicletNotificationCounterCtrl(const Params& p);
+	friend class LLUICtrlFactory;
+
+private:
+
+	S32 mCounter;
+	S32 mInitialWidth;
+	S32 mMaxDisplayedCount;
+};
+
 /**
  * Class for displaying avatar's icon in P2P chiclet.
  */
@@ -104,7 +164,7 @@ public:
 		Params();
 	};
 
-	/*virtual*/ ~LLChiclet();
+	virtual ~LLChiclet() {}
 
 	/**
 	 * Associates chat session id with chiclet.
@@ -116,6 +176,11 @@ public:
 	 */
 	virtual const LLUUID& getSessionId() const { return mSessionId; }
 
+	/**
+	 * Sets show counter state.
+	 */
+	virtual void setShowCounter(bool show) { mShowCounter = show; }
+
 	/**
 	 * Connects chiclet clicked event with callback.
 	 */
@@ -194,6 +259,22 @@ public:
 	 */
 	BOOL postBuild();
 
+	/**
+	 * Sets IM session name. This name will be displayed in chiclet tooltip.
+	 */
+	virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
+
+	/**
+	 * Sets id of person/group user is chatting with.
+	 * Session id should be set before calling this
+	 */
+	virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
+
+	/**
+	 * Enables/disables the counter control for a chiclet.
+	 */
+	virtual void enableCounterControl(bool enable);
+
 	/**
 	* Sets required width for a chiclet according to visible controls.
 	*/
@@ -366,6 +447,131 @@ private:
 	LLChicletInvOfferIconCtrl* mChicletIconCtrl;
 };
 
+/**
+ * Implements notification chiclet. Used to display total amount of unread messages 
+ * across all IM sessions, total amount of system notifications. See EXT-3147 for details
+ */
+class LLSysWellChiclet : public LLChiclet
+{
+public:
+		
+	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+	{
+		Optional<LLButton::Params> button;
+
+		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
+
+		/**
+		 * Contains maximum displayed count of unread messages. Default value is 9.
+		 *
+		 * If count is less than "max_unread_count" will be displayed as is.
+		 * Otherwise 9+ will be shown (for default value).
+		 */
+		Optional<S32> max_displayed_count;
+
+		Params();
+	};
+
+	/*virtual*/ void setCounter(S32 counter);
+
+	// *TODO: mantipov: seems getCounter is not necessary for LLNotificationChiclet
+	// but inherited interface requires it to implement. 
+	// Probably it can be safe removed.
+	/*virtual*/S32 getCounter() { return mCounter; }
+
+	boost::signals2::connection setClickCallback(const commit_callback_t& cb);
+
+	/*virtual*/ ~LLSysWellChiclet();
+
+	void setToggleState(BOOL toggled);
+
+	void setNewMessagesState(bool new_messages);
+	//this method should change a widget according to state of the SysWellWindow 
+	virtual void updateWidget(bool is_window_empty);
+
+protected:
+
+	LLSysWellChiclet(const Params& p);
+	friend class LLUICtrlFactory;
+
+	/**
+	 * Change Well 'Lit' state from 'Lit' to 'Unlit' and vice-versa.
+	 *
+	 * There is an assumption that it will be called 2*N times to do not change its start state.
+	 * @see FlashToLitTimer
+	 */
+	void changeLitState(bool blink);
+
+	/**
+	 * Displays menu.
+	 */
+	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+	virtual void createMenu() = 0;
+
+protected:
+	class FlashToLitTimer;
+	LLButton* mButton;
+	S32 mCounter;
+	S32 mMaxDisplayedCount;
+	bool mIsNewMessagesState;
+
+	LLFlashTimer* mFlashToLitTimer;
+	LLContextMenu* mContextMenu;
+};
+
+class LLNotificationChiclet : public LLSysWellChiclet
+{
+	LOG_CLASS(LLNotificationChiclet);
+			
+	friend class LLUICtrlFactory;
+public:
+	struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
+		
+protected:
+	struct ChicletNotificationChannel : public LLNotificationChannel
+	{
+		ChicletNotificationChannel(LLNotificationChiclet* chiclet) 
+			: LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString()))
+			, mChiclet(chiclet)
+		{
+			// connect counter handlers to the signals
+			connectToChannel("Group Notifications");
+			connectToChannel("Offer");
+			connectToChannel("Notifications");
+		}
+				
+		static bool filterNotification(LLNotificationPtr notify);
+		// connect counter updaters to the corresponding signals
+		/*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
+		/*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
+				
+		LLNotificationChiclet* const mChiclet;
+	};
+				
+	boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
+				
+	LLNotificationChiclet(const Params& p);
+				
+	/**
+	 * Processes clicks on chiclet menu.
+	 */
+	void onMenuItemClicked(const LLSD& user_data);
+				
+	/**
+	 * Enables chiclet menu items.
+	 */
+	bool enableMenuItem(const LLSD& user_data);
+				
+	/**
+	 * Creates menu.
+	 */
+	/*virtual*/ void createMenu();
+
+	/*virtual*/ void setCounter(S32 counter);
+	S32 mUreadSystemNotifications;
+};
+
 /**
  * Storage class for all IM chiclets. Provides mechanism to display, 
  * scroll, create, remove chiclets.
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index fde7764129..a51c844775 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -30,6 +30,7 @@
 #include "llchiclet.h"
 #include "lllayoutstack.h"
 #include "llpaneltopinfobar.h"
+#include "llsyswellwindow.h"
 
 namespace
 {
@@ -58,6 +59,8 @@ BOOL LLChicletBar::postBuild()
 	mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
 	mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
 
+	showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
+
 	LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
 	LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
 
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 8a43855a7d..e92bd766ca 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -40,6 +40,7 @@
 LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true,  key),
 													mChannel(NULL),
 													mMessageList(NULL),
+													mSysWellChiclet(NULL),
 													NOTIFICATION_WELL_ANCHOR_NAME("notification_well_panel"),
 													IM_WELL_ANCHOR_NAME("im_well_panel"),
 													mIsReshapedByUser(false)
@@ -79,6 +80,15 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
 	setVisible(TRUE);
 }
 
+void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet) 
+{ 
+	mSysWellChiclet = chiclet;
+	if(NULL != mSysWellChiclet)
+	{
+		mSysWellChiclet->updateWidget(isWindowEmpty());
+	}
+}
+
 //---------------------------------------------------------------------------------
 LLSysWellWindow::~LLSysWellWindow()
 {
@@ -89,6 +99,10 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
 {
 	if(mMessageList->removeItemByValue(id))
 	{
+		if (NULL != mSysWellChiclet)
+		{
+			mSysWellChiclet->updateWidget(isWindowEmpty());
+		}
 		reshapeWindow();
 	}
 	else
@@ -334,6 +348,7 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
 	LLSysWellItem* new_item = new LLSysWellItem(p);
 	if (mMessageList->addItem(new_item, value, ADD_TOP))
 	{
+		mSysWellChiclet->updateWidget(isWindowEmpty());
 		reshapeWindow();
 		new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
 		new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 406ab1b59e..cc5c057d8b 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -66,6 +66,8 @@ public:
 
 	void onStartUpToastClick(S32 x, S32 y, MASK mask);
 
+	void setSysWellChiclet(LLSysWellChiclet* chiclet);
+
 	// size constants for the window and for its elements
 	static const S32 MAX_WINDOW_HEIGHT		= 200;
 	static const S32 MIN_WINDOW_WIDTH		= 318;
@@ -84,6 +86,11 @@ protected:
 	LLNotificationsUI::LLScreenChannel*	mChannel;
 	LLFlatListView*	mMessageList;
 
+	/**
+	 * Reference to an appropriate Well chiclet to release "new message" state. EXT-3147
+	 */
+	LLSysWellChiclet* mSysWellChiclet;
+
 	bool mIsReshapedByUser;
 };
 
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index bf6e933dfd..a07d7e4855 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -365,6 +365,8 @@ with the same filename but different name
 
   <texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" />
 
+  <texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" />
+
   <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" />
   <texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" />
 
diff --git a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
new file mode 100644
index 0000000000..40b35b5fdd
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Luk alle" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
new file mode 100644
index 0000000000..0f2784f160
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Alle schließen" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
new file mode 100644
index 0000000000..263ac40f4e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Notification Well Button Context Menu">
+    <menu_item_call
+     label="Close All"
+     layout="topleft"
+     name="Close All">
+        <menu_item_call.on_click
+         function="NotificationWellChicletMenu.Action"
+         parameter="close all" />
+        <menu_item_call.on_enable
+         function="NotificationWellChicletMenu.EnableItem"
+         parameter="can close all" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
index 390047d493..fc321fdd23 100644
--- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
@@ -77,5 +77,49 @@
                  width="12" />
       </chiclet_panel>
     </layout_panel>
+    <layout_panel auto_resize="false"
+                      width="4"
+                      min_width="4"/>
+    <layout_panel
+         auto_resize="false"
+         follows="right"
+         height="28"
+         layout="topleft"
+         min_height="28"
+         min_width="37"
+         name="notification_well_panel"
+         top="0"
+         width="37">
+      <chiclet_notification
+             follows="right"
+             height="23"
+             layout="topleft"
+             left="0"
+             max_displayed_count="99"
+             name="notification_well"
+             top="5"
+             width="35">
+        <button
+                 auto_resize="false"
+                 bottom_pad="3"
+                 follows="right"
+                 halign="center"
+                 height="23"
+                 image_overlay="Notices_Unread"
+                 image_overlay_alignment="center"
+                 image_pressed="WellButton_Lit"
+                 image_pressed_selected="WellButton_Lit_Selected"
+                 image_selected="PushButton_Press"
+                 label_color="Black"
+                 left="0"
+                 name="Unread"
+                 tool_tip="Notifications"
+                 width="34">
+          <init_callback
+                     function="Button.SetDockableFloaterToggle"
+                     parameter="notification_well_window" />
+        </button>
+      </chiclet_notification>
+    </layout_panel>
   </layout_stack>
 </panel>
diff --git a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
new file mode 100644
index 0000000000..0562d35be7
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Cerrar todo" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
new file mode 100644
index 0000000000..323bfdbf16
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Tout fermer" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
new file mode 100644
index 0000000000..8c82e30f0e
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Chiudi tutto" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
new file mode 100644
index 0000000000..913bae8958
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="すべて閉じる" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
new file mode 100644
index 0000000000..bd3d42f9b1
--- /dev/null
+++ b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Zamknij" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
new file mode 100644
index 0000000000..43ad4134ec
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Fechar tudo" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
new file mode 100644
index 0000000000..4d067e232a
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Закрыть все" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
new file mode 100644
index 0000000000..39c66268f5
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Tümünü Kapat" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
new file mode 100644
index 0000000000..b629f73584
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="全部關閉" name="Close All"/>
+</context_menu>
-- 
cgit v1.2.3


From 13a619cb5fc8da621d4e7becbf95ca2a8014deb3 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 18 Dec 2012 18:15:28 -0800
Subject: CHUI-385: Problem: When the new session was created with multiple
 participants the old conversation floater was being recycled. When the
 conversation floater was re-initialized it did not remove and update the chat
 messages. Resolution: When the conversation floater is recycled simply call
 reloadMessages().

---
 indra/newview/llfloaterimsession.cpp | 5 +----
 indra/newview/llfloaterimsession.h   | 4 ----
 indra/newview/llimview.cpp           | 3 ++-
 3 files changed, 3 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index f2afe9d7bb..ff07ddfcbf 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -73,8 +73,7 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
 	mTypingTimer(),
 	mTypingTimeoutTimer(),
 	mPositioned(false),
-	mSessionInitialized(false),
-	mStartConferenceInSameFloater(false)
+	mSessionInitialized(false)
 {
 	mIsNearbyChat = false;
 
@@ -462,8 +461,6 @@ void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, con
 		return;
 	}
 
-	mStartConferenceInSameFloater = true;
-
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
 
 	// first check whether this is a voice session
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 43d84eb8c0..6a2f4b29eb 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -127,8 +127,6 @@ public:
 	//used as a callback on receiving new IM message
 	static void sRemoveTypingIndicator(const LLSD& data);
 	static void onIMChicletCreated(const LLUUID& session_id);
-
-	bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
     const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;}
 
 	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
@@ -188,8 +186,6 @@ private:
 	bool mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
 
-	bool mStartConferenceInSameFloater;
-
 	uuid_vec_t mInvitedParticipants;
 
 	// connection to voice channel state change signal
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index da3d2e89bf..868dba9687 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2699,12 +2699,13 @@ LLUUID LLIMMgr::addSession(
 	{
 		LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(floater_id);
 
-		if (im_floater && im_floater->getStartConferenceInSameFloater())
+		if (im_floater)
 		{
 			// The IM floater should be initialized with a new session_id
 			// so that it is found by that id when creating a chiclet in LLFloaterIMSession::onIMChicletCreated,
 			// and a new floater is not created.
 			im_floater->initIMSession(session_id);
+            im_floater->reloadMessages();
 		}
 	}
 
-- 
cgit v1.2.3


From c73947ac1fc6c48bca75ea7d6beeda63eb695b2b Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 18 Dec 2012 18:48:15 -0800
Subject: CHUI-499: Adding ability to serialize the communication notifications
 to local disk per user.

---
 indra/llui/llnotifications.cpp                     |   2 +
 indra/llui/llnotifications.h                       |   3 +
 indra/newview/CMakeLists.txt                       |   4 +
 indra/newview/llchannelmanager.cpp                 |   2 +
 indra/newview/llcommunicationchannel.cpp           |  73 ++++++++++++++
 indra/newview/llcommunicationchannel.h             |  59 ++++++++++++
 .../newview/lldonotdisturbnotificationstorage.cpp  | 106 +++++++++++++++++++++
 indra/newview/lldonotdisturbnotificationstorage.h  |  57 +++++++++++
 indra/newview/llimview.cpp                         |   6 +-
 indra/newview/llnotificationhandler.h              |   1 -
 indra/newview/llviewerwindow.cpp                   |   3 +-
 11 files changed, 311 insertions(+), 5 deletions(-)
 create mode 100644 indra/newview/llcommunicationchannel.cpp
 create mode 100644 indra/newview/llcommunicationchannel.h
 create mode 100644 indra/newview/lldonotdisturbnotificationstorage.cpp
 create mode 100644 indra/newview/lldonotdisturbnotificationstorage.h

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 937dcf0afc..c9b4399bef 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -992,10 +992,12 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 	bool abortProcessing = false;
 	if (passesFilter)
 	{
+		onFilterPass(pNotification);
 		abortProcessing = mPassedFilter(payload);
 	}
 	else
 	{
+		onFilterFail(pNotification);
 		abortProcessing = mFailedFilter(payload);
 	}
 	
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 8bb79b57e3..42dee4c3e9 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -774,6 +774,9 @@ protected:
 	virtual void onDelete(LLNotificationPtr p) {}
 	virtual void onChange(LLNotificationPtr p) {}
 
+	virtual void onFilterPass(LLNotificationPtr p) {}
+	virtual void onFilterFail(LLNotificationPtr p) {}
+
 	bool updateItem(const LLSD& payload, LLNotificationPtr pNotification);
 	LLNotificationFilter mFilter;
 };
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index da1d96414b..d43f9e9988 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -137,6 +137,7 @@ set(viewer_SOURCE_FILES
     llcommanddispatcherlistener.cpp
     llcommandhandler.cpp
     llcommandlineparser.cpp
+    llcommunicationchannel.cpp
     llcompilequeue.cpp
     llconfirmationmanager.cpp
     llconversationlog.cpp
@@ -152,6 +153,7 @@ set(viewer_SOURCE_FILES
     lldebugview.cpp
     lldelayedgestureerror.cpp
     lldirpicker.cpp
+    lldonotdisturbnotificationstorage.cpp
     lldndbutton.cpp
     lldrawable.cpp
     lldrawpool.cpp
@@ -723,6 +725,7 @@ set(viewer_HEADER_FILES
     llcommanddispatcherlistener.h
     llcommandhandler.h
     llcommandlineparser.h
+    llcommunicationchannel.h
     llcompilequeue.h
     llconfirmationmanager.h
     llconversationlog.h
@@ -738,6 +741,7 @@ set(viewer_HEADER_FILES
     lldebugview.h
     lldelayedgestureerror.h
     lldirpicker.h
+    lldonotdisturbnotificationstorage.h
     lldndbutton.h
     lldrawable.h
     lldrawpool.h
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 79e2d376ea..dd2bcc742b 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -29,6 +29,7 @@
 #include "llchannelmanager.h"
 
 #include "llappviewer.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llpersistentnotificationstorage.h"
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
@@ -138,6 +139,7 @@ void LLChannelManager::onLoginCompleted()
 	}
 
 	LLPersistentNotificationStorage::getInstance()->loadNotifications();
+	LLDoNotDisturbNotificationStorage::getInstance()->initialize();
 }
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
new file mode 100644
index 0000000000..353447e4b6
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -0,0 +1,73 @@
+/** 
+* @file llcommunicationchannel.cpp
+* @brief Implementation of llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llcommunicationchannel.h"
+
+#include <string>
+#include <map>
+
+#include "llagent.h"
+#include "lldate.h"
+#include "llnotifications.h"
+
+
+LLCommunicationChannel::LLCommunicationChannel(const std::string& pName, const std::string& pParentName)
+	: LLNotificationChannel(pName, pParentName, filterByDoNotDisturbStatus)
+{
+}
+
+LLCommunicationChannel::~LLCommunicationChannel()
+{
+}
+
+bool LLCommunicationChannel::filterByDoNotDisturbStatus(LLNotificationPtr)
+{
+	return !gAgent.isDoNotDisturb();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::beginHistory() const
+{
+	return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::endHistory() const
+{
+	return mHistory.end();
+}
+
+void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
+{
+	std::string notificationType = pNotificationPtr->getType();
+	if ((notificationType == "groupnotify")
+		|| (notificationType == "offer")
+		|| (notificationType == "notifytoast"))
+	{
+		mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr));
+	}
+}
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
new file mode 100644
index 0000000000..a4756b8993
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.h
@@ -0,0 +1,59 @@
+/** 
+* @file   llcommunicationchannel.h
+* @brief  Header file for llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLCOMMUNICATIONCHANNEL_H
+#define LL_LLCOMMUNICATIONCHANNEL_H
+
+#include <string>
+#include <map>
+
+#include "lldate.h"
+#include "llerror.h"
+#include "llnotifications.h"
+
+class LLCommunicationChannel : public LLNotificationChannel
+{
+	LOG_CLASS(LLCommunicationChannel);
+public:
+	LLCommunicationChannel(const std::string& pName, const std::string& pParentName);
+	virtual ~LLCommunicationChannel();
+
+	static bool filterByDoNotDisturbStatus(LLNotificationPtr);
+
+	typedef std::multimap<LLDate, LLNotificationPtr> history_list_t;
+	history_list_t::const_iterator beginHistory() const;
+	history_list_t::const_iterator endHistory() const;
+
+protected:
+	virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
+
+private:
+
+	history_list_t mHistory;
+};
+
+#endif // LL_LLCOMMUNICATIONCHANNEL_H
+
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
new file mode 100644
index 0000000000..472a0dd9ee
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -0,0 +1,106 @@
+/** 
+* @file lldonotdisturbnotificationstorage.cpp
+* @brief Implementation of lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldonotdisturbnotificationstorage.h"
+
+#include "llcommunicationchannel.h"
+#include "lldir.h"
+#include "llerror.h"
+#include "llfasttimer_class.h"
+#include "llnotifications.h"
+#include "llnotificationstorage.h"
+#include "llsd.h"
+#include "llsingleton.h"
+
+LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
+	: LLSingleton<LLDoNotDisturbNotificationStorage>()
+	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
+{
+}
+
+LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
+{
+}
+
+void LLDoNotDisturbNotificationStorage::initialize()
+{
+	getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::saveNotifications()
+{
+	LLFastTimer _(FTM_SAVE_DND_NOTIFICATIONS);
+
+	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+	const LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+	llassert(commChannel != NULL);
+
+	LLSD output = LLSD::emptyMap();
+	LLSD& data = output["data"];
+	data = LLSD::emptyArray();
+
+	for (LLCommunicationChannel::history_list_t::const_iterator historyIter = commChannel->beginHistory();
+		historyIter != commChannel->endHistory(); ++historyIter)
+	{
+		LLNotificationPtr notificationPtr = historyIter->second;
+
+		if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && !notificationPtr->isExpired())
+		{
+			data.append(notificationPtr->asLLSD());
+		}
+	}
+
+	writeNotifications(output);
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::loadNotifications()
+{
+}
+
+LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
+{
+	LLNotificationChannelPtr channelPtr = LLNotifications::getInstance()->getChannel("Communication");
+	llassert(channelPtr);
+	return channelPtr;
+}
+
+
+bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
+{
+	if (pPayload["sigtype"].asString() != "load")
+	{
+		saveNotifications();
+	}
+
+	return false;
+}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
new file mode 100644
index 0000000000..60bcd89ec3
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -0,0 +1,57 @@
+/** 
+* @file   lldonotdisturbnotificationstorage.h
+* @brief  Header file for lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+#define LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "llnotifications.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage
+{
+	LOG_CLASS(LLDoNotDisturbNotificationStorage);
+public:
+	LLDoNotDisturbNotificationStorage();
+	~LLDoNotDisturbNotificationStorage();
+
+	void initialize();
+
+	void saveNotifications();
+	void loadNotifications();
+
+protected:
+
+private:
+	LLNotificationChannelPtr getCommunicationChannel() const;
+	bool                     onChannelChanged(const LLSD& pPayload);
+};
+
+#endif // LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c9672413bf..26be7f6bbf 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -149,7 +149,7 @@ void on_new_message(const LLSD& msg)
     }
 
     // do not show notification in "do not disturb" mode or it goes from agent
-    if (gAgent.isDoNotDisturb() || gAgent.getID() == participant_id)
+    if (gAgent.getID() == participant_id)
     {
         return;
     }
@@ -2500,7 +2500,7 @@ void LLIMMgr::addMessage(
 	}
 
 	bool new_session = !hasSession(new_session_id);
-	if (new_session && !gAgent.isDoNotDisturb())
+	if (new_session)
 	{
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
@@ -2543,7 +2543,7 @@ void LLIMMgr::addMessage(
 		}
 
         //Play sound for new conversations
-        if(gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE)
+		if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
         {
             make_ui_sound("UISndNewIncomingIMSession");
         }
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index a78f0c067b..bff4efa9ea 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -119,7 +119,6 @@ public:
 /**
  * Handler for chat message notifications. 
  */
-// XXX stinson 12/06/2012 : can I just remove the LLChatHandler class?
 class LLChatHandler : public LLEventHandler
 {
 public:
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 424898536e..1c463015e2 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -37,6 +37,7 @@
 
 #include "llagent.h"
 #include "llagentcamera.h"
+#include "llcommunicationchannel.h"
 #include "llfloaterreg.h"
 #include "llmeshrepository.h"
 #include "llnotificationhandler.h"
@@ -1557,7 +1558,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mViewerWindowListener.reset(new LLViewerWindowListener(this));
 
 	mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
-	mCommunicationChannel.reset(new LLNotificationChannel("Communication", "Visible", !boost::bind(&LLAgent::isDoNotDisturb, &gAgent)));
+	mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible"));
 	mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
 	mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
 
-- 
cgit v1.2.3


From a4975ace20faa3b6de952f26865dca53dcb9060c Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 18 Dec 2012 19:10:19 -0800
Subject: CHUI-569: Ensure that we create a friend request notification even in
 the case of do-not-disturb mode.  The DND mode will log it to a file to be
 re-created when DND mode is exited.

---
 indra/newview/llviewermessage.cpp | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 5bb7db5c0d..04dd7c911b 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3169,17 +3169,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			payload["online"] = (offline == IM_ONLINE);
 			payload["sender"] = msg->getSender().getIPandPort();
 
-			if (is_do_not_disturb)
-			{
-				send_do_not_disturb_message(msg, from_id);
-				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
-			}
-			else if (is_muted)
+			if (is_muted)
 			{
 				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
 			}
 			else
 			{
+				if (is_do_not_disturb)
+				{
+					send_do_not_disturb_message(msg, from_id);
+				}
 				args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
 				if(message.empty())
 				{
-- 
cgit v1.2.3


From da59ef8013801eac3695cea0ae8c1097275b6832 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 18 Dec 2012 19:22:21 -0800
Subject: Removing copy from the DoNotDisturbModeSet notification as we are no
 longer auto deleting inventory offers.

---
 indra/newview/skins/default/xui/en/notifications.xml | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 94307d2f93..35ce787847 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3696,7 +3696,6 @@ Do Not Disturb is on.  You will not be notified of incoming communications.
 - Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
 - Teleportation offers will be declined.
 - Voice calls will be rejected.
-- Inventory offers will go to your Trash.
     <usetemplate
      ignoretext="I change my status to Do Not Disturb mode"
      name="okignore"
-- 
cgit v1.2.3


From 8adca4583ec95ac063f79990ac092998f24415b8 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 18 Dec 2012 22:57:56 -0800
Subject: CHUI-600 : WIP : Flash conversation item in different color than
 select and start flashing only when shown

---
 indra/llui/llfolderviewitem.cpp        | 46 +++++++++++++++++++++-------------
 indra/llui/llfolderviewitem.h          |  5 +++-
 indra/newview/llconversationview.cpp   | 20 ++++++++++++---
 indra/newview/llconversationview.h     |  5 +++-
 indra/newview/skins/default/colors.xml |  6 +++++
 5 files changed, 60 insertions(+), 22 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 0a06ce66aa..100904c5a2 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -50,6 +50,7 @@ std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
 bool LLFolderViewItem::sColorSetInitialized = false;
 LLUIColor LLFolderViewItem::sFgColor;
 LLUIColor LLFolderViewItem::sHighlightBgColor;
+LLUIColor LLFolderViewItem::sFlashBgColor;
 LLUIColor LLFolderViewItem::sFocusOutlineColor;
 LLUIColor LLFolderViewItem::sMouseOverColor;
 LLUIColor LLFolderViewItem::sFilterBGColor;
@@ -151,6 +152,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	{
 		sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
 		sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+		sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
 		sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
 		sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 		sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
@@ -686,26 +688,31 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
 	return mIsCurSelection;
 }
 
-void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, 
+void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor,  
                                                         const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
 {
-
-    //--------------------------------------------------------------------------------//
-    // Draw highlight for selected items
-    //
-
     const S32 focus_top = getRect().getHeight();
     const S32 focus_bottom = getRect().getHeight() - mItemHeight;
     const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
     const S32 FOCUS_LEFT = 1;
+	
+	// Determine which background color to use for highlighting
+	LLUIColor bgColor = (isFlashing() ? flashColor : selectColor);
 
-    if (isHighlightAllowed())	// always render "current" item (only render other selected items if
-    							// mShowSingleSelection is FALSE) or flashing item
+    //--------------------------------------------------------------------------------//
+    // Draw highlight for selected items
+	// Note: Always render "current" item or flashing item, only render other selected 
+	// items if mShowSingleSelection is FALSE.
+    //
+    if (isHighlightAllowed())	
+    							
     {
         gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-        LLColor4 bg_color = bgColor;
-        if (!isHighlightActive())
+		
+		// Highlight for selected but not current items
+        if (!isHighlightActive() && !isFlashing())
         {
+			LLColor4 bg_color = bgColor;
             // do time-based fade of extra objects
             F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
             if (getRoot() && getRoot()->getShowSingleSelection())
@@ -718,25 +725,30 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
                 // fading in
                 bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
             }
+        	gl_rect_2d(FOCUS_LEFT,
+					   focus_top,
+					   getRect().getWidth() - 2,
+					   focus_bottom,
+					   bg_color, hasKeyboardFocus);
         }
 
-        if (isHighlightAllowed() || isHighlightActive())
+		// Highlight for currently selected or flashing item
+        if (isHighlightActive())
         {
+			// Background
         	gl_rect_2d(FOCUS_LEFT,
                 focus_top,
                 getRect().getWidth() - 2,
                 focus_bottom,
-                bg_color, hasKeyboardFocus);
-        }
-
-        if (isHighlightActive())
-        {
+                bgColor, hasKeyboardFocus);
+			// Outline
             gl_rect_2d(FOCUS_LEFT, 
                 focus_top, 
                 getRect().getWidth() - 2,
                 focus_bottom,
                 focusOutlineColor, FALSE);
         }
+
         if (folder_open)
         {
             gl_rect_2d(FOCUS_LEFT,
@@ -810,7 +822,7 @@ void LLFolderViewItem::draw()
 
     drawOpenFolderArrow(default_params, sFgColor);
 
-    drawHighlight(show_context, filled, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+    drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
 
 	//--------------------------------------------------------------------------------//
 	// Draw open icon
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index d7f5e86aea..ca31931e19 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -128,6 +128,7 @@ protected:
 	static LLUIColor			sFgColor;
 	static LLUIColor			sFgDisabledColor;
 	static LLUIColor			sHighlightBgColor;
+	static LLUIColor			sFlashBgColor;
 	static LLUIColor			sFocusOutlineColor;
 	static LLUIColor			sMouseOverColor;
 	static LLUIColor			sFilterBGColor;
@@ -141,6 +142,8 @@ protected:
 	virtual void addFolder(LLFolderViewFolder*) { }
 	virtual bool isHighlightAllowed();
 	virtual bool isHighlightActive();
+	virtual bool isFlashing() { return false; }
+	virtual void setFlashState(bool) { }
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
@@ -269,7 +272,7 @@ public:
 	//	virtual void handleDropped();
 	virtual void draw();
 	void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
-    void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
+    void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
     void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 									EDragAndDropType cargo_type,
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index c0a209f22d..d3a0e882f5 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -101,7 +101,17 @@ LLConversationViewSession::~LLConversationViewSession()
 void LLConversationViewSession::setFlashState(bool flash_state)
 {
 	mFlashStateOn = flash_state;
-	(flash_state ? mFlashTimer->startFlashing() : mFlashTimer->stopFlashing());
+	mFlashStarted = false;
+	mFlashTimer->stopFlashing();
+}
+
+void LLConversationViewSession::startFlashing()
+{
+	if (mFlashStateOn && !mFlashStarted)
+	{
+		mFlashStarted = true;
+		mFlashTimer->startFlashing();
+	}
 }
 
 bool LLConversationViewSession::isHighlightAllowed()
@@ -198,8 +208,11 @@ void LLConversationViewSession::draw()
 		drawOpenFolderArrow(default_params, sFgColor);
 	}
 
+	// Indicate that flash can start (moot operation if already started, done or not flashing)
+	startFlashing();
+
 	// draw highlight for selected items
-	drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+	drawHighlight(show_context, true, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
 
 	// Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap.
 	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen();
@@ -427,6 +440,7 @@ void LLConversationViewParticipant::draw()
 	static LLUIColor sFgDisabledColor = LLUIColorTable::instance().getColor("MenuItemDisabledColor", DEFAULT_WHITE);
     static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
     static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+    static LLUIColor sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
     static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
     static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 
@@ -450,7 +464,7 @@ void LLConversationViewParticipant::draw()
 		color = mIsSelected ? sHighlightFgColor : sFgColor;
 	}
 
-    drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+    drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
     drawLabel(font, text_left, y, color, right_x);
 	refresh();
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 1e20fb8b7e..74443e1d88 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -58,6 +58,7 @@ protected:
 
 	/*virtual*/ bool isHighlightAllowed();
 	/*virtual*/ bool isHighlightActive();
+	/*virtual*/ bool isFlashing() { return mFlashStateOn; }
 
 	LLFloaterIMContainer* mContainer;
 	
@@ -83,11 +84,12 @@ public:
 
 	virtual void refresh();
 
-	void setFlashState(bool flash_state);
+	/*virtual*/ void setFlashState(bool flash_state);
 
 private:
 
 	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
+	void startFlashing();
 
 	LLPanel*				mItemPanel;
 	LLPanel*				mCallIconLayoutPanel;
@@ -95,6 +97,7 @@ private:
 	LLOutputMonitorCtrl*	mSpeakingIndicator;
 	LLFlashTimer*			mFlashTimer;
 	bool					mFlashStateOn;
+	bool					mFlashStarted;
 
 	bool					mCollapsedMode;
     bool                    mHasArrow;
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 05230b8bd5..becdbda067 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -11,6 +11,9 @@
 	<color
 	 name="EmphasisColor_35"
 	 value="0.38 0.694 0.573 0.35" />
+	<color
+	 name="BeaconColor"
+    value="1 .67 .2 1" />	 
 	<color
 	 name="White"
 	 value="1 1 1 1" />
@@ -522,6 +525,9 @@
     <color
      name="MenuItemHighlightBgColor"
      reference="EmphasisColor_35" />
+    <color
+     name="MenuItemFlashBgColor"
+     reference="BeaconColor" />
     <color
      name="MenuItemHighlightFgColor"
      reference="White" />
-- 
cgit v1.2.3


From 6b9ead91459d702727b54ab7e51614c2d5959f5f Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Tue, 18 Dec 2012 23:07:27 -0800
Subject: CHUI-499: Refactoring the LLPersistentNotificationStorage
 implementation for shared usage with the new
 LLDoNotDisturbNotificationStorage class.

---
 indra/newview/llnotificationstorage.cpp           | 69 +++++++++++++++++++++++
 indra/newview/llnotificationstorage.h             |  3 +
 indra/newview/llpersistentnotificationstorage.cpp | 67 +---------------------
 3 files changed, 73 insertions(+), 66 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index d25a212059..4746e4bbd4 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -29,14 +29,39 @@
 #include "llnotificationstorage.h"
 
 #include <string>
+#include <map>
 
 #include "llerror.h"
 #include "llfile.h"
+#include "llnotifications.h"
 #include "llpointer.h"
 #include "llsd.h"
 #include "llsdserialize.h"
+#include "llsingleton.h"
+#include "llviewermessage.h"
 
 
+class LLResponderRegistry : public LLSingleton<LLResponderRegistry>
+{
+public:
+	LLResponderRegistry();
+	~LLResponderRegistry();
+	
+	LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams);
+	
+protected:
+	
+private:
+	template<typename RESPONDER_TYPE> static LLNotificationResponderInterface* create(const LLSD& pParams);
+	
+	typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
+	
+	void add(const std::string& pNotificationName, const responder_constructor_t& pConstructor);
+	
+	typedef std::map<std::string, responder_constructor_t> build_map_t;
+	build_map_t mBuildMap;
+};
+
 LLNotificationStorage::LLNotificationStorage(std::string pFileName)
 	: mFileName(pFileName)
 {
@@ -90,3 +115,47 @@ bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
 
 	return didFileRead;
 }
+
+LLNotificationResponderInterface* LLNotificationStorage::createResponder(const std::string& pNotificationName, const LLSD& pParams) const
+{
+	return LLResponderRegistry::getInstance()->createResponder(pNotificationName, pParams);
+}
+
+LLResponderRegistry::LLResponderRegistry()
+	: LLSingleton<LLResponderRegistry>()
+	, mBuildMap()
+{
+	add("ObjectGiveItem", &create<LLOfferInfo>);
+	add("UserGiveItem", &create<LLOfferInfo>);
+}
+
+LLResponderRegistry::~LLResponderRegistry()
+{
+}
+
+LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& pNotificationName, const LLSD& pParams)
+{
+	build_map_t::const_iterator it = mBuildMap.find(pNotificationName);
+	if(mBuildMap.end() == it)
+	{
+		return NULL;
+	}
+	responder_constructor_t ctr = it->second;
+	return ctr(pParams);
+}
+
+template<typename RESPONDER_TYPE> LLNotificationResponderInterface* LLResponderRegistry::create(const LLSD& pParams)
+{
+	RESPONDER_TYPE* responder = new RESPONDER_TYPE();
+	responder->fromLLSD(pParams);
+	return responder;
+}
+	
+void LLResponderRegistry::add(const std::string& pNotificationName, const responder_constructor_t& pConstructor)
+{
+	if (mBuildMap.find(pNotificationName) != mBuildMap.end())
+	{
+		LL_ERRS("LLResponderRegistry") << "Responder is already registered : " << pNotificationName << LL_ENDL;
+	}
+	mBuildMap.insert(std::make_pair<std::string, responder_constructor_t>(pNotificationName, pConstructor));
+}
diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h
index ab4da4e73f..7aabf7d09e 100644
--- a/indra/newview/llnotificationstorage.h
+++ b/indra/newview/llnotificationstorage.h
@@ -31,6 +31,7 @@
 
 #include "llerror.h"
 
+class LLNotificationResponderInterface;
 class LLSD;
 
 class LLNotificationStorage
@@ -44,6 +45,8 @@ protected:
 	bool writeNotifications(const LLSD& pNotificationData) const;
 	bool readNotifications(LLSD& pNotificationData) const;
 
+	LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams) const;
+
 private:
 	std::string mFileName;
 };
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 7aaad64fd7..224aaa2146 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -36,34 +36,6 @@
 #include "llscriptfloater.h"
 #include "llviewermessage.h"
 
-class LLResponderRegistry
-{
-public:
-
-	static void registerResponders();
-
-	static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
-
-protected:
-
-private:
-	template<typename RESPONDER_TYPE>
-	static LLNotificationResponderInterface* create(const LLSD& params)
-	{
-		RESPONDER_TYPE* responder = new RESPONDER_TYPE();
-		responder->fromLLSD(params);
-		return responder;
-	}
-
-	typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
-
-	static void add(const std::string& notification_name, const responder_constructor_t& ctr);
-
-	typedef std::map<std::string, responder_constructor_t> build_map_t;
-
-	static build_map_t sBuildMap;
-};
-
 LLPersistentNotificationStorage::LLPersistentNotificationStorage()
 	: LLSingleton<LLPersistentNotificationStorage>()
 	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"))
@@ -114,7 +86,6 @@ static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
 void LLPersistentNotificationStorage::loadNotifications()
 {
 	LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
-	LLResponderRegistry::registerResponders();
 
 	LLNotifications::instance().getChannel("Persistent")->
 		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
@@ -144,8 +115,7 @@ void LLPersistentNotificationStorage::loadNotifications()
 		LLSD notification_params = *notification_it;
 		LLNotificationPtr notification(new LLNotification(notification_params));
 
-		LLNotificationResponderPtr responder(LLResponderRegistry::
-			createResponder(notification_params["name"], notification_params["responder"]));
+		LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"]));
 		notification->setResponseFunctor(responder);
 
 		instance.add(notification);
@@ -172,39 +142,4 @@ bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& pay
 	return false;
 }
 
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
-
-void LLResponderRegistry::registerResponders()
-{
-	sBuildMap.clear();
-
-	add("ObjectGiveItem", &create<LLOfferInfo>);
-	add("UserGiveItem", &create<LLOfferInfo>);
-}
-
-LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
-{
-	build_map_t::const_iterator it = sBuildMap.find(notification_name);
-	if(sBuildMap.end() == it)
-	{
-		return NULL;
-	}
-	responder_constructor_t ctr = it->second;
-	return ctr(params);
-}
-
-void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
-{
-	if(sBuildMap.find(notification_name) != sBuildMap.end())
-	{
-		llwarns << "Responder is already registered : " << notification_name << llendl;
-		llassert(!"Responder already registered");
-	}
-	sBuildMap[notification_name] = ctr;
-}
-
 // EOF
-- 
cgit v1.2.3


From bd6d34d312c3e3322ab62f3a60253fb88fcbc9e3 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Wed, 19 Dec 2012 01:48:37 -0800
Subject: CHUI-499: Loading the DND notifications upon exit from DND mode and
 after login.

---
 indra/newview/llagent.cpp                          | 14 ++--
 indra/newview/llchannelmanager.cpp                 |  2 +
 indra/newview/llcommunicationchannel.cpp           |  6 ++
 indra/newview/llcommunicationchannel.h             |  2 +
 .../newview/lldonotdisturbnotificationstorage.cpp  | 76 ++++++++++++++++++++++
 5 files changed, 96 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 49c570c30b..fc3be9ca21 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -41,6 +41,7 @@
 #include "llchannelmanager.h"
 #include "llchicletbar.h"
 #include "llconsole.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llenvmanager.h"
 #include "llfirstuse.h"
 #include "llfloatercamera.h"
@@ -1389,11 +1390,16 @@ BOOL LLAgent::getAFK() const
 //-----------------------------------------------------------------------------
 // setDoNotDisturb()
 //-----------------------------------------------------------------------------
-void LLAgent::setDoNotDisturb(bool pIsDotNotDisturb)
+void LLAgent::setDoNotDisturb(bool pIsDoNotDisturb)
 {
-	mIsDoNotDisturb = pIsDotNotDisturb;
-	sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, (pIsDotNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP));
-	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDotNotDisturb);
+	bool isDoNotDisturbSwitchedOff = (mIsDoNotDisturb && !pIsDoNotDisturb);
+	mIsDoNotDisturb = pIsDoNotDisturb;
+	sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, (pIsDoNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP));
+	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDoNotDisturb);
+	if (isDoNotDisturbSwitchedOff)
+	{
+		LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
+	}
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index dd2bcc742b..43757d0174 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -139,7 +139,9 @@ void LLChannelManager::onLoginCompleted()
 	}
 
 	LLPersistentNotificationStorage::getInstance()->loadNotifications();
+
 	LLDoNotDisturbNotificationStorage::getInstance()->initialize();
+	LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
 }
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
index 353447e4b6..4b0a70ffd8 100644
--- a/indra/newview/llcommunicationchannel.cpp
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -39,6 +39,7 @@
 
 LLCommunicationChannel::LLCommunicationChannel(const std::string& pName, const std::string& pParentName)
 	: LLNotificationChannel(pName, pParentName, filterByDoNotDisturbStatus)
+	, mHistory()
 {
 }
 
@@ -61,6 +62,11 @@ LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::e
 	return mHistory.end();
 }
 
+void LLCommunicationChannel::clearHistory()
+{
+	mHistory.clear();
+}
+
 void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
 {
 	std::string notificationType = pNotificationPtr->getType();
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
index a4756b8993..0e15e1cd15 100644
--- a/indra/newview/llcommunicationchannel.h
+++ b/indra/newview/llcommunicationchannel.h
@@ -46,6 +46,8 @@ public:
 	typedef std::multimap<LLDate, LLNotificationPtr> history_list_t;
 	history_list_t::const_iterator beginHistory() const;
 	history_list_t::const_iterator endHistory() const;
+	
+	void clearHistory();
 
 protected:
 	virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 472a0dd9ee..43fd7705aa 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -29,14 +29,25 @@
 
 #include "lldonotdisturbnotificationstorage.h"
 
+#define XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT 0
+
+#if XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
+#include "llchannelmanager.h"
+#endif // XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
 #include "llcommunicationchannel.h"
 #include "lldir.h"
 #include "llerror.h"
 #include "llfasttimer_class.h"
 #include "llnotifications.h"
+#include "llnotificationhandler.h"
 #include "llnotificationstorage.h"
+#if XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
+#include "llscreenchannel.h"
+#endif // XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
+#include "llscriptfloater.h"
 #include "llsd.h"
 #include "llsingleton.h"
+#include "lluuid.h"
 
 LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
 	: LLSingleton<LLDoNotDisturbNotificationStorage>()
@@ -85,6 +96,71 @@ static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notificati
 
 void LLDoNotDisturbNotificationStorage::loadNotifications()
 {
+	LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS);
+	
+	LL_INFOS("stinsonDebug") << "STINSON DEBUG: loading notifiations" << LL_ENDL;
+
+	LLSD input;
+	if (!readNotifications(input) ||input.isUndefined())
+	{
+		return;
+	}
+	
+	LLSD& data = input["data"];
+	if (data.isUndefined())
+	{
+		return;
+	}
+
+#if XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
+	LLNotificationsUI::LLScreenChannel* notification_channel =
+		dynamic_cast<LLNotificationsUI::LLScreenChannel*>(LLNotificationsUI::LLChannelManager::getInstance()->
+		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+#endif // XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
+	
+	LLNotifications& instance = LLNotifications::instance();
+	
+	for (LLSD::array_const_iterator notification_it = data.beginArray();
+		 notification_it != data.endArray();
+		 ++notification_it)
+	{
+		LLSD notification_params = *notification_it;
+		LLNotificationPtr notification(new LLNotification(notification_params));
+		
+		LL_INFOS("stinsonDebug") << "STINSON DEBUG: loading notification of type '" << notification->getType() << "'" << LL_ENDL;
+
+		const LLUUID& notificationID = notification->id();
+		if (instance.find(notificationID))
+		{
+			instance.update(notification);
+		}
+		else
+		{
+			LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"]));
+			notification->setResponseFunctor(responder);
+			
+			instance.add(notification);
+		}
+
+#if XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
+		// hide script floaters so they don't confuse the user and don't overlap startup toast
+		LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
+		
+		if(notification_channel)
+		{
+			// hide saved toasts so they don't confuse the user
+			notification_channel->hideToast(notification->getID());
+		}
+#endif // XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
+	}
+
+	// Clear the communication channel history and rewrite the save file to empty it as well
+	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+	LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+	llassert(commChannel != NULL);
+	commChannel->clearHistory();
+	
+	saveNotifications();
 }
 
 LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
-- 
cgit v1.2.3


From ca4c5d3bcb18afefc181bdc164d1c338abef7488 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Wed, 19 Dec 2012 11:28:38 -0800
Subject: Switching some notification types from "offer" to be "notify" as the
 notifications were not offers.

---
 indra/newview/skins/default/xui/en/notifications.xml | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 35ce787847..05798da8e2 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6583,7 +6583,7 @@ However, this region contains content accessible to adults only.
    log_to_im="true"
    log_to_chat="false"
    show_toast="false"
-   type="offer">
+   type="notify">
 	Teleport offer sent to [TO_NAME]
   </notification>
 
@@ -6636,7 +6636,7 @@ However, this region contains content accessible to adults only.
    name="FriendshipOffered"
    log_to_im="true"   
    show_toast="false"   
-   type="offer">
+   type="notify">
     <tag>friendship</tag>
 	You have offered friendship to [TO_NAME]
   </notification>
@@ -6666,7 +6666,7 @@ However, this region contains content accessible to adults only.
    icon="notify.tga"
    name="FriendshipAccepted"
    log_to_im="true"   
-   type="offer">
+   type="notify">
     <tag>friendship</tag>
 &lt;nolink&gt;[NAME]&lt;/nolink&gt; accepted your friendship offer.
   </notification>
@@ -6686,7 +6686,7 @@ However, this region contains content accessible to adults only.
    name="FriendshipAcceptedByMe"
    log_to_im="true"   
    show_toast="false"
-   type="offer">
+   type="notify">
     <tag>friendship</tag>
 Friendship offer accepted.
   </notification>
@@ -6696,7 +6696,7 @@ Friendship offer accepted.
    name="FriendshipDeclinedByMe"
    log_to_im="true"   
    show_toast="false"   
-   type="offer">
+   type="notify">
     <tag>friendship</tag>
 Friendship offer declined.
   </notification>
-- 
cgit v1.2.3


From dcfcc191dd3caaa84d0f789a928a83adf55c13b1 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 19 Dec 2012 12:45:59 -0800
Subject: Pull merge from richard/viewer-chui

---
 indra/newview/llconversationview.cpp   |  1 +
 indra/newview/llimview.cpp             | 14 +++++++-------
 indra/newview/skins/default/colors.xml |  3 ---
 3 files changed, 8 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index d3a0e882f5..fdba5b7289 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -109,6 +109,7 @@ void LLConversationViewSession::startFlashing()
 {
 	if (mFlashStateOn && !mFlashStarted)
 	{
+		llinfos << "Merov debug : Start the flashing for " << getName() << llendl;
 		mFlashStarted = true;
 		mFlashTimer->startFlashing();
 	}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5b4d5466a1..39f54dfd4d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -155,6 +155,8 @@ void on_new_message(const LLSD& msg)
     }
 
     // execution of the action
+	llinfos << "Merov debug : on_new_message action = " << action << llendl;
+	
 
     LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
@@ -174,13 +176,11 @@ void on_new_message(const LLSD& msg)
     if ("toast" == action)
     {
         // Skip toasting if we have open window of IM with this session id
-        if (
-            session_floater
+        if (session_floater
             && session_floater->isInVisibleChain()
             && session_floater->hasFocus()
             && !session_floater->isMinimized()
-            && !(session_floater->getHost()
-            && session_floater->getHost()->isMinimized())
+            && !(session_floater->getHost() && session_floater->getHost()->isMinimized())
             )
         {
             return;
@@ -222,10 +222,10 @@ void on_new_message(const LLSD& msg)
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
             }
             //conversation floater is open but a different conversation is focused
-            else
-            {
+            //else
+            //{
                 im_box->flashConversationItemWidget(session_id, true);
-            }
+            //}
     	}
     }
 
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index c3df04d0a6..becdbda067 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -11,9 +11,6 @@
 	<color
 	 name="EmphasisColor_35"
 	 value="0.38 0.694 0.573 0.35" />
-    <color
-    name="BeaconColor"
-    value="1 .67 .2 1" />	 
 	<color
 	 name="BeaconColor"
     value="1 .67 .2 1" />	 
-- 
cgit v1.2.3


From ef6121cba1c72549cca10763645254ae3aaf2887 Mon Sep 17 00:00:00 2001
From: William Todd Stinson <stinson@lindenlab.com>
Date: Wed, 19 Dec 2012 15:37:12 -0800
Subject: CHUI-499: Code clean-up and adding some more types badly defined.

---
 indra/newview/lldonotdisturbnotificationstorage.cpp | 17 +++++++++++------
 indra/newview/llnotificationstorage.cpp             |  6 ++++++
 2 files changed, 17 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 43fd7705aa..bf3dcae1f3 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -98,8 +98,6 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 {
 	LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS);
 	
-	LL_INFOS("stinsonDebug") << "STINSON DEBUG: loading notifiations" << LL_ENDL;
-
 	LLSD input;
 	if (!readNotifications(input) ||input.isUndefined())
 	{
@@ -127,8 +125,6 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 		LLSD notification_params = *notification_it;
 		LLNotificationPtr notification(new LLNotification(notification_params));
 		
-		LL_INFOS("stinsonDebug") << "STINSON DEBUG: loading notification of type '" << notification->getType() << "'" << LL_ENDL;
-
 		const LLUUID& notificationID = notification->id();
 		if (instance.find(notificationID))
 		{
@@ -136,8 +132,17 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 		}
 		else
 		{
-			LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"]));
-			notification->setResponseFunctor(responder);
+			LLNotificationResponderInterface* responder = createResponder(notification_params["name"], notification_params["responder"]);
+			if (responder == NULL)
+			{
+				LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
+					<< notification->getType() << "'" << LL_ENDL;
+			}
+			else
+			{
+				LLNotificationResponderPtr responderPtr(responder);
+				notification->setResponseFunctor(responderPtr);
+			}
 			
 			instance.add(notification);
 		}
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index 4746e4bbd4..b797775369 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -126,7 +126,13 @@ LLResponderRegistry::LLResponderRegistry()
 	, mBuildMap()
 {
 	add("ObjectGiveItem", &create<LLOfferInfo>);
+	add("OwnObjectGiveItem", &create<LLOfferInfo>);
 	add("UserGiveItem", &create<LLOfferInfo>);
+
+	add("TeleportOffered", &create<LLOfferInfo>);
+	add("TeleportOffered_MaturityExceeded", &create<LLOfferInfo>);
+
+	add("OfferFriendship", &create<LLOfferInfo>);
 }
 
 LLResponderRegistry::~LLResponderRegistry()
-- 
cgit v1.2.3


From c81cf89086b0282121c6577b6fde75e050c1a0e8 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 19 Dec 2012 17:10:31 -0800
Subject: CHUI-600 : Fix the orange (provided by Leo), fix the conversation
 item flashing (when shown)

---
 indra/newview/llconversationview.cpp   |  6 ++++--
 indra/newview/llfloaterimcontainer.cpp | 25 ++++++++++++++-----------
 indra/newview/llfloaterimcontainer.h   |  1 +
 indra/newview/llimview.cpp             |  3 ---
 indra/newview/skins/default/colors.xml |  2 +-
 5 files changed, 20 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index fdba5b7289..e51efd48f5 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -81,7 +81,9 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mSpeakingIndicator(NULL),
 	mVoiceClientObserver(NULL),
 	mCollapsedMode(false),
-    mHasArrow(true)
+    mHasArrow(true),
+	mFlashStateOn(false),
+	mFlashStarted(false)
 {
 	mFlashTimer = new LLFlashTimer();
 }
@@ -109,7 +111,6 @@ void LLConversationViewSession::startFlashing()
 {
 	if (mFlashStateOn && !mFlashStarted)
 	{
-		llinfos << "Merov debug : Start the flashing for " << getName() << llendl;
 		mFlashStarted = true;
 		mFlashTimer->startFlashing();
 	}
@@ -245,6 +246,7 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
     if(result && getRoot()->getCurSelectedItem() == this)
 	{
 		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+		im_container->clearAllFlashStates();
 		im_container->selectConversationPair(session_id, false);
 		im_container->collapseMessagesPane(false);
 	}
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 390eec84f6..58ba186b57 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1229,6 +1229,20 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
     selectConversationPair(session_id, true);
 }
 
+void LLFloaterIMContainer::clearAllFlashStates()
+{
+	llinfos << "Merov debug : clear all flash states" << llendl;
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+			widget->setFlashState(false);
+		}
+	}
+}
+
 void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
 {
     selectConversationPair(session_id, true);
@@ -1240,17 +1254,6 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     BOOL handled = TRUE;
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
 
-	// On selection, stop the flash state on all conversation widgets
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
-	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
-	{
-		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
-		if (widget)
-		{
-			widget->setFlashState(false);
-		}
-	}
-	
     /* widget processing */
     if (select_widget)
     {
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 5db1565cea..09a24c0105 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -69,6 +69,7 @@ public:
     void showConversation(const LLUUID& session_id);
     void selectConversation(const LLUUID& session_id);
     BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
+    void clearAllFlashStates();
 
 	/*virtual*/ void tabClose();
 	void showStub(bool visible);
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 39f54dfd4d..65048e352e 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -155,9 +155,6 @@ void on_new_message(const LLSD& msg)
     }
 
     // execution of the action
-	llinfos << "Merov debug : on_new_message action = " << action << llendl;
-	
-
     LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index becdbda067..0de217fc0d 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -13,7 +13,7 @@
 	 value="0.38 0.694 0.573 0.35" />
 	<color
 	 name="BeaconColor"
-    value="1 .67 .2 1" />	 
+    value="0.749 0.298 0 1" />	 
 	<color
 	 name="White"
 	 value="1 1 1 1" />
-- 
cgit v1.2.3


From b15ba74485e24db9a996a2f6a9438ac48224ea7a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 19 Dec 2012 17:19:48 -0800
Subject: CHUI-607: Due to a problem in design we have two checkboxes that
 determine whether a conversation transcript should be saved. By defaut
 commiting a change that makes both checkboxes checked by default. This makes
 it so that a new user can see their transcript/chat history.

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 24fa0a0cd4..ebc915ec5a 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4676,7 +4676,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>LandBrushSize</key>
     <map>
-- 
cgit v1.2.3


From ba297b167f75d8a09c959952a300d492f2aec88b Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 19 Dec 2012 20:07:08 -0800
Subject: CHUI-600 : Fixed! Modified the button flash state so it sticks after
 the animation and is dismissed on toggle

---
 indra/llui/llbutton.cpp | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 99384439d2..7ca9b869a8 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -311,7 +311,7 @@ void LLButton::onCommit()
 	{
 		make_ui_sound("UISndClickRelease");
 	}
-
+	
 	if (mIsToggle)
 	{
 		toggleState();
@@ -613,10 +613,6 @@ void LLButton::draw()
 	static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
 	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
 
-	if (mFlashingTimer)
-	{
-		mFlashing = mFlashingTimer->isFlashingInProgress();
-	}
 	bool flash = mFlashing && sEnableButtonFlashing;
 
 	bool pressed_by_keyboard = FALSE;
@@ -701,7 +697,8 @@ void LLButton::draw()
 		imagep = mImageDisabled;
 	}
 
-	if (mFlashing)
+	// Selected has a higher priority than flashing. If both are set, flashing is ignored.
+	if (mFlashing && !selected)
 	{
 		// if button should flash and we have icon for flashing, use it as image for button
 		if(flash && mImageFlash)
@@ -711,13 +708,13 @@ void LLButton::draw()
 			imagep = mImageFlash;
 		}
 		// else use usual flashing via flash_color
-		else
+		else if (mFlashingTimer)
 		{
 			LLColor4 flash_color = mFlashBgColor.get();
 			use_glow_effect = TRUE;
 			glow_type = LLRender::BT_ALPHA; // blend the glow
 
-			if (mFlashingTimer->isCurrentlyHighlighted())
+			if (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress())
 			{
 				glow_color = flash_color;
 			}
@@ -773,8 +770,7 @@ void LLButton::draw()
 	if (use_glow_effect)
 	{
 		mCurGlowStrength = lerp(mCurGlowStrength,
-					mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || mNeedsHighlight? 1.0 : 0.0)
-					: mHoverGlowStrength,
+					mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress() || mNeedsHighlight? 1.0 : 0.0) : mHoverGlowStrength,
 					LLCriticalDamp::getInterpolant(0.05f));
 	}
 	else
@@ -961,23 +957,18 @@ void LLButton::setToggleState(BOOL b)
 	{
 		setControlValue(b); // will fire LLControlVariable callbacks (if any)
 		setValue(b);        // may or may not be redundant
+		setFlashing(false);	// stop flash state whenever the selected/unselected state if reset
 		// Unselected label assignments
 		autoResize();
 	}
 }
 
-void LLButton::setFlashing( bool b )	
+void LLButton::setFlashing(bool b)	
 { 
 	if (mFlashingTimer)
 	{
-		if (b)
-		{
-			mFlashingTimer->startFlashing();
-		}
-		else
-		{
-			mFlashingTimer->stopFlashing();
-		}
+		mFlashing = b; 
+		(b ? mFlashingTimer->startFlashing() : mFlashingTimer->stopFlashing());
 	}
 	else if (b != mFlashing)
 	{
-- 
cgit v1.2.3


From ed716d996987722c32a105fac79daf1af4e5fb23 Mon Sep 17 00:00:00 2001
From: MaximB ProductEngine <mberezhnoy@productengine.com>
Date: Thu, 20 Dec 2012 09:42:34 +0200
Subject: CHUI-588 (Clicking nearby chat toast doesn't highlight proper
 conversation line item)

---
 indra/newview/llfloaterimsessiontab.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 7984034ded..53d2f31b79 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -308,7 +308,7 @@ void LLFloaterIMSessionTab::onFocusReceived()
 	LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
 	if (container)
 	{
-		container->selectConversationPair(mSessionID, ! getHost());
+		container->selectConversationPair(mSessionID, true);
 		container->showStub(! getHost());
 	}
 }
-- 
cgit v1.2.3


From eb68845767309900b6b5915f6358ae5027fb7136 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 20 Dec 2012 15:01:50 +0200
Subject: CHUI-606 Default settings in CHUI viewer do not keep IM logs for
 users: Preferences > Chat > Keep a convers. log was turned on

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 24fa0a0cd4..ebc915ec5a 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4676,7 +4676,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>LandBrushSize</key>
     <map>
-- 
cgit v1.2.3


From c81a0b0a5701425aa52521d8600a280d05040517 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Thu, 20 Dec 2012 15:23:36 +0200
Subject: CHUI-602 FIXED Don't call getUUID() if there is no selected
 participants

---
 indra/newview/llfloaterimcontainer.cpp | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 58ba186b57..92ea6dacde 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1101,7 +1101,14 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 	uuid_vec_t uuids;
 	getParticipantUUIDs(uuids);
 
-    if("can_activate_group" == item)
+
+	// If nothing is selected, everything needs to be disabled
+	if (uuids.size() <= 0)
+    {
+        return false;
+    }
+
+	if("can_activate_group" == item)
     {
     	LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
     	return gAgent.getGroupID() != selected_group_id;
@@ -1116,12 +1123,6 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
 	{
 		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
 	}
-
-	// If nothing is selected, everything needs to be disabled
-	if (uuids.size() <= 0)
-    {
-        return false;
-    }
 	
 	// Extract the single select info
 	bool is_single_select = (uuids.size() == 1);
-- 
cgit v1.2.3


From 2aefdb47ca1d02bfe8b74928dee479072ef151a3 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 20 Dec 2012 15:24:14 +0200
Subject: CHUI-618 User sees no indication of offline messages received with
 conversation log preference turned off: flashing of CHUI button if offline
 messages was received

---
 indra/newview/llimview.cpp | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 65048e352e..cdc51ad2fc 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2488,16 +2488,23 @@ void LLIMMgr::addMessage(
 	}
 
 	// Open conversation log if offline messages are present and user allows a Call Log
-	if (is_offline_msg && gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
-	{
-		LLFloaterConversationLog* floater_log =
-				LLFloaterReg::getTypedInstance<LLFloaterConversationLog>("conversation");
-		if (floater_log && !(floater_log->isFrontmost()))
+	if (is_offline_msg)
+    {
+		if (gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
 		{
-            floater_log->openFloater();
-			floater_log->setFrontmost(TRUE);
+			LLFloaterConversationLog* floater_log =
+					LLFloaterReg::getTypedInstance<LLFloaterConversationLog>("conversation");
+			if (floater_log && !(floater_log->isFrontmost()))
+			{
+				floater_log->openFloater();
+				floater_log->setFrontmost(TRUE);
+			}
 		}
-	}
+		else
+		{
+           gToolBarView->flashCommand(LLCommandId("chat"), true);
+		}
+    }
 
 	//*NOTE session_name is empty in case of incoming P2P sessions
 	std::string fixed_session_name = from;
-- 
cgit v1.2.3


From 95380b0aaa635c18c03801048559ba811640bc02 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 20 Dec 2012 22:37:04 +0200
Subject: CHUI-513 FIXED Revise initial conversation floater size

---
 indra/newview/app_settings/settings_per_account.xml         | 2 +-
 indra/newview/skins/default/xui/en/floater_im_container.xml | 7 ++-----
 indra/newview/skins/default/xui/en/floater_im_session.xml   | 2 +-
 3 files changed, 4 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index ca22041671..4ff494fbfb 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -53,7 +53,7 @@
         <key>Type</key>
             <string>S32</string>
         <key>Value</key>
-            <integer>268</integer>
+            <integer>205</integer>
     </map>
     <key>ConversationsMessagePaneCollapsed</key>
     <map>
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 3475c7da33..cbf1830093 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -3,9 +3,8 @@
  can_close="true"  
  can_minimize="true"
  can_resize="true"
- height="230"
+ height="210"
  layout="topleft"
- min_height="50"
  name="floater_im_box"
  help_topic="floater_im_box"
  save_rect="true"
@@ -15,7 +14,7 @@
  title="CONVERSATIONS"
  bottom="-50"
  right="-5"
- width="500">
+ width="450">
     <string
      name="collapse_icon"
      value="Conv_toolbar_collapse"/>
@@ -37,7 +36,6 @@
          user_resize="true"        
          name="conversations_layout_panel"
          min_dim="38"
-         width="225"
          expanded_min_dim="156">
             <layout_stack
              animate="false" 
@@ -121,7 +119,6 @@
              opaque="true"
              top_pad="0"
              left="5"
-             height="390"
              right="-1"/>
         </layout_panel>
         <layout_panel
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 4dbd52d05e..9e2132dc3b 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -206,7 +206,7 @@
        auto_resize="true"
        visible="true"
        name="left_part_holder"
-       min_width="225">
+       min_width="221">
         <panel
          name="trnsAndChat_panel"
          follows="all"
-- 
cgit v1.2.3


From 090636f107a2d3ba3438a6690f36eac3ec257314 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 20 Dec 2012 18:36:01 -0800
Subject: CHUI-429 : Fixed! Add a flag to filter multi/single selection
 situations in menu building. Implement in conversation contextual menu.

---
 indra/llui/llfolderview.cpp                        |  5 +-
 indra/llui/llfolderview.h                          |  1 +
 indra/newview/llconversationmodel.cpp              | 67 ++++++++++++----------
 indra/newview/llconversationmodel.h                |  2 +-
 indra/newview/llfloaterimcontainer.cpp             |  1 -
 .../skins/default/xui/en/menu_conversation.xml     |  7 +++
 6 files changed, 50 insertions(+), 33 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index a33ffc4240..7ae79d94fe 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1913,14 +1913,15 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)
 
 	// Successively filter out invalid options
 
-	U32 flags = FIRST_SELECTED_ITEM;
+	U32 multi_select_flag = (mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION : 0x0);
+	U32 flags = multi_select_flag | FIRST_SELECTED_ITEM;
 	for (selected_items_t::iterator item_itor = mSelectedItems.begin();
 			item_itor != mSelectedItems.end();
 			++item_itor)
 	{
 		LLFolderViewItem* selected_item = (*item_itor);
 		selected_item->buildContextMenu(*menu, flags);
-		flags = 0x0;
+		flags = multi_select_flag;
 	}
 
 	addNoOptions(menu);
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index d4a1434c73..2ee7417240 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -400,5 +400,6 @@ public:
 // Flags for buildContextMenu()
 const U32 SUPPRESS_OPEN_ITEM = 0x1;
 const U32 FIRST_SELECTED_ITEM = 0x2;
+const U32 ITEM_IN_MULTI_SELECTION = 0x4;
 
 #endif // LL_LLFOLDERVIEW_H
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index d03ad92fbc..005439301a 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -102,35 +102,44 @@ void LLConversationItem::showProperties(void)
 {
 }
 
-void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t&   items)
-{
-    items.push_back(std::string("view_profile"));
-    items.push_back(std::string("im"));
-    items.push_back(std::string("offer_teleport"));
-    items.push_back(std::string("voice_call"));
-    items.push_back(std::string("chat_history"));
-    items.push_back(std::string("separator_chat_history"));
-    items.push_back(std::string("add_friend"));
-    items.push_back(std::string("remove_friend"));
-    items.push_back(std::string("invite_to_group"));
-    items.push_back(std::string("separator_invite_to_group"));
-    items.push_back(std::string("map"));
-    items.push_back(std::string("share"));
-    items.push_back(std::string("pay"));
-    items.push_back(std::string("block_unblock"));
-    items.push_back(std::string("MuteText"));
-
-	if(this->getType() != CONV_SESSION_1_ON_1 && mDisplayModeratorOptions)
+void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags)
+{
+	if (flags & ITEM_IN_MULTI_SELECTION)
 	{
-		items.push_back(std::string("Moderator Options Separator"));
-		items.push_back(std::string("Moderator Options"));
-		items.push_back(std::string("AllowTextChat"));
-		items.push_back(std::string("moderate_voice_separator"));
-		items.push_back(std::string("ModerateVoiceToggleMuteSelected"));
-		items.push_back(std::string("ModerateVoiceMute"));
-		items.push_back(std::string("ModerateVoiceUnmute"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("remove_friends"));
+	}
+	else 
+	{
+		items.push_back(std::string("view_profile"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("chat_history"));
+		items.push_back(std::string("separator_chat_history"));
+		items.push_back(std::string("add_friend"));
+		items.push_back(std::string("remove_friend"));
+		items.push_back(std::string("invite_to_group"));
+		items.push_back(std::string("separator_invite_to_group"));
+		items.push_back(std::string("map"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("block_unblock"));
+		items.push_back(std::string("MuteText"));
+
+		if ((getType() != CONV_SESSION_1_ON_1) && mDisplayModeratorOptions)
+		{
+			items.push_back(std::string("Moderator Options Separator"));
+			items.push_back(std::string("Moderator Options"));
+			items.push_back(std::string("AllowTextChat"));
+			items.push_back(std::string("moderate_voice_separator"));
+			items.push_back(std::string("ModerateVoiceToggleMuteSelected"));
+			items.push_back(std::string("ModerateVoiceMute"));
+			items.push_back(std::string("ModerateVoiceUnmute"));
+		}
 	}
-
 }
 
 //
@@ -306,7 +315,7 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
     {
         items.push_back(std::string("close_conversation"));
         items.push_back(std::string("separator_disconnect_from_voice"));
-        buildParticipantMenuOptions(items);
+        buildParticipantMenuOptions(items, flags);
     }
     else if(this->getType() == CONV_SESSION_GROUP)
     {
@@ -440,7 +449,7 @@ void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
     menuentry_vec_t items;
     menuentry_vec_t disabled_items;
 
-	buildParticipantMenuOptions(items);
+	buildParticipantMenuOptions(items, flags);
 	
     hide_context_entries(menu, items, disabled_items);
 }
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 743a6ba40b..02002d8f70 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -130,7 +130,7 @@ public:
 	
 	void postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant);
 	
-    void buildParticipantMenuOptions(menuentry_vec_t&   items);
+    void buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags);
 
 protected:
 	std::string mName;	// Name of the session or the participant
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 92ea6dacde..2019a35faa 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1232,7 +1232,6 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
 
 void LLFloaterIMContainer::clearAllFlashStates()
 {
-	llinfos << "Merov debug : clear all flash states" << llendl;
 	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
 	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
 	{
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index e0edf384d6..46c6e19fa5 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -75,6 +75,13 @@
         <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
         <on_enable function="Avatar.EnableItem" parameter="can_delete" />
     </menu_item_call>	
+    <menu_item_call
+     label="Remove friends"
+     layout="topleft"
+     name="remove_friends">
+        <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
+        <on_enable function="Avatar.EnableItem" parameter="can_delete" />
+    </menu_item_call>	
     <menu_item_call
      label="Invite to group..."
      layout="topleft"
-- 
cgit v1.2.3


From d1898ef3b8cf1344bd1f3980b500d4d2f5c10593 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 20 Dec 2012 19:57:51 +0200
Subject: CHUI-605 : Fixed : Keep conversation log requires restart to change
 preference: connected LLConversationLog::enableLogging() as listener to
 "LogInstantMessages" control changes

---
 indra/newview/llconversationlog.cpp | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 1171b3db41..eb3a3731ee 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -187,16 +187,23 @@ void LLConversationLogFriendObserver::changed(U32 mask)
 
 LLConversationLog::LLConversationLog()
 {
-	LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
-	if (ctrl)
+	LLControlVariable* log_instant_message = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
+	LLControlVariable* keep_convers_log = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+	bool is_log_message = false;
+	bool is_keep_log = false;
+
+	if (log_instant_message)
 	{
-		ctrl->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
-		if (ctrl->getValue().asBoolean()
-				&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
-		{
-			enableLogging(true);
-		}
+		log_instant_message->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+		is_log_message = log_instant_message->getValue().asBoolean();
 	}
+	if (keep_convers_log)
+	{
+		keep_convers_log->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+		is_keep_log = keep_convers_log->getValue().asBoolean();
+	}
+
+	enableLogging(is_log_message && is_keep_log);
 }
 
 void LLConversationLog::enableLogging(bool enable)
-- 
cgit v1.2.3


From 2610af9798374ce9fff7623d7aa7e269b2a78174 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 21 Dec 2012 15:35:56 +0200
Subject: CHUI-619 FUI button and conversation line items blink at different
 rates: changed rate

---
 indra/newview/app_settings/settings.xml | 2 +-
 indra/newview/llimview.cpp              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ebc915ec5a..507eb33f2d 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -13173,7 +13173,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>0.25</real>
+      <real>0.5</real>
     </map>
     <key>WindLightUseAtmosShaders</key>
     <map>
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cdc51ad2fc..708400cbe1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -964,7 +964,7 @@ const std::string LLIMModel::getName(const LLUUID& session_id) const
 {
 	LLIMSession* session = findIMSession(session_id);
 
-	if (!session) 
+	if (!session)
 	{
 		llwarns << "session " << session_id << "does not exist " << llendl;
 		return LLTrans::getString("no_session_message");
-- 
cgit v1.2.3


From 7549a392cc32dc36f0bc673a6569f01731cc1bbd Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 21 Dec 2012 16:28:33 +0200
Subject: CHUI-566 Flashing and color on Conversations FUI button and
 conversation line item: change behavior for the case "If conversations
 (container) floater open but not on top"

---
 indra/newview/llimview.cpp | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 708400cbe1..d736b81bb7 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -160,6 +160,7 @@ void on_new_message(const LLSD& msg)
 
     //session floater not focused (visible or not)
     bool session_floater_not_focused = session_floater && !session_floater->hasFocus();
+
     //conv. floater is closed
     bool conversation_floater_is_closed =
     		!(  im_box
@@ -210,20 +211,16 @@ void on_new_message(const LLSD& msg)
 
     else if ("flash" == action)
     {
-    	if (session_floater_not_focused)
+    	if (conversation_floater_not_focused)
     	{
-    		//User is not focused on conversation containing the message
-
-            if(conversation_floater_not_focused)
+            if(session_floater_not_focused)
             {
+            	//User is not focused on conversation containing the message
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
             }
-            //conversation floater is open but a different conversation is focused
-            //else
-            //{
-                im_box->flashConversationItemWidget(session_id, true);
-            //}
-    	}
+
+            im_box->flashConversationItemWidget(session_id, true);
+        }
     }
 
     else if("openconversations" == action)
-- 
cgit v1.2.3


From 765a5a73dd3e2e7a88141e26f4aa7b479229ad2e Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Fri, 21 Dec 2012 16:45:58 +0200
Subject: CHUI-621 FIXED Notification chiclet UI error

---
 indra/newview/llchiclet.cpp                              |   2 +-
 .../skins/default/textures/bottomtray/Notices_Unread.png | Bin 0 -> 3693 bytes
 2 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 indra/newview/skins/default/textures/bottomtray/Notices_Unread.png

(limited to 'indra')

diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 2fdcb17570..3dbb43c657 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -76,7 +76,7 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
 
 LLSysWellChiclet::~LLSysWellChiclet()
 {
-	delete mFlashToLitTimer;
+	mFlashToLitTimer->unset();
 }
 
 void LLSysWellChiclet::setCounter(S32 counter)
diff --git a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png
new file mode 100644
index 0000000000..0ac5b72b8f
Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png differ
-- 
cgit v1.2.3


From dd7509f56de5e8a47680b33176e90c11ed518066 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 21 Dec 2012 20:05:40 +0200
Subject: CHUI-411 Entries in chat history viewer do not show all dates of
 entries and some entries show on multiple pages Type of variable for the time
 saving was changed from S32 to long int ("capacity" of S32-timer is only ~18
 hours!)

---
 indra/newview/llconversationlog.cpp | 45 +++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 22 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index eb3a3731ee..e44749fd79 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -236,17 +236,20 @@ void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offli
 	const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 	LLConversation* conversation = findConversation(session);
 
-	if (session && conversation)
+    if (session)
 	{
-		if(has_offline_msg)
+    	if (conversation)
 		{
-			updateOfflineIMs(session, has_offline_msg);
+			if(has_offline_msg)
+			{
+				updateOfflineIMs(session, has_offline_msg);
+			}
+			updateConversationTimestamp(conversation);
+		}
+		else
+		{
+			createConversation(session);
 		}
-		updateConversationTimestamp(conversation);
-	}
-	else if (session && !conversation)
-	{
-		createConversation(session);
 	}
 }
 
@@ -307,19 +310,17 @@ void LLConversationLog::updateConversationTimestamp(LLConversation* conversation
 
 LLConversation* LLConversationLog::findConversation(const LLIMModel::LLIMSession* session)
 {
-	if (!session)
+	if (session)
 	{
-		return NULL;
-	}
+		const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
 
-	const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
-
-	conversations_vec_t::iterator conv_it = mConversations.begin();
-	for(; conv_it != mConversations.end(); ++conv_it)
-	{
-		if (conv_it->getSessionID() == session_id)
+		conversations_vec_t::iterator conv_it = mConversations.begin();
+		for(; conv_it != mConversations.end(); ++conv_it)
 		{
-			return &*conv_it;
+			if (conv_it->getSessionID() == session_id)
+			{
+				return &*conv_it;
+			}
 		}
 	}
 
@@ -411,8 +412,8 @@ bool LLConversationLog::saveToFile(const std::string& filename)
 		// [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe|
 		// [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
 
-		fprintf(fp, "[%d] %d %d %d %s| %s %s %s|\n",
-				(S32)conv_it->getTime(),
+		fprintf(fp, "[%ld] %d %d %d %s| %s %s %s|\n",
+				conv_it->getTime(),
 				(S32)conv_it->getConversationType(),
 				(S32)0,
 				(S32)conv_it->hasOfflineMessages(),
@@ -446,7 +447,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	char history_file_name[MAX_STRING];
 	int has_offline_ims;
 	int stype;
-	S32 time;
+	time_t time;
 	// before CHUI-348 it was a flag of conversation voice state
 	int prereserved_unused;
 
@@ -456,7 +457,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 		part_id_buffer[0]	= '\0';
 		conv_id_buffer[0]	= '\0';
 
-		sscanf(buffer, "[%d] %d %d %d %[^|]| %s %s %[^|]|",
+		sscanf(buffer, "[%ld] %d %d %d %[^|]| %s %s %[^|]|",
 				&time,
 				&stype,
 				&prereserved_unused,
-- 
cgit v1.2.3


From 6df0377d1dd810cc1656c6c2664af2c7c87705fc Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Fri, 21 Dec 2012 20:11:01 +0200
Subject: CHUI-622 FIXED Default size of conversation log floater seems large

---
 .../default/xui/en/floater_conversation_log.xml    | 163 ++++++++++-----------
 1 file changed, 80 insertions(+), 83 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index c9c52e5ce5..960db137b3 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -1,91 +1,88 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
 
 <floater
-  can_resize="true"
-  positioning="cascading"
-  height="400"
-  min_height="100"
-  min_width="390"
-  layout="topleft"
-  name="floater_conversation_log"
-  save_rect="true"
-  single_instance="true"
-  reuse_instance="true"
-  title="CONVERSATION LOG"
-  width="450">
-  
+ can_resize="true"
+ positioning="cascading"
+ height="200"
+ min_height="100"
+ min_width="200"
+ layout="topleft"
+ name="floater_conversation_log"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ title="CONVERSATION LOG"
+ width="300">
   <string name="logging_calls_disabled">
      Conversations are not being logged. To log conversations in the future, select "Save IM logs on my computer" under Preferences > Privacy.
   </string>
-  
-	<panel
-      follows="left|top|right"
-      height="27"
-      layout="topleft"
-      left="0"
-      name="buttons_panel"
-      top="0">
-        <filter_editor
-          follows="left|top|right"
-          height="23"
-          layout="topleft"
-          left="8"
-          label="Filter People"
-          max_length_chars="300"
-          name="people_filter_input"
-          text_color="Black"
-          text_pad_left="10"
-          top="4"
-          width="364" />
-        <menu_button
-          follows="right"
-          height="25"
-          image_hover_unselected="Toolbar_Middle_Over"
-          image_overlay="Conv_toolbar_sort"
-          image_selected="Toolbar_Middle_Selected"
-          image_unselected="Toolbar_Middle_Off"
-          layout="topleft"
-          left_pad="5"
-          menu_filename="menu_conversation_log_view.xml"
-          menu_position="bottomleft"
-          name="conversation_view_btn"
-          tool_tip="View/sort options"
-          top="3"
-          width="31" />
-        <menu_button
-          follows="right"
-          height="25"
-          image_hover_unselected="Toolbar_Middle_Over"
-          image_overlay="OptionsMenu_Off"
-          image_selected="Toolbar_Middle_Selected"
-          image_unselected="Toolbar_Middle_Off"
-          layout="topleft"
-          left_pad="2"
-          name="conversations_gear_btn"
-          tool_tip="Actions on selected person or group"
-          top="3"
-          width="31" />
-    </panel>
-    <panel
-      follows="all"
-      height="370"
-      layout="topleft"
-      left="5"
-      name="buttons_panel"
-      right="-5"
-      top_pad="5">
+  <panel
+   bottom="0"
+   follows="left|top|right"
+   height="32"
+   left="0"
+   name="buttons_panel"
+   right="0"
+   top="0">
+    <filter_editor
+     follows="left|top|right"
+     height="23"
+     layout="topleft"
+     left="8"
+     label="Filter People"
+     max_length_chars="300"
+     name="people_filter_input"
+     text_color="Black"
+     text_pad_left="10"
+     top="4"
+     width="204" />
+    <menu_button
+     follows="top|right"
+     height="25"
+     image_hover_unselected="Toolbar_Middle_Over"
+     image_overlay="Conv_toolbar_sort"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     layout="topleft"
+     left_pad="8"
+     menu_filename="menu_conversation_log_view.xml"
+     menu_position="bottomleft"
+     name="conversation_view_btn"
+     tool_tip="View/sort options"
+     top="3"
+     width="31" />
+    <menu_button
+     follows="top|right"
+     height="25"
+     image_hover_unselected="Toolbar_Middle_Over"
+     image_overlay="OptionsMenu_Off"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     layout="topleft"
+     left_pad="8"
+     name="conversations_gear_btn"
+     tool_tip="Actions on selected person or group"
+     top="3"
+     width="31" />
+  </panel>
+  <panel
+   bottom="-1"
+   follows="all"
+   left="0"
+   name="log_panel"
+   right="-1"
+   top="32">
     <conversation_log_list
-      opaque="true"
-      allow_select="true"
-      follows="all"
-      height="360"
-      layout="topleft"
-      left="3"
-      keep_selection_visible_on_reshape="true"
-      item_pad="2"
-      multi_select="false"
-      name="conversation_log_list"
-      right="-3"
-      top="5" />
-    </panel>
+     allow_select="true"
+     bottom="-8"
+     opaque="true"
+     follows="all"
+     left="8"
+     keep_selection_visible_on_reshape="true"
+     item_pad="2"
+     multi_select="false"
+     name="conversation_log_list"
+     right="-8"
+     top="0" />
+  </panel>
 </floater>
-- 
cgit v1.2.3


From 923262f154748eea5ce1eda37df1b9df1eaf0f43 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Mon, 24 Dec 2012 14:20:25 +0200
Subject: CHUI-583 FIXED Link will be opened in external browser if this
 preference is set.

---
 indra/newview/llviewermenu.cpp                     | 15 +++++++++++++++
 indra/newview/skins/default/xui/en/menu_viewer.xml | 14 +++++++-------
 2 files changed, 22 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index fe9c00cc27..be9f7d645a 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7586,6 +7586,20 @@ void handle_web_content_test(const LLSD& param)
 	LLWeb::loadURLInternal(url);
 }
 
+void handle_show_url(const LLSD& param)
+{
+	std::string url = param.asString();
+	if(gSavedSettings.getBOOL("UseExternalBrowser"))
+	{
+		LLWeb::loadURLExternal(url);
+	}
+	else
+	{
+		LLWeb::loadURLInternal(url);
+	}
+
+}
+
 void handle_buy_currency_test(void*)
 {
 	std::string url =
@@ -8415,6 +8429,7 @@ void initialize_menus()
 	// Advanced > UI
 	commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test,	_2));	// sigh! this one opens the MEDIA browser
 	commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2));	// this one opens the Web Content floater
+	commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2));
 	view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
 	view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
 	view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 00424e97f6..76de81559b 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1273,35 +1273,35 @@
              label="User’s guide"
              name="User’s guide">
              <menu_item_call.on_click
-                 function="Advanced.WebBrowserTest"
+                 function="Advanced.ShowURL"
                  parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-User-s-Guide/ta-p/1244857"/>
         </menu_item_call>
         <menu_item_call
              label="Knowledge Base"
              name="Knowledge Base">
              <menu_item_call.on_click
-                 function="Advanced.WebBrowserTest"
+                 function="Advanced.ShowURL"
                  parameter="http://community.secondlife.com/t5/tkb/communitypage"/>
         </menu_item_call>
         <menu_item_call
              label="Wiki"
              name="Wiki">
              <menu_item_call.on_click
-                 function="Advanced.WebBrowserTest"
+                 function="Advanced.ShowURL"
                  parameter="http://wiki.secondlife.com"/>
         </menu_item_call>
         <menu_item_call
              label="Community Forums"
              name="Community Forums">
              <menu_item_call.on_click
-                 function="Advanced.WebBrowserTest"
+                 function="Advanced.ShowURL"
                  parameter="http://community.secondlife.com/t5/Forums/ct-p/Forums"/>
         </menu_item_call>         
         <menu_item_call
              label="Support portal"
              name="Support portal">
              <menu_item_call.on_click
-                 function="Advanced.WebBrowserTest"
+                 function="Advanced.ShowURL"
                  parameter="https://support.secondlife.com/"/>         
         </menu_item_call>
         <menu_item_separator/>
@@ -1309,14 +1309,14 @@
              label="[SECOND_LIFE] News"
              name="Second Life News">
              <menu_item_call.on_click
-                 function="Advanced.WebBrowserTest"
+                 function="Advanced.ShowURL"
                  parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>  
         </menu_item_call>
         <menu_item_call
              label="[SECOND_LIFE] Blogs"
              name="Second Life Blogs">
              <menu_item_call.on_click
-                 function="Advanced.WebBrowserTest"
+                 function="Advanced.ShowURL"
                  parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
         </menu_item_call>
         <menu_item_separator/>
-- 
cgit v1.2.3


From 32944ef9e41a96950aa645a016c8f2c6bf71a351 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Mon, 24 Dec 2012 19:01:27 +0200
Subject: CHUI-627 FIXED Unnecessary attributes are deleted  in xml

---
 indra/newview/skins/default/xui/en/floater_conversation_log.xml | 2 --
 1 file changed, 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index 960db137b3..cf61348a66 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -17,12 +17,10 @@
      Conversations are not being logged. To log conversations in the future, select "Save IM logs on my computer" under Preferences > Privacy.
   </string>
   <panel
-   bottom="0"
    follows="left|top|right"
    height="32"
    left="0"
    name="buttons_panel"
-   right="0"
    top="0">
     <filter_editor
      follows="left|top|right"
-- 
cgit v1.2.3


From 51747dc6bfcdf0c3a9926f2b28ff30f0686623b3 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 25 Dec 2012 21:16:30 +0200
Subject: CHUI-623 FIXED No vertical scrollbar in conversation list

---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index cbf1830093..e7638fe669 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -113,11 +113,12 @@
                 </layout_panel>
             </layout_stack>
             <panel
+             bottom="-5"
              follows="all"
              layout="topleft"
              name="conversations_list_panel"
              opaque="true"
-             top_pad="0"
+             top="35"
              left="5"
              right="-1"/>
         </layout_panel>
@@ -127,7 +128,7 @@
          name="messages_layout_panel"
          expanded_min_dim="222">
             <panel_container
-             bottom="-1"
+             bottom="-5"
              follows="all"
              layout="topleft"
              left="0"
-- 
cgit v1.2.3


From 12466171b149ebe94b20cc8c74b7c9b1163fdc33 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 26 Dec 2012 11:23:59 +0200
Subject: CHUI-632 FIXED Disable Gear button if nothing is selected

---
 indra/newview/llpanelblockedlist.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index ecab7d2167..df1ccdd9fc 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -137,6 +137,7 @@ void LLPanelBlockedList::updateButtons()
 {
 	bool hasSelected = NULL != mBlockedList->getSelectedItem();
 	getChildView("unblock_btn")->setEnabled(hasSelected);
+	getChildView("blocked_gear_btn")->setEnabled(hasSelected);
 }
 
 void LLPanelBlockedList::unblockItem()
-- 
cgit v1.2.3


From d05df4087c334fe30a9d0fe5224a828c677d0244 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 26 Dec 2012 11:46:29 +0200
Subject: CHUI-617 FIXED Update Gear button state after initing session.
 mConversationsRoot creation is moved to postBuild().

---
 indra/newview/llfloaterimsession.cpp    |  4 +--
 indra/newview/llfloaterimsessiontab.cpp | 44 ++++++++++++++-------------------
 2 files changed, 20 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index ff07ddfcbf..d36b138c21 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -86,7 +86,7 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
     mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&LLFloaterIMSession::GearDoToSelected, this, _2));
     mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&LLFloaterIMSession::checkGearMenuItem, this, _2));
 
-	setDocked(true);
+    setDocked(true);
 }
 
 
@@ -754,7 +754,7 @@ void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id)
 	}
 
 	initIMFloater();
-	
+	LLFloaterIMSessionTab::updateGearBtn();
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
 
 	//need to send delayed messages collected while waiting for session initialization
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 53d2f31b79..f5b657fa60 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -240,7 +240,24 @@ BOOL LLFloaterIMSessionTab::postBuild()
 		result = LLDockableFloater::postBuild();
 	}
 
-	// Now ready to build the conversation and participants list
+	// Create the root using an ad-hoc base item
+	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mParticipantListPanel;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
+    p.use_ellipses = true;
+    p.options_menu = "menu_conversation.xml";
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+	// Attach that root to the scroller
+	mScroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(mScroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+
 	buildConversationViewParticipant();
 	refreshConversation();
 
@@ -388,31 +405,6 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
 		return;
 	}
 	
-	// Create or recreate the root folder: this is a dummy folder (not shown) but required by the LLFolderView architecture 
-	// We need to redo this when rebuilding as the session id (mSessionID) *may* have changed
-	if (mConversationsRoot)
-	{
-		// Remove the old root if any
-		mScroller->removeChild(mConversationsRoot);
-	}
-	// Create the root using an ad-hoc base item
-	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
-    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
-    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
-    p.parent_panel = mParticipantListPanel;
-    p.listener = base_item;
-    p.view_model = &mConversationViewModel;
-    p.root = NULL;
-    p.use_ellipses = true;
-    p.options_menu = "menu_conversation.xml";
-	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
-    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
-	// Attach that root to the scroller
-	mScroller->addChild(mConversationsRoot);
-	mConversationsRoot->setScrollContainer(mScroller);
-	mConversationsRoot->setFollowsAll();
-	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
-	
 	// Create the participants widgets now
 	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
 	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
-- 
cgit v1.2.3


From 099c9bcc6ffd9760cf935b6bcff8d796d0dff09d Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 26 Dec 2012 20:25:56 +0200
Subject: CHUI-629 FIXED Windows crash on exit when closing viewer with
 conversation log open with unread offline messages

---
 indra/newview/llconversationlog.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index e44749fd79..0479733706 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -412,7 +412,7 @@ bool LLConversationLog::saveToFile(const std::string& filename)
 		// [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe|
 		// [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
 
-		fprintf(fp, "[%ld] %d %d %d %s| %s %s %s|\n",
+		fprintf(fp, "[%lld] %d %d %d %s| %s %s %s|\n",
 				conv_it->getTime(),
 				(S32)conv_it->getConversationType(),
 				(S32)0,
-- 
cgit v1.2.3


From 1eae887434331357e057498905f7f5ff8f9f9c77 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 26 Dec 2012 23:55:23 +0200
Subject: CHUI-629 FIXED Resolve build problems;

---
 indra/newview/llconversationlog.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 0479733706..8c86871134 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -413,7 +413,7 @@ bool LLConversationLog::saveToFile(const std::string& filename)
 		// [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
 
 		fprintf(fp, "[%lld] %d %d %d %s| %s %s %s|\n",
-				conv_it->getTime(),
+				(S64)conv_it->getTime(),
 				(S32)conv_it->getConversationType(),
 				(S32)0,
 				(S32)conv_it->hasOfflineMessages(),
-- 
cgit v1.2.3


From 7e8d336749b42ce134a67dfe1f1990644f1b263a Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 28 Dec 2012 15:28:19 +0200
Subject: CHUI-639 FIXED Min. width is increased to avoid overlapping

---
 indra/newview/skins/default/xui/en/floater_conversation_log.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index cf61348a66..256e03c4d7 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -5,7 +5,7 @@
  positioning="cascading"
  height="200"
  min_height="100"
- min_width="200"
+ min_width="230"
  layout="topleft"
  name="floater_conversation_log"
  save_rect="true"
-- 
cgit v1.2.3


From d99fa985c8ff65913e85dfaa9fd91892a197c4cc Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 28 Dec 2012 18:55:24 +0200
Subject: CHUI-566 ADD. FIX Flashing and color on Conversations FUI button and
 conversation line item Cancel sticking of color, if the button is pressed, or
 when a flashing of the previously selected button is ended

---
 indra/llui/llbutton.cpp    | 18 +++++++++++++-----
 indra/newview/llimview.cpp | 16 ++++++----------
 2 files changed, 19 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 7ca9b869a8..a8149a9a1d 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -311,7 +311,7 @@ void LLButton::onCommit()
 	{
 		make_ui_sound("UISndClickRelease");
 	}
-	
+
 	if (mIsToggle)
 	{
 		toggleState();
@@ -613,8 +613,6 @@ void LLButton::draw()
 	static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
 	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
 
-	bool flash = mFlashing && sEnableButtonFlashing;
-
 	bool pressed_by_keyboard = FALSE;
 	if (hasFocus())
 	{
@@ -642,6 +640,17 @@ void LLButton::draw()
 	LLColor4 glow_color;
 	LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
 	LLUIImage* imagep = NULL;
+
+    //  Cancel sticking of color, if the button is pressed,
+	//  or when a flashing of the previously selected button is ended
+	if (mFlashingTimer
+		&& ((selected && !mFlashingTimer->isFlashingInProgress()) || pressed))
+	{
+		mFlashing = false;
+	}
+
+	bool flash = mFlashing && sEnableButtonFlashing;
+
 	if (pressed && mDisplayPressedState)
 	{
 		imagep = selected ? mImagePressedSelected : mImagePressed;
@@ -697,8 +706,7 @@ void LLButton::draw()
 		imagep = mImageDisabled;
 	}
 
-	// Selected has a higher priority than flashing. If both are set, flashing is ignored.
-	if (mFlashing && !selected)
+	if (mFlashing)
 	{
 		// if button should flash and we have icon for flashing, use it as image for button
 		if(flash && mImageFlash)
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d736b81bb7..48cf7b3463 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -122,7 +122,7 @@ void on_new_message(const LLSD& msg)
     LLUUID session_id = msg["session_id"].asUUID();
     LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 
-    // determine action for this session
+    //  determine action for this session
 
     if (session_id.isNull())
     {
@@ -148,13 +148,14 @@ void on_new_message(const LLSD& msg)
         action = gSavedSettings.getString("NotificationGroupChatOptions");
     }
 
-    // do not show notification in "do not disturb" mode or it goes from agent
+    // do not show notification which goes from agent
     if (gAgent.getID() == participant_id)
     {
         return;
     }
 
     // execution of the action
+
     LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
@@ -173,7 +174,7 @@ void on_new_message(const LLSD& msg)
 
     if ("toast" == action)
     {
-        // Skip toasting if we have open window of IM with this session id
+        // Skip toasting and flashing if we have open window of IM with this session id
         if (session_floater
             && session_floater->isInVisibleChain()
             && session_floater->hasFocus()
@@ -184,12 +185,6 @@ void on_new_message(const LLSD& msg)
             return;
         }
 
-	    // Skip toasting for system messages and for nearby chat
-	    if (participant_id.isNull())
-        {
-            return;
-        }
-
         //User is not focused on conversation containing the message
         if(session_floater_not_focused)
         {
@@ -201,7 +196,8 @@ void on_new_message(const LLSD& msg)
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
 
                 //Show IM toasts (upper right toasts)
-                if(session_id.notNull())
+                // Skip toasting for system messages and for nearby chat
+                if(session_id.notNull() && participant_id.notNull())
                 {
                     LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
                 }
-- 
cgit v1.2.3


From a25e6eb733bb8f6a0e9f8de1094155f685c6216d Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 28 Dec 2012 16:11:05 +0200
Subject: CHUI-453 FIXED Tooltip on chevron in torn-off conversation is
 incorrect: implemented suitable tool-tips; fixed a small separate bug
 ("tooltip_to_separate_window"/"tooltip_to_main_window" for Tear-Off Button:
 was shown reverse)

---
 indra/newview/llfloaterimsessiontab.cpp            | 24 ++++++++++++++--------
 .../skins/default/xui/en/floater_im_session.xml    |  9 ++++++++
 2 files changed, 24 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 4e79bd0ac8..a79b4b3f1d 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -606,8 +606,8 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 	// prevent start conversation before its container
     LLFloaterIMContainer::getInstance();
 
-	bool is_torn_off = checkIfTornOff();
-	if (!is_torn_off)
+	bool is_not_torn_off = !checkIfTornOff();
+	if (is_not_torn_off)
 	{
 		hideAllStandardButtons();
 	}
@@ -616,7 +616,7 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 
 	// Participant list should be visible only in torn off floaters.
 	bool is_participant_list_visible =
-			is_torn_off
+			!is_not_torn_off
 			&& gSavedSettings.getBOOL("IMShowControlPanel")
 			&& !mIsP2PChat;
 
@@ -624,22 +624,28 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
-	bool is_expanded = !is_torn_off || is_participant_list_visible;
+	bool is_expanded = is_not_torn_off || is_participant_list_visible;
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+	mExpandCollapseBtn->setToolTip(
+			is_not_torn_off?
+				getString("expcol_button_not_tearoff_tooltip") :
+				(is_expanded?
+					getString("expcol_button_tearoff_and_expanded_tooltip") :
+					getString("expcol_button_tearoff_and_collapsed_tooltip")));
 
 	// toggle floater's drag handle and title visibility
 	if (mDragHandle)
 	{
-		mDragHandle->setTitleVisible(is_torn_off);
+		mDragHandle->setTitleVisible(!is_not_torn_off);
 	}
 
 	// The button (>>) should be disabled for torn off P2P conversations.
-	mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat);
+	mExpandCollapseBtn->setEnabled(is_not_torn_off || !mIsP2PChat);
 
-	mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon"));
-	mTearOffBtn->setToolTip(getString(!is_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
+	mTearOffBtn->setImageOverlay(getString(is_not_torn_off? "tear_off_icon" : "return_icon"));
+	mTearOffBtn->setToolTip(getString(is_not_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
 
-	mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat);
+	mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat);
 
 	enableDisableCallBtn();
 
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 9e2132dc3b..8f0574177f 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -49,6 +49,15 @@
   <floater.string
      name="end_call_button_tooltip"
      value="Close voice connection"/>
+   <floater.string
+     name="expcol_button_not_tearoff_tooltip"
+     value="Collapse this pane"/>
+   <floater.string
+     name="expcol_button_tearoff_and_expanded_tooltip"
+     value="Collapse participant list"/>
+   <floater.string
+     name="expcol_button_tearoff_and_collapsed_tooltip"
+     value="Expand participant list"/>
     <view
         follows="all"
         layout="topleft"
-- 
cgit v1.2.3


From 034143225ba60e8bb1163501e2f57c2be932578b Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 2 Jan 2013 13:10:42 -0800
Subject: CHUI-499: Removing debug code

---
 .../newview/lldonotdisturbnotificationstorage.cpp  | 25 ----------------------
 1 file changed, 25 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index bf3dcae1f3..f4560d5668 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -29,11 +29,6 @@
 
 #include "lldonotdisturbnotificationstorage.h"
 
-#define XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT 0
-
-#if XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
-#include "llchannelmanager.h"
-#endif // XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
 #include "llcommunicationchannel.h"
 #include "lldir.h"
 #include "llerror.h"
@@ -41,9 +36,6 @@
 #include "llnotifications.h"
 #include "llnotificationhandler.h"
 #include "llnotificationstorage.h"
-#if XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
-#include "llscreenchannel.h"
-#endif // XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
 #include "llscriptfloater.h"
 #include "llsd.h"
 #include "llsingleton.h"
@@ -109,12 +101,6 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 	{
 		return;
 	}
-
-#if XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
-	LLNotificationsUI::LLScreenChannel* notification_channel =
-		dynamic_cast<LLNotificationsUI::LLScreenChannel*>(LLNotificationsUI::LLChannelManager::getInstance()->
-		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-#endif // XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
 	
 	LLNotifications& instance = LLNotifications::instance();
 	
@@ -146,17 +132,6 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 			
 			instance.add(notification);
 		}
-
-#if XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
-		// hide script floaters so they don't confuse the user and don't overlap startup toast
-		LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
-		
-		if(notification_channel)
-		{
-			// hide saved toasts so they don't confuse the user
-			notification_channel->hideToast(notification->getID());
-		}
-#endif // XXX_STINSON_HIDE_NOTIFICATIONS_ON_DND_EXIT
 	}
 
 	// Clear the communication channel history and rewrite the save file to empty it as well
-- 
cgit v1.2.3


From f40ee4792d948ca99d19bdd6f645faea07e15f47 Mon Sep 17 00:00:00 2001
From: maximbproductengine <maximbproductengine@lindenlab.com>
Date: Thu, 3 Jan 2013 06:35:40 +0200
Subject: CHUI-616 (Left Click on participant name in torn off conference moves
 focus to conversation floater)

---
 indra/newview/llconversationview.cpp | 21 ---------------------
 indra/newview/llconversationview.h   |  2 --
 2 files changed, 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index e51efd48f5..903dd2a407 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -547,27 +547,6 @@ void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
     LLFolderViewItem::onMouseLeave(x, y, mask);
 }
 
-BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
-{
-	LLConversationItem* item = NULL;
-	LLConversationViewSession* session_widget =
-			dynamic_cast<LLConversationViewSession *>(this->getParentFolder());
-	if (session_widget)
-	{
-	    item = dynamic_cast<LLConversationItem*>(session_widget->getViewModelItem());
-	}
-    LLUUID session_id = item? item->getUUID() : LLUUID();
-    BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask);
-
-    if(result)
-    {
-        (LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
-            selectConversationPair(session_id, false);
-    }
-
-	return result;
-}
-
 S32 LLConversationViewParticipant::getLabelXPos()
 {
     return getIndentation() + mAvatarIcon->getRect().getWidth() + mIconPad;
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 74443e1d88..5f6acfb9ab 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -132,8 +132,6 @@ public:
     void addToFolder(LLFolderViewFolder* folder);
 	void addToSession(const LLUUID& session_id);
 
-    /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
-
     void onMouseEnter(S32 x, S32 y, MASK mask);
     void onMouseLeave(S32 x, S32 y, MASK mask);
 
-- 
cgit v1.2.3


From 3d83fc3da5b0fa20bb631bfd2c94368946905675 Mon Sep 17 00:00:00 2001
From: maximbproductengine <maximbproductengine@lindenlab.com>
Date: Thu, 3 Jan 2013 06:43:25 +0200
Subject: CHUI-608 (Conversations floater can be resized too small once a
 conversation is torn off)

---
 indra/newview/llfloaterimcontainer.h    | 3 ++-
 indra/newview/llfloaterimsessiontab.cpp | 5 +++++
 2 files changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 09a24c0105..8daed46c7d 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -106,6 +106,8 @@ public:
     bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
     void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
 
+	void assignResizeLimits();
+
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
 	avatarID_panel_map_t mSessions;
@@ -154,7 +156,6 @@ private:
 	void toggleAllowTextChat(const LLUUID& participant_uuid);
 	void toggleMute(const LLUUID& participant_id, U32 flags);
 	void openNearbyChat();
-	void assignResizeLimits();
 
 	LLButton* mExpandCollapseBtn;
 	LLButton* mStubCollapseBtn;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index f5b657fa60..4e79bd0ac8 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -751,6 +751,11 @@ void LLFloaterIMSessionTab::onTearOffClicked()
 	{
 		forceReshape();
 	}
+	LLFloaterIMContainer* container = LLFloaterIMContainer::getInstance();
+	if (container)
+	{
+		container->assignResizeLimits();
+	}
 	refreshConversation();
 	updateGearBtn();
 }
-- 
cgit v1.2.3


From c464adc8ae35d3656e8de6aa459eb4615bb34c6f Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Thu, 3 Jan 2013 14:03:33 +0200
Subject: CHUI-636 FIXED Enable group context menu options, if uuid is empty
 and selected model item is group chat. In addition enable Chat history item
 for ad-hoc and group conversations.

---
 indra/newview/llfloaterimcontainer.cpp | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2019a35faa..61a67a1f9f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1101,12 +1101,20 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 	uuid_vec_t uuids;
 	getParticipantUUIDs(uuids);
 
+	//Enable Chat history item for ad-hoc and group conversations
+	if ("can_chat_history" == item)
+	{
+		if (getCurSelectedViewModelItem()->getType() != LLConversationItem::CONV_PARTICIPANT)
+		{
+			return isConversationLoggingAllowed();
+		}
+	}
 
-	// If nothing is selected, everything needs to be disabled
+	// If nothing is selected(and selected item is not group chat), everything needs to be disabled
 	if (uuids.size() <= 0)
-    {
-        return false;
-    }
+	{
+		return getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP;
+	}
 
 	if("can_activate_group" == item)
     {
@@ -1123,7 +1131,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
 	{
 		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
 	}
-	
+
 	// Extract the single select info
 	bool is_single_select = (uuids.size() == 1);
 	const LLUUID& single_id = uuids.front();
-- 
cgit v1.2.3


From f4902521f58956eda7701770eec51763a7663d3c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 3 Jan 2013 15:12:11 +0200
Subject: CHUI-631 FIXED 'Nearby chat' is not selected in Conversations floater
 after closing separate conversation if list of participants was expand in
 Conversations floater: force select 'Nearby chat' when session floater is
 destroyed

---
 indra/newview/llfloaterimsessiontab.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index a79b4b3f1d..76643b0235 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -82,6 +82,13 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
 {
 	delete mRefreshTimer;
+
+	// Select Nearby Chat session
+	LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+	if (container)
+	{
+		container->selectConversationPair(LLUUID(NULL), true);
+	}
 }
 
 //static
-- 
cgit v1.2.3


From 799c1f241f66db6d8701ee8c4339a5cce41c3c47 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 3 Jan 2013 18:59:20 +0200
Subject: CHUI-628 FIXED Open conversation log menu option not active in
 conversation floater when nearby chat is selected: Determination of the
 availability menu item was moved to the right place

---
 indra/newview/llfloaterimcontainer.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 61a67a1f9f..50acd4ae24 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1101,6 +1101,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 	uuid_vec_t uuids;
 	getParticipantUUIDs(uuids);
 
+	if ("conversation_log" == item)
+	{
+		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+	}
+
 	//Enable Chat history item for ad-hoc and group conversations
 	if ("can_chat_history" == item)
 	{
@@ -1127,11 +1132,6 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 
 bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_vec_t& uuids)
 {
-	if ("conversation_log" == item)
-	{
-		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
-	}
-
 	// Extract the single select info
 	bool is_single_select = (uuids.size() == 1);
 	const LLUUID& single_id = uuids.front();
-- 
cgit v1.2.3


From aa6fee292d1721eac6f0f1f270844e01e06979d4 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 3 Jan 2013 14:19:04 -0800
Subject: CHUI-499: Fixed a serialization problem where the a notification's
 objectInfo was not being serialized/deserialized.

---
 indra/llui/llnotifications.cpp                      | 5 +++++
 indra/llui/llnotifications.h                        | 4 +++-
 indra/newview/lldonotdisturbnotificationstorage.cpp | 2 +-
 indra/newview/llnotificationstorage.cpp             | 7 +------
 indra/newview/llviewermessage.cpp                   | 3 +++
 indra/newview/llviewermessage.h                     | 1 +
 6 files changed, 14 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index c9b4399bef..8aa0b6f110 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -517,6 +517,11 @@ LLSD LLNotification::asLLSD()
 	p.expiry = mExpiresAt;
 	p.priority = mPriority;
 
+    if(mResponder)
+    {
+        p.functor.responder_sd = mResponder->asLLSD();
+    }
+    
 	if(!mResponseFunctorName.empty())
 	{
 		p.functor.name = mResponseFunctorName;
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 42dee4c3e9..2a6391f49e 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -322,11 +322,13 @@ public:
 			Alternative<std::string>										name;
 			Alternative<LLNotificationFunctorRegistry::ResponseFunctor>	function;
 			Alternative<LLNotificationResponderPtr>						responder;
+            Alternative<LLSD>						                    responder_sd;
 
 			Functor()
 			:	name("responseFunctor"),
 				function("functor"),
-				responder("responder")
+				responder("responder"),
+                responder_sd("responder_sd")
 			{}
 		};
 		Optional<Functor>						functor;
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index f4560d5668..6407a3fa0c 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -118,7 +118,7 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 		}
 		else
 		{
-			LLNotificationResponderInterface* responder = createResponder(notification_params["name"], notification_params["responder"]);
+			LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
 			if (responder == NULL)
 			{
 				LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index b797775369..4c5b7cc198 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -126,13 +126,8 @@ LLResponderRegistry::LLResponderRegistry()
 	, mBuildMap()
 {
 	add("ObjectGiveItem", &create<LLOfferInfo>);
-	add("OwnObjectGiveItem", &create<LLOfferInfo>);
 	add("UserGiveItem", &create<LLOfferInfo>);
-
-	add("TeleportOffered", &create<LLOfferInfo>);
-	add("TeleportOffered_MaturityExceeded", &create<LLOfferInfo>);
-
-	add("OfferFriendship", &create<LLOfferInfo>);
+    add("offer_info", &create<LLOfferInfo>);
 }
 
 LLResponderRegistry::~LLResponderRegistry()
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 04dd7c911b..d264a18597 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1361,6 +1361,8 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
 			gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
 }
 
+std::string LLOfferInfo::mResponderType = "offer_info";
+
 LLOfferInfo::LLOfferInfo()
  : LLNotificationResponderInterface()
  , mFromGroup(FALSE)
@@ -1406,6 +1408,7 @@ LLOfferInfo::LLOfferInfo(const LLOfferInfo& info)
 LLSD LLOfferInfo::asLLSD()
 {
 	LLSD sd;
+    sd["responder_type"] = mResponderType;
 	sd["im_type"] = mIM;
 	sd["from_id"] = mFromID;
 	sd["from_group"] = mFromGroup;
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 447fdeb9c7..3237f3fbdd 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -229,6 +229,7 @@ public:
 
 	void forceResponse(InventoryOfferResponse response);
 
+    static std::string mResponderType;
 	EInstantMessage mIM;
 	LLUUID mFromID;
 	BOOL mFromGroup;
-- 
cgit v1.2.3


From 0e6ff3e7021b2e72f02b22550bbb96bc3674cba4 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 3 Jan 2013 14:37:24 -0800
Subject: CHUI-654 : Fixed! Select the Nearby Chat directly when one
 conversation only left, don't finesse with a root UUID that might not be NULL

---
 indra/newview/llfloaterimcontainer.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 50acd4ae24..9fe67e99da 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1430,11 +1430,10 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	{
 		is_widget_selected = widget->isSelected();
 		new_selection = mConversationsRoot->getNextFromChild(widget);
-		if(new_selection == NULL)
+		if (!new_selection)
 		{
 			new_selection = mConversationsRoot->getPreviousFromChild(widget);
 		}
-
 		widget->destroyView();
 	}
 	
@@ -1446,14 +1445,20 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	if (change_focus)
 	{
 		setFocus(TRUE);
-		if(new_selection != NULL)
+		if (new_selection)
 		{
 			if (mConversationsWidgets.size() == 1)
-				new_selection = new_selection->getParentFolder();
-			LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
-			if(vmi != NULL)
 			{
-				selectConversationPair(vmi->getUUID(), true);
+				// If only one widget is left, it has to be the Nearby Chat. Select it directly.
+				selectConversationPair(LLUUID(NULL), true);
+			}
+			else
+			{
+				LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+				if (vmi)
+				{
+					selectConversationPair(vmi->getUUID(), true);
+				}
 			}
 		}
 	}
-- 
cgit v1.2.3


From 3d1feec7641051386733405186cfe81b68a929ca Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 3 Jan 2013 15:11:53 -0800
Subject: CHUI-656 : Fixed. getTypedInstance() will create an instance if not
 found. Do not use that in destructors (bad...) or in places where creation is
 not required. Use findTypedInstance() instead.

---
 indra/newview/llfloaterimsessiontab.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 76643b0235..7b34a86f24 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -84,7 +84,7 @@ LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
 	delete mRefreshTimer;
 
 	// Select Nearby Chat session
-	LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+	LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
 	if (container)
 	{
 		container->selectConversationPair(LLUUID(NULL), true);
@@ -329,7 +329,7 @@ void LLFloaterIMSessionTab::onFocusReceived()
 
 	LLTransientDockableFloater::onFocusReceived();
 
-	LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+	LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
 	if (container)
 	{
 		container->selectConversationPair(mSessionID, true);
-- 
cgit v1.2.3


From 9d687cc0042a6972a603778359055394c1cf0850 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 4 Jan 2013 15:14:24 +0200
Subject: CHUI-637 FIXED Call requestArrange() to update widget state.

---
 indra/newview/llfloaterimcontainer.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 9fe67e99da..22db4dd0eb 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -678,6 +678,7 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 		    {
 		    	widget->setOpen(false);
 		    }
+		    widget->requestArrange();
 }
 	}
 }
-- 
cgit v1.2.3


From 4d971c43518f02fe202cf437f059250061cd9756 Mon Sep 17 00:00:00 2001
From: maximbproductengine <maximbproductengine@lindenlab.com>
Date: Fri, 4 Jan 2013 16:48:34 +0200
Subject: CHUI-608 (Conversations floater can be resized too small once a
 conversation is torn off)

---
 indra/newview/llfloaterimcontainer.cpp  | 6 ++++++
 indra/newview/llfloaterimcontainer.h    | 1 +
 indra/newview/llfloaterimsessiontab.cpp | 5 -----
 3 files changed, 7 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2019a35faa..151d901708 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -605,6 +605,12 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
 	LLMultiFloater::setVisible(visible);
 }
 
+void LLFloaterIMContainer::updateResizeLimits()
+{
+	LLMultiFloater::updateResizeLimits();
+	assignResizeLimits();
+}
+
 void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 {
 	if (mMessagesPane->isCollapsed() == collapse)
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 8daed46c7d..0cd1b6759b 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -60,6 +60,7 @@ public:
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void draw();
 	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void updateResizeLimits();
 	void onCloseFloater(LLUUID& id);
 
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 4e79bd0ac8..f5b657fa60 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -751,11 +751,6 @@ void LLFloaterIMSessionTab::onTearOffClicked()
 	{
 		forceReshape();
 	}
-	LLFloaterIMContainer* container = LLFloaterIMContainer::getInstance();
-	if (container)
-	{
-		container->assignResizeLimits();
-	}
 	refreshConversation();
 	updateGearBtn();
 }
-- 
cgit v1.2.3


From b1ba208e7fcb8dbaa2c47b70fe580094982e36dd Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Sat, 5 Jan 2013 00:09:36 +0200
Subject: CHUI-643 W.I.P. Collapsed conversations floater has huge right
 padding: corrected of a imcontainer's resize calculating

---
 indra/newview/llfloaterimcontainer.cpp             | 59 ++++++++++++----------
 .../skins/default/xui/en/floater_im_container.xml  |  3 +-
 2 files changed, 34 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index ae243d6495..69d6f1ca38 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -618,34 +618,34 @@ void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 		return;
 	}
 
+	// Save current width of panels before collapsing/expanding right pane.
+	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
+    S32 msg_pane_width = mMessagesPane->getRect().getWidth();
+
 	if (collapse)
 	{
 		// Save the messages pane width before collapsing it.
-		gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", mMessagesPane->getRect().getWidth());
+		gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", msg_pane_width);
 
 		// Save the order in which the panels are closed to reverse user's last action.
 		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
 	}
 
-	// Save left pane rectangle before collapsing/expanding right pane.
-	LLRect prevRect = mConversationsPane->getRect();
-
 	// Show/hide the messages pane.
 	mConversationsStack->collapsePanel(mMessagesPane, collapse);
 
-	if (!collapse)
-	{
-		// Make sure layout is updated before resizing conversation pane.
-		mConversationsStack->updateLayout();
-	}
+	// Make sure layout is updated before resizing conversation pane.
+	mConversationsStack->updateLayout();
 
 	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+
 	if (!collapse)
 	{
 		// Restore conversation's pane previous width after expanding messages pane.
-		mConversationsPane->setTargetDim(prevRect.getWidth());
+		mConversationsPane->setTargetDim(conv_pane_width);
 	}
 }
+
 void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 {
 	if (mConversationsPane->isCollapsed() == collapse)
@@ -657,10 +657,13 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 	button_panel->setVisible(!collapse);
 	mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon"));
 
+	// Save current width of panels before collapsing/expanding right pane.
+	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
+
 	if (collapse)
 	{
 		// Save the conversations pane width before collapsing it.
-		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", mConversationsPane->getRect().getWidth());
+		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", conv_pane_width);
 
 		// Save the order in which the panels are closed to reverse user's last action.
 		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", !mMessagesPane->isCollapsed());
@@ -668,8 +671,9 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 
 	mConversationsStack->collapsePanel(mConversationsPane, collapse);
 
-	S32 collapsed_width = mConversationsPane->getMinDim();
-	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - collapsed_width);
+	S32 delta_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - mConversationsPane->getMinDim();
+
+	updateState(collapse, delta_width);
 
 	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
 			widget_it != mConversationsWidgets.end(); ++widget_it)
@@ -685,7 +689,7 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 		    	widget->setOpen(false);
 		    }
 		    widget->requestArrange();
-}
+        }
 	}
 }
 
@@ -693,6 +697,8 @@ void LLFloaterIMContainer::updateState(bool collapse, S32 delta_width)
 {
 	LLRect floater_rect = getRect();
 	floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
+S32 debug_var = floater_rect.getWidth();
+debug_var = debug_var + 1;
 
 	// Set by_user = true so that reshaped rect is saved in user_settings.
 	setShape(floater_rect, true);
@@ -705,29 +711,28 @@ void LLFloaterIMContainer::updateState(bool collapse, S32 delta_width)
 	setCanResize(is_left_pane_expanded || is_right_pane_expanded);
 	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
 
+    assignResizeLimits();
+
     // force set correct size for the title after show/hide minimize button
 	LLRect cur_rect = getRect();
 	LLRect force_rect = cur_rect;
 	force_rect.mRight = cur_rect.mRight + 1;
     setRect(force_rect);
     setRect(cur_rect);
-
-    // restore floater's resize limits (prevent collapse when left panel is expanded)
-	if (is_left_pane_expanded && !is_right_pane_expanded)
-	{
-		S32 expanded_min_size = mConversationsPane->getExpandedMinDim();
-        setResizeLimits(expanded_min_size, expanded_min_size);
-	}
-
-    assignResizeLimits();
 }
 
 void LLFloaterIMContainer::assignResizeLimits()
 {
-	const LLRect& conv_rect = mConversationsPane->isCollapsed() ? LLRect() : mConversationsPane->getRect();
-	S32 msg_limits  = mMessagesPane->isCollapsed() ? 0 : mMessagesPane->getExpandedMinDim();
-	S32 x_limits = conv_rect.getWidth() + msg_limits;
-	setResizeLimits(x_limits + LLPANEL_BORDER_WIDTH * 3, getMinHeight());
+	bool is_conv_pane_expanded = !mConversationsPane->isCollapsed();
+	bool is_msg_pane_expanded = !mMessagesPane->isCollapsed();
+
+    S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3);
+    S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH;
+	S32 conv_pane_current_width = is_conv_pane_expanded? mConversationsPane->getRect().getWidth() : mConversationsPane->getMinDim();
+	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
+	S32 new_min_width = conv_pane_current_width + msg_pane_min_width + summary_width_of_visible_borders;
+
+	setResizeLimits(new_min_width, getMinHeight());
 }
 
 void LLFloaterIMContainer::onAddButtonClicked()
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index e7638fe669..951665552f 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -14,7 +14,8 @@
  title="CONVERSATIONS"
  bottom="-50"
  right="-5"
- width="450">
+ width="450"
+ min_width="38">
     <string
      name="collapse_icon"
      value="Conv_toolbar_collapse"/>
-- 
cgit v1.2.3


From 118201943da157b6932d8c79ab3eb3d8c3c0a9a4 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 4 Jan 2013 23:54:38 +0200
Subject: CHUI-643 FIXED Collapsed conversations floater has huge right
 padding: prevent of a rewriting mOriginMinWidth and mOriginMinHeight to
 default values

---
 indra/llui/llmultifloater.cpp          | 10 ++++------
 indra/newview/llfloaterimcontainer.cpp | 15 ++++++++++++---
 indra/newview/llfloaterimcontainer.h   |  2 +-
 3 files changed, 17 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index 179b251cdb..59faabd482 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -37,12 +37,10 @@
 //
 
 LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
-	: LLFloater(key),
-	  mTabContainer(NULL),
-	  mTabPos(LLTabContainer::TOP),
-	  mAutoResize(TRUE),
-	  mOrigMinWidth(params.min_width),
-	  mOrigMinHeight(params.min_height)
+	: LLFloater(key)
+	, mTabContainer(NULL)
+	, mTabPos(LLTabContainer::TOP)
+	, mAutoResize(TRUE)
 {
 }
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 69d6f1ca38..5624788e45 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -56,8 +56,8 @@
 //
 // LLFloaterIMContainer
 //
-LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed)
-:	LLMultiFloater(seed),
+LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& params /*= getDefaultParams()*/)
+:	LLMultiFloater(seed, params),
 	mExpandCollapseBtn(NULL),
 	mConversationsRoot(NULL),
 	mConversationsEventStream("ConversationsEvents"),
@@ -153,6 +153,9 @@ void LLFloaterIMContainer::onCurrentChannelChanged(const LLUUID& session_id)
 
 BOOL LLFloaterIMContainer::postBuild()
 {
+	mOrigMinWidth = getMinWidth();
+	mOrigMinHeight = getMinHeight();
+
 	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLFloaterIMContainer::onNewMessageReceived, this, _1));
 	// Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
 	// mTabContainer will be initialized in LLMultiFloater::addChild()
@@ -657,7 +660,7 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 	button_panel->setVisible(!collapse);
 	mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon"));
 
-	// Save current width of panels before collapsing/expanding right pane.
+	// Save current width of Conversation panel before collapsing/expanding right pane.
 	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
 
 	if (collapse)
@@ -1408,6 +1411,12 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 			current_participant_model++;
 		}
 	}
+
+	if (uuid.notNull() && im_sessionp->isP2PSessionType())
+	{
+		item->fetchAvatarName(LLIMModel::getInstance()->getOtherParticipantID(uuid));
+	}
+
 	// Do that too for the conversation dialog
     LLFloaterIMSessionTab *conversation_floater = (uuid.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(uuid)));
 	if (conversation_floater)
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 0cd1b6759b..85d950c58b 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -53,7 +53,7 @@ class LLFloaterIMContainer
 	, public LLIMSessionObserver
 {
 public:
-	LLFloaterIMContainer(const LLSD& seed);
+	LLFloaterIMContainer(const LLSD& seed, const Params& params = getDefaultParams());
 	virtual ~LLFloaterIMContainer();
 	
 	/*virtual*/ BOOL postBuild();
-- 
cgit v1.2.3


From e59458590535d7fe571f9504fe97caa4e15701e6 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Sat, 5 Jan 2013 00:19:54 +0200
Subject: CHUI-643 FIXED Collapsed conversations floater has huge right
 padding: clean up; remove debug code

---
 indra/newview/llfloaterimcontainer.cpp | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 5624788e45..09d83e2a8f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -700,8 +700,6 @@ void LLFloaterIMContainer::updateState(bool collapse, S32 delta_width)
 {
 	LLRect floater_rect = getRect();
 	floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
-S32 debug_var = floater_rect.getWidth();
-debug_var = debug_var + 1;
 
 	// Set by_user = true so that reshaped rect is saved in user_settings.
 	setShape(floater_rect, true);
@@ -729,6 +727,8 @@ void LLFloaterIMContainer::assignResizeLimits()
 	bool is_conv_pane_expanded = !mConversationsPane->isCollapsed();
 	bool is_msg_pane_expanded = !mMessagesPane->isCollapsed();
 
+	// With two panels visible number of borders is three, because the borders
+	// between the panels are merged into one
     S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3);
     S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH;
 	S32 conv_pane_current_width = is_conv_pane_expanded? mConversationsPane->getRect().getWidth() : mConversationsPane->getMinDim();
@@ -1412,11 +1412,6 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 		}
 	}
 
-	if (uuid.notNull() && im_sessionp->isP2PSessionType())
-	{
-		item->fetchAvatarName(LLIMModel::getInstance()->getOtherParticipantID(uuid));
-	}
-
 	// Do that too for the conversation dialog
     LLFloaterIMSessionTab *conversation_floater = (uuid.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(uuid)));
 	if (conversation_floater)
-- 
cgit v1.2.3


From 02ca16c1334d1409d8b14136f76305686796c359 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 4 Jan 2013 17:58:30 -0800
Subject: CHUI-499: Now when existing DND mode, stored IM's will not show a
 toast but instead flash the conversation line item and Chat FUI button.

---
 indra/llui/llnotifications.cpp                     |  3 +-
 indra/llui/llnotifications.h                       | 18 ++++-
 .../newview/lldonotdisturbnotificationstorage.cpp  | 10 ++-
 indra/newview/llimhandler.cpp                      | 86 ++++++++++++----------
 indra/newview/llimview.cpp                         | 37 ++++++++++
 5 files changed, 110 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 8aa0b6f110..9ba598995f 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -475,7 +475,8 @@ LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) :
 	mIgnored(false),
 	mResponderObj(NULL),
 	mId(p.id.isProvided() ? p.id : LLUUID::generateNewID()),
-	mOfferFromAgent(p.offer_from_agent)
+	mOfferFromAgent(p.offer_from_agent),
+    mIsDND(p.is_dnd)
 {
 	if (p.functor.name.isChosen())
 	{
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 2a6391f49e..092a9acd7c 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -316,6 +316,7 @@ public:
 		Optional<LLNotificationContext*>		context;
 		Optional<void*>							responder;
 		Optional<bool>							offer_from_agent;
+        Optional<bool>							is_dnd;
 
 		struct Functor : public LLInitParam::ChoiceBlock<Functor>
 		{
@@ -342,7 +343,8 @@ public:
 			form_elements("form"),
 			substitutions("substitutions"),
 			expiry("expiry"),
-			offer_from_agent("offer_from_agent", false)
+			offer_from_agent("offer_from_agent", false),
+            is_dnd("is_dnd", false)
 		{
 			time_stamp = LLDate::now();
 			responder = NULL;
@@ -356,7 +358,8 @@ public:
 			form_elements("form"),
 			substitutions("substitutions"),
 			expiry("expiry"),
-			offer_from_agent("offer_from_agent", false)
+			offer_from_agent("offer_from_agent", false),
+            is_dnd("is_dnd", false)
 		{
 			functor.name = _name;
 			name = _name;
@@ -383,6 +386,7 @@ private:
 	void* mResponderObj; // TODO - refactor/remove this field
 	LLNotificationResponderPtr mResponder;
 	bool mOfferFromAgent;
+    bool mIsDND;
 
 	// a reference to the template
 	LLNotificationTemplatePtr mTemplatep;
@@ -523,6 +527,16 @@ public:
 		return mOfferFromAgent;
 	}
 
+    bool isDND() const
+    {
+        return mIsDND;
+    }
+
+    void setDND(const bool flag)
+    {
+        mIsDND = flag;
+    }
+
 	std::string getType() const;
 	std::string getMessage() const;
 	std::string getFooter() const;
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 6407a3fa0c..9bb2f27a46 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -109,15 +109,19 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 		 ++notification_it)
 	{
 		LLSD notification_params = *notification_it;
-		LLNotificationPtr notification(new LLNotification(notification_params));
+        const LLUUID& notificationID = notification_params["id"];
+        LLNotificationPtr notification = instance.find(notificationID);
 		
-		const LLUUID& notificationID = notification->id();
-		if (instance.find(notificationID))
+        //Notification already exists in notification pipeline (same instance of app running)
+		if (notification)
 		{
+            notification->setDND(true);
 			instance.update(notification);
 		}
+        //Notification doesn't exist (different instance since restarted app while in DND mode)
 		else
 		{
+            notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
 			LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
 			if (responder == NULL)
 			{
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 72967eb6c7..c2b29f36e8 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -36,6 +36,8 @@
 
 using namespace LLNotificationsUI;
 
+extern void process_dnd_im(const LLSD& notification);
+
 //--------------------------------------------------------------------------
 LLIMHandler::LLIMHandler()
 :	LLCommunicationNotificationHandler("IM Notifications", "notifytoast")
@@ -60,44 +62,52 @@ void LLIMHandler::initChannel()
 //--------------------------------------------------------------------------
 bool LLIMHandler::processNotification(const LLNotificationPtr& notification)
 {
-	if(mChannel.isDead())
-	{
-		return false;
-	}
-
-	// arrange a channel on a screen
-	if(!mChannel.get()->getVisible())
-	{
-		initChannel();
-	}
-
-	LLSD substitutions = notification->getSubstitutions();
-
-	// According to comments in LLIMMgr::addMessage(), if we get message
-	// from ourselves, the sender id is set to null. This fixes EXT-875.
-	LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
-	if (avatar_id.isNull())
-		avatar_id = gAgentID;
-
-	LLToastIMPanel::Params im_p;
-	im_p.notification = notification;
-	im_p.avatar_id = avatar_id;
-	im_p.from = substitutions["FROM"].asString();
-	im_p.time = substitutions["TIME"].asString();
-	im_p.message = substitutions["MESSAGE"].asString();
-	im_p.session_id = substitutions["SESSION_ID"].asUUID();
-
-	LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
-
-	LLToast::Params p;
-	p.notif_id = notification->getID();
-	p.session_id = im_p.session_id;
-	p.notification = notification;
-	p.panel = im_box;
-	p.can_be_stored = false;
-	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-	if(channel)
-		channel->addToast(p);
+    if(notification->isDND())
+    {
+        LLSD data = notification->asLLSD(); //don't need this if retrieve needed data from notification getters
+        process_dnd_im(data);
+    }
+    else
+    {
+	    if(mChannel.isDead())
+	    {
+		    return false;
+	    }
+
+	    // arrange a channel on a screen
+	    if(!mChannel.get()->getVisible())
+	    {
+		    initChannel();
+	    }
+
+	    LLSD substitutions = notification->getSubstitutions();
+
+	    // According to comments in LLIMMgr::addMessage(), if we get message
+	    // from ourselves, the sender id is set to null. This fixes EXT-875.
+	    LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
+	    if (avatar_id.isNull())
+		    avatar_id = gAgentID;
+
+	    LLToastIMPanel::Params im_p;
+	    im_p.notification = notification;
+	    im_p.avatar_id = avatar_id;
+	    im_p.from = substitutions["FROM"].asString();
+	    im_p.time = substitutions["TIME"].asString();
+	    im_p.message = substitutions["MESSAGE"].asString();
+	    im_p.session_id = substitutions["SESSION_ID"].asUUID();
+
+	    LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
+
+	    LLToast::Params p;
+	    p.notif_id = notification->getID();
+	    p.session_id = im_p.session_id;
+	    p.notification = notification;
+	    p.panel = im_box;
+	    p.can_be_stored = false;
+	    LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	    if(channel)
+		    channel->addToast(p);
+    }
 
 	return false;
 }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d736b81bb7..716e6fe7ba 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -101,6 +101,43 @@ BOOL LLSessionTimeoutTimer::tick()
 	return TRUE;
 }
 
+
+
+void process_dnd_im(const LLSD& notification)
+{
+    LLSD data = notification["substitutions"];
+    LLUUID sessionID = data["SESSION_ID"].asUUID();
+
+    //re-create the IM session if needed 
+    //(when coming out of DND mode upon app restart)
+    if(!gIMMgr->hasSession(sessionID))
+    {
+        //reconstruct session using data from the notification
+        std::string name = data["FROM"];
+        LLAvatarName av_name;
+        if (LLAvatarNameCache::get(data["FROM_ID"], &av_name))
+        {
+            name = av_name.getDisplayName();
+        }
+
+        
+        LLIMModel::getInstance()->newSession(sessionID, 
+            name, 
+            IM_NOTHING_SPECIAL, 
+            data["FROM_ID"], 
+            false, 
+            false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
+    }
+
+    //For now always flash conversation line item
+    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+    im_box->flashConversationItemWidget(sessionID, true);
+
+    //And flash toolbar button
+    gToolBarView->flashCommand(LLCommandId("chat"), true);
+}
+
+
 static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 									   const LLAvatarName& av_name,
 									   LLSD msg)
-- 
cgit v1.2.3


From 12554bffb34895533ed11013a780bfa088756a67 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 4 Jan 2013 20:23:14 -0800
Subject: CHUI-580 : Fixed : Avoid fetching names while reacting to display
 name checkbox change (overkill), make display name pref disabled when
 usePeopleAPI is off

---
 indra/newview/llconversationmodel.cpp  | 33 +++++++++++++++++++++++++--------
 indra/newview/llconversationmodel.h    |  6 ++++--
 indra/newview/llfloaterimcontainer.cpp |  2 +-
 indra/newview/llfloaterpreference.cpp  | 13 ++++++++++++-
 4 files changed, 42 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index b1f45d6d64..bc5b72e029 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -434,24 +434,31 @@ void LLConversationItemParticipant::fetchAvatarName()
 	}
 }
 
-void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
+void LLConversationItemParticipant::updateAvatarName()
 {
-    menuentry_vec_t items;
-    menuentry_vec_t disabled_items;
-
-	buildParticipantMenuOptions(items);
-	
-    hide_context_entries(menu, items, disabled_items);
+	llassert(getUUID().notNull());
+	if (getUUID().notNull())
+	{
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(getUUID(),&av_name))
+		{
+			updateAvatarName(av_name);
+		}
+	}
 }
 
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
 {
 	mAvatarNameCacheConnection.disconnect();
+	updateAvatarName(av_name);
+}
 
+void LLConversationItemParticipant::updateAvatarName(const LLAvatarName& av_name)
+{
 	mName = av_name.getUserName();
 	mDisplayName = av_name.getDisplayName();
 	mNeedsRefresh = true;
-	if(mParent != NULL)
+	if (mParent != NULL)
 	{
 		LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
 		if (parent_session != NULL)
@@ -463,6 +470,16 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 	}
 }
 
+void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+	
+	buildParticipantMenuOptions(items);
+	
+    hide_context_entries(menu, items, disabled_items);
+}
+
 LLConversationItemSession* LLConversationItemParticipant::getParentSession()
 {
 	LLConversationItemSession* parent_session = NULL;
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 743a6ba40b..6ae891203d 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -195,14 +195,16 @@ public:
 
 	virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
 
-	void fetchAvatarName();
+	void fetchAvatarName();		// fetch and update the avatar name
+	void updateAvatarName();	// get from the cache (do *not* fetch) and update the avatar name
 	LLConversationItemSession* getParentSession();
 
 	void dumpDebugData();
 	void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; }
 
 private:
-	void onAvatarNameCache(const LLAvatarName& av_name);
+	void onAvatarNameCache(const LLAvatarName& av_name);	// callback used by fetchAvatarName
+	void updateAvatarName(const LLAvatarName& av_name);
 
 	bool mIsMuted;		// default is false
 	bool mIsModerator;	// default is false
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 3c85f21188..e1288a763c 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -393,7 +393,7 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
 		{
 			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
 			// Get the avatar name for this participant id from the cache and update the model
-			participant_model->fetchAvatarName();
+			participant_model->updateAvatarName();
 			// Next participant
 			current_participant_model++;
 		}
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 13d8a79f8d..3d4a1c44d8 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1682,6 +1682,17 @@ LLPanelPreference::LLPanelPreference()
 //virtual
 BOOL LLPanelPreference::postBuild()
 {
+	////////////////////// PanelGeneral ///////////////////
+	if (hasChild("display_names_check"))
+	{
+		BOOL use_people_api = gSavedSettings.getBOOL("UsePeopleAPI");
+		LLCheckBoxCtrl* ctrl_display_name = getChild<LLCheckBoxCtrl>("display_names_check");
+		ctrl_display_name->setEnabled(use_people_api);
+		if (!use_people_api)
+		{
+			ctrl_display_name->setValue(FALSE);
+		}
+	}
 
 	////////////////////// PanelVoice ///////////////////
 	if (hasChild("voice_unavailable"))
@@ -1732,7 +1743,7 @@ BOOL LLPanelPreference::postBuild()
 		getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&showFavoritesOnLoginWarning, _1, _2));
 	}
 
-	// Panel Advanced
+	//////////////////////PanelAdvanced ///////////////////
 	if (hasChild("modifier_combo"))
 	{
 		//localizing if push2talk button is set to middle mouse
-- 
cgit v1.2.3


From 3d0ec3da5baea6bb2b9b72707a884ac7b516c4fd Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 7 Jan 2013 15:32:47 -0800
Subject: CHUI-659 : WIP : Verified (tested) and cleaned up some CHUI-101
 refactoring code.

---
 indra/llui/llfolderviewmodel.h           |  4 ++--
 indra/newview/llinventoryfilter.cpp      |  9 +++------
 indra/newview/llpanelobjectinventory.cpp | 10 +++++-----
 indra/newview/lltexturectrl.cpp          | 15 ---------------
 4 files changed, 10 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 7019857c0f..5837052565 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -401,8 +401,8 @@ public:
 	virtual const FilterType& getFilter() const		 { return mFilter; }
 	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
 
-	// TODO RN: remove this and put all filtering logic in view model
-	// add getStatusText and isFiltering()
+	// By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
+	// this method needs to be overloaded and return the relevant fetch status.
 	virtual bool contentsReady()					{ return true; }
 
 
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index c913269aad..92f2d33073 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -42,8 +42,6 @@
 #include "llclipboard.h"
 #include "lltrans.h"
 
-//TODO RN: fix use of static cast as much as possible
-
 LLFastTimer::DeclareTimer FT_FILTER_CLIPBOARD("Filter Clipboard");
 
 LLInventoryFilter::FilterOps::FilterOps(const Params& p)
@@ -83,7 +81,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
 
 bool LLInventoryFilter::check(const LLFolderViewModelItem* item) 
 {
-	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item);
+	const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item);
 	// Clipboard cut items are *always* filtered so we need this value upfront
 	const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
 
@@ -122,7 +120,7 @@ bool LLInventoryFilter::check(const LLInventoryItem* item)
 
 bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
 {
-	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item);
+	const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item);
 	if (!listener)
 	{
 		llerrs << "Folder view event listener not found." << llendl;
@@ -384,8 +382,7 @@ const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
 
 std::string::size_type LLInventoryFilter::getStringMatchOffset(LLFolderViewModelItem* item) const
 {
-	const LLFolderViewModelItemInventory* listener = static_cast<const LLFolderViewModelItemInventory*>(item);
-	return mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos;
+	return mFilterSubString.size() ? item->getSearchableName().find(mFilterSubString) : std::string::npos;
 }
 
 bool LLInventoryFilter::isDefault() const
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index a2aabb50b5..527aefe821 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1555,6 +1555,10 @@ void LLPanelObjectInventory::reset()
 
 	mCommitCallbackRegistrar.pushScope(); // push local callbacks
 	
+	// Reset the inventory model to show all folders by default
+	mInventoryViewModel.getFilter().setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+	
+	// Create a new folder view root
 	LLRect dummy_rect(0, 1, 1, 0);
 	LLFolderView::Params p;
 	p.name = "task inventory";
@@ -1566,11 +1570,7 @@ void LLPanelObjectInventory::reset()
 	p.view_model = &mInventoryViewModel;
 	p.root = NULL;
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
-	// this ensures that we never say "searching..." or "no items found"
-	//TODO RN: make this happen by manipulating filter object directly
-  	LLInventoryFilter& inventoryFilter = dynamic_cast<LLInventoryFilter&>(mFolders->getFolderViewModel()->getFilter());
-   	inventoryFilter.setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
-  
+
 	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
 	if (hasFocus())
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 65f0290060..007eb8e33f 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -652,26 +652,11 @@ void LLFloaterTexturePicker::draw()
 		{
 			folder_view->setPinningSelectedItem(mSelectedItemPinned);
 			folder_view->getViewModelItem()->dirtyFilter();
-			//TODO RN: test..still works without this?
-			//folder_view->arrangeFromRoot();
-
 			mSelectedItemPinned = TRUE;
 		}
 	}
 }
 
-// static
-/*
-void LLFloaterTexturePicker::onSaveAnotherCopyDialog( S32 option, void* userdata )
-{
-	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
-	if( 0 == option )
-	{
-		self->copyToInventoryFinal();
-	}
-}
-*/
-
 const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only)
 {
 	LLViewerInventoryCategory::cat_array_t cats;
-- 
cgit v1.2.3


From d68f4ff646378070c1a92b3dc53f791454395356 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 7 Jan 2013 17:42:11 -0800
Subject: CHUI-659 : WIP : Reimplemented favorite landmark sorting to follow
 favorites bar index sorting.

---
 indra/newview/llfolderviewmodelinventory.cpp | 53 ++++++++++++----------------
 1 file changed, 23 insertions(+), 30 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 8a4b4bae84..429315e33f 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -29,6 +29,7 @@
 #include "llinventorymodelbackgroundfetch.h"
 #include "llinventorypanel.h"
 #include "lltooldraganddrop.h"
+#include "llfavoritesbar.h"
 
 //
 // class LLFolderViewModelInventory
@@ -236,39 +237,31 @@ const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
 
 bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
 {
-	// ignore sort order for landmarks in the Favorites folder.
-	// they should be always sorted as in Favorites bar. See EXT-719
-	//TODO RN: fix sorting in favorites folder
-	//if (a->getSortGroup() == SG_ITEM
-	//	&& b->getSortGroup() == SG_ITEM
-	//	&& a->getInventoryType() == LLInventoryType::IT_LANDMARK
-	//	&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
-	//{
-
-	//	static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-
-	//	LLUUID a_uuid = a->getParentFolder()->getUUID();
-	//	LLUUID b_uuid = b->getParentFolder()->getUUID();
-
-	//	if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
-	//	{
-	//		// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
-	//		// or to LLInvFVBridge
-	//		LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a))->getItem();
-	//		LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b))->getItem();
-	//		if (!aitem || !bitem)
-	//			return false;
-	//		S32 a_sort = aitem->getSortField();
-	//		S32 b_sort = bitem->getSortField();
-	//		return a_sort < b_sort;
-	//	}
-	//}
+	// Ignore sort order for landmarks in the Favorites folder.
+	// In that folder, landmarks should be always sorted as in the Favorites bar. See EXT-719
+	if (a->getSortGroup() == SG_ITEM
+		&& b->getSortGroup() == SG_ITEM
+		&& a->getInventoryType() == LLInventoryType::IT_LANDMARK
+		&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	{
+		static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+		// If both landmarks are in the favorite folder...
+		if (gInventory.isObjectDescendentOf(a->getUUID(), favorites_folder_id) && gInventory.isObjectDescendentOf(b->getUUID(), favorites_folder_id))
+		{
+			// Get their index in that folder
+			S32 a_sort = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
+			S32 b_sort = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+			// Note: since there are both in the favorite, we shouldn't get negative index value...
+			if (!((a_sort < 0) && (b_sort < 0)))
+			{
+				return a_sort < b_sort;
+			}
+		}
+	}
 
 	// We sort by name if we aren't sorting by date
 	// OR if these are folders and we are sorting folders by name.
-	bool by_name = (!mByDate 
-		|| (mFoldersByName 
-		&& (a->getSortGroup() != SG_ITEM)));
+	bool by_name = (!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM)));
 
 	if (a->getSortGroup() != b->getSortGroup())
 	{
-- 
cgit v1.2.3


From 51d6589eedc408aa7f8a81009b1be356ddc99252 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 7 Jan 2013 18:02:28 -0800
Subject: CHUI-659 : WIP : Clean up typos in my own comments

---
 indra/newview/llfolderviewmodelinventory.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index 429315e33f..d47c28678d 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -245,13 +245,13 @@ bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a,
 		&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-		// If both landmarks are in the favorite folder...
+		// If both landmarks are in the Favorites folder...
 		if (gInventory.isObjectDescendentOf(a->getUUID(), favorites_folder_id) && gInventory.isObjectDescendentOf(b->getUUID(), favorites_folder_id))
 		{
 			// Get their index in that folder
 			S32 a_sort = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
 			S32 b_sort = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
-			// Note: since there are both in the favorite, we shouldn't get negative index value...
+			// Note: this test is a bit overkill: since they are both in the Favorites folder, we shouldn't get negative index values...
 			if (!((a_sort < 0) && (b_sort < 0)))
 			{
 				return a_sort < b_sort;
-- 
cgit v1.2.3


From d71c0ab32c744a6672e4364e3d090d317ec0647c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 7 Jan 2013 18:30:59 -0800
Subject: CHUI-659 : WIP : Clamp down on the number of rearrange we really
 need.

---
 indra/llui/llfolderviewitem.cpp              | 14 +++++++-------
 indra/newview/llfolderviewmodelinventory.cpp |  1 -
 2 files changed, 7 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 1281d6bd66..6f8bdb1919 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -1664,16 +1664,16 @@ void LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
 
 void LLFolderViewFolder::requestArrange()
 { 
-	//if ( mLastArrangeGeneration != -1)
+	if ( mLastArrangeGeneration != -1)
 	{
-	mLastArrangeGeneration = -1; 
-	// flag all items up to root
-	if (mParentFolder)
-	{
-		mParentFolder->requestArrange();
-	}
+		mLastArrangeGeneration = -1; 
+		// flag all items up to root
+		if (mParentFolder)
+		{
+			mParentFolder->requestArrange();
 		}
 	}
+}
 
 void LLFolderViewFolder::toggleOpen()
 {
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
index d47c28678d..586965e5a0 100644
--- a/indra/newview/llfolderviewmodelinventory.cpp
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -135,7 +135,6 @@ void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_gen
 
 	if (passed_filter_before != mPrevPassedAllFilters)
 	{
-		//TODO RN: ensure this still happens, but without dependency on folderview
 		LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
 		if (parent_folder)
 		{
-- 
cgit v1.2.3


From 0e7e877379b4ab0d8d8b7ae3ce8c9dfb91cc9de7 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 7 Jan 2013 19:12:32 -0800
Subject: CHUI-659 : WIP : Cleanup llfolderviewitem of filter code as it all
 moved into llfolderviewmodel.

---
 indra/llui/llfolderviewitem.cpp | 53 +++--------------------------------------
 1 file changed, 3 insertions(+), 50 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 6f8bdb1919..b7165f68b7 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -267,28 +267,11 @@ void LLFolderViewItem::refresh()
 	mIconOpen = vmi.getIconOpen();
 	mIconOverlay = vmi.getIconOverlay();
 
-		if (mRoot->useLabelSuffix())
-		{
+	if (mRoot->useLabelSuffix())
+	{
 		mLabelStyle = vmi.getLabelStyle();
 		mLabelSuffix = vmi.getLabelSuffix();
-}
-
-	//TODO RN: make sure this logic still fires
-	//std::string searchable_label(mLabel);
-	//searchable_label.append(mLabelSuffix);
-	//LLStringUtil::toUpper(searchable_label);
-
-	//if (mSearchableLabel.compare(searchable_label))
-	//{
-	//	mSearchableLabel.assign(searchable_label);
-	//	vmi.dirtyFilter();
-	//	// some part of label has changed, so overall width has potentially changed, and sort order too
-	//	if (mParentFolder)
-	//	{
-	//		mParentFolder->requestSort();
-	//		mParentFolder->requestArrange();
-	//	}
-	//}
+	}
 
 	mLabelWidthDirty = true;
 	vmi.dirtyFilter();
@@ -1125,22 +1108,6 @@ BOOL LLFolderViewFolder::needsArrange()
 	return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); 
 }
 
-//TODO RN: get height resetting working
-//void LLFolderViewFolder::setPassedFilter(BOOL passed, BOOL passed_folder, S32 filter_generation)
-//{
-//	// if this folder is now filtered, but wasn't before
-//	// (it just passed)
-//	if (passed && !passedFilter(filter_generation))
-//	{
-//		// reset current height, because last time we drew it
-//		// it might have had more visible items than now
-//		mCurHeight = 0.f;
-//	}
-//
-//	LLFolderViewItem::setPassedFilter(passed, passed_folder, filter_generation);
-//}
-
-
 // Passes selection information on to children and record selection
 // information if necessary.
 BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
@@ -1620,20 +1587,6 @@ void LLFolderViewFolder::addItem(LLFolderViewItem* item)
 	{
 		getViewModelItem()->addChild(item->getViewModelItem());
 	}
-	
-	//TODO RN - make sort bubble up as long as parent Folder doesn't have anything matching sort criteria
-	//// Traverse parent folders and update creation date and resort, if necessary
-	//LLFolderViewFolder* parentp = this;
-	//while (parentp)
-	//{
-	//	if (parentp->mSortFunction.isByDate())
-	//	{
-	//		// parent folder doesn't have a time stamp yet, so get it from us
-	//		parentp->requestSort();
-	//	}
-
-	//	parentp = parentp->getParentFolder();
-	//}
 }
 
 // this is an internal method used for adding items to folders. 
-- 
cgit v1.2.3


From dbe1d2f0933db59493d11e9b3ab2d84ca884e28a Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 8 Jan 2013 14:38:30 +0200
Subject: CHUI-602 FIXED Return false if Selected view model item is null.

---
 indra/newview/llfloaterimcontainer.cpp | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 09d83e2a8f..82563b8736 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1124,16 +1124,23 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 	//Enable Chat history item for ad-hoc and group conversations
 	if ("can_chat_history" == item)
 	{
-		if (getCurSelectedViewModelItem()->getType() != LLConversationItem::CONV_PARTICIPANT)
+		if(getCurSelectedViewModelItem())
 		{
-			return isConversationLoggingAllowed();
+			if (getCurSelectedViewModelItem()->getType() != LLConversationItem::CONV_PARTICIPANT)
+			{
+				return isConversationLoggingAllowed();
+			}
 		}
 	}
 
 	// If nothing is selected(and selected item is not group chat), everything needs to be disabled
 	if (uuids.size() <= 0)
 	{
-		return getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP;
+		if(getCurSelectedViewModelItem())
+		{
+			return getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP;
+		}
+		return false;
 	}
 
 	if("can_activate_group" == item)
-- 
cgit v1.2.3


From df5378cf38b0e8325ae41be8af772e30cb815dd4 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 8 Jan 2013 19:59:27 +0200
Subject: CHUI-611 Fixed! Text in torn off message panel not wrapping correctly
 with size of conversation panel

---
 indra/newview/llfloaterimcontainer.cpp             |  2 +-
 .../skins/default/xui/en/floater_im_container.xml  | 30 ++++++----------------
 2 files changed, 9 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 82563b8736..38528f18f0 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -162,7 +162,7 @@ BOOL LLFloaterIMContainer::postBuild()
 	
 	setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
 	mStubPanel = getChild<LLPanel>("stub_panel");
-    mStubTextBox = getChild<LLTextBox>("stub_textbox_2");
+    mStubTextBox = getChild<LLTextBox>("stub_textbox");
     mStubTextBox->setURLClickedCallback(boost::bind(&LLFloaterIMContainer::returnFloaterToHost, this));
 
 	mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 951665552f..12c1676127 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -161,32 +161,18 @@
                  <text
                    type="string"
                    clip_partial="false"
-                   follows="left|top"
+                   follows="left|top|right"
                    layout="topleft"
-                   left="20"
-                   right="-20"
-                   name="stub_textbox_1"
-                   top="30"
-                   height="20"
-                   valign="center"
-                   wrap="true">
-                   This conversation is in a separate window.
-                 </text>
-                 <text
-                   type="string"
-                   clip_partial="false"
-                   follows="left|top"
-                   layout="topleft"
-                   left="20"
-                   right="-20"
-                   name="stub_textbox_2"
-                   top="60"
-                   height="20"
+                   left="15"
+                   right="-15"
+                   name="stub_textbox"
+                   top="25"
+                   height="40"
                    valign="center"
                    parse_urls="true"
                    wrap="true">
-                     [secondlife:/// Bring it back.]
-                </text>
+                   This conversation is in a separate window.   [secondlife:/// Bring it back.]
+                 </text>
              </panel>
             </panel_container>
         </layout_panel>
-- 
cgit v1.2.3


From 974720373d608a8cbcd3cd26c125b6487b5926a2 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 8 Jan 2013 12:21:47 -0800
Subject: CHUI-660: Problem: Upon auto-existing DND mode upon startup, the
 notification form elements (buttonts) were added to the form. But then
 deserialized form elements were also being added to the form causing
 duplicate buttons. As a solution, only add on the deserialized form elements
 that exceed the amount in the template.

---
 indra/llui/llnotifications.cpp       |  18 ++-
 indra/llui/llnotifications.h         |   1 +
 indra/newview/lltoastnotifypanel.cpp | 300 +++++++++++++++++------------------
 3 files changed, 168 insertions(+), 151 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 386345177d..ebdb4d5024 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -320,6 +320,11 @@ void LLNotificationForm::addElement(const std::string& type, const std::string&
 	mFormData.append(element);
 }
 
+void LLNotificationForm::addElement(const LLSD& element)
+{
+    mFormData.append(element);
+}
+
 void LLNotificationForm::append(const LLSD& sub_form)
 {
 	if (sub_form.isArray())
@@ -818,7 +823,18 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele
 	//mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
 
 	mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
-	mForm->append(form_elements);
+
+    //Prevents appending elements(buttons) that the template already had
+    if(form_elements.isArray()
+        && mForm->getNumElements() < form_elements.size())
+    {
+        LLSD::array_const_iterator it = form_elements.beginArray() + mForm->getNumElements();;
+
+        for(; it != form_elements.endArray(); ++it)
+        {
+            mForm->addElement(*it);
+        }
+    }
 
 	// apply substitution to form labels
 	mForm->formatElements(mSubstitutions);
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 092a9acd7c..96e0a86b7f 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -246,6 +246,7 @@ public:
 	bool getElementEnabled(const std::string& element_name) const;
 	void setElementEnabled(const std::string& element_name, bool enabled);
 	void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD(), bool enabled = true);
+    void addElement(const LLSD &element);
 	void formatElements(const LLSD& substitutions);
 	// appends form elements from another form serialized as LLSD
 	void append(const LLSD& sub_form);
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 844d7314d9..d494d12903 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -343,156 +343,156 @@ void LLToastNotifyPanel::onClickButton(void* data)
 
 void LLToastNotifyPanel::init( LLRect rect, bool show_images )
 {
-	deleteAllChildren();
-
-	mTextBox = NULL;
-	mInfoPanel = NULL;
-	mControlPanel = NULL;
-	mNumOptions = 0;
-	mNumButtons = 0;
-	mAddedDefaultBtn = false;
-
-	buildFromFile( "panel_notification.xml");
-	if(rect != LLRect::null)
-	{
-		this->setShape(rect);
-	}		 
-	mInfoPanel = getChild<LLPanel>("info_panel");
-	mInfoPanel->setFollowsAll();
-
-	mControlPanel = getChild<LLPanel>("control_panel");
-	BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
-	// customize panel's attributes
-	// is it intended for displaying a tip?
-	mIsTip = mNotification->getType() == "notifytip";
-	// is it a script dialog?
-	mIsScriptDialog = (mNotification->getName() == "ScriptDialog" || mNotification->getName() == "ScriptDialogGroup");
-	// is it a caution?
-	//
-	// caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
-	// notify xml template specifies that it is a caution
-	// tip-style notification handle 'caution' differently -they display the tip in a different color
-	mIsCaution = mNotification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
-
-	// setup parameters
-	// get a notification message
-	mMessage = mNotification->getMessage();
-	// init font variables
-	if (!sFont)
-{
-		sFont = LLFontGL::getFontSansSerif();
-		sFontSmall = LLFontGL::getFontSansSerifSmall();
-}
-	// initialize
-	setFocusRoot(!mIsTip);
-	// get a form for the notification
-	LLNotificationFormPtr form(mNotification->getForm());
-	// get number of elements
-	mNumOptions = form->getNumElements();
-
-	// customize panel's outfit
-	// preliminary adjust panel's layout
-	//move to the end 
-	//mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);
-
-	// adjust text options according to the notification type
-	// add a caution textbox at the top of a caution notification
-	if (mIsCaution && !mIsTip)
-	{
-		mTextBox = getChild<LLTextBox>("caution_text_box");
-	}
-	else
-	{
-		mTextBox = getChild<LLTextEditor>("text_editor_box"); 
-	}
-
-	mTextBox->setMaxTextLength(MAX_LENGTH);
-	mTextBox->setVisible(TRUE);
-	mTextBox->setPlainText(!show_images);
-	mTextBox->setValue(mNotification->getMessage());
-
-	// add buttons for a script notification
-	if (mIsTip)
-	{
-		adjustPanelForTipNotice();
-	}
-	else
-{
-		std::vector<index_button_pair_t> buttons;
-		buttons.reserve(mNumOptions);
-		S32 buttons_width = 0;
-		// create all buttons and accumulate they total width to reshape mControlPanel
-		for (S32 i = 0; i < mNumOptions; i++)
-	{
-			LLSD form_element = form->getElement(i);
-			if (form_element["type"].asString() != "button")
-		{
-				// not a button.
-				continue;
-		}
-			if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
-			{
-				// a textbox pretending to be a button.
-				continue;
-	}
-			LLButton* new_button = createButton(form_element, TRUE);
-			buttons_width += new_button->getRect().getWidth();
-			S32 index = form_element["index"].asInteger();
-			buttons.push_back(index_button_pair_t(index,new_button));
-}
-		if (buttons.empty())
-{
-			addDefaultButton();
-	}
-		else
-	{
-			const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
-			S32 button_panel_height = mControlPanel->getRect().getHeight();
-			//try get an average h_pad to spread out buttons
-			S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
-			if(h_pad < 2*HPAD)
-	{
-				/*
-				* Probably it is a scriptdialog toast
-				* for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
-				* In last case set default h_pad to avoid heaping of buttons 
-				*/
-				S32 button_per_row = button_panel_width / BUTTON_WIDTH;
-				h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1  because we do not need space after last button in a row   
-				if(h_pad < 2*HPAD) // still not enough space between buttons ?
-	{
-					h_pad = 2*HPAD;
-	}
-}
-			if (mIsScriptDialog)
-{
-				// we are using default width for script buttons so we can determinate button_rows
-				//to get a number of rows we divide the required width of the buttons to button_panel_width
-				S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
-				//S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
-				//reserve one row for the ignore_btn
-				button_rows++;
-				//calculate required panel height for scripdialog notification.
-				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
-			}
-			else
-	{
-				// in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
-				//S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
-				S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
-				//calculate required panel height 
-				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ BOTTOM_PAD;
-}
-
-			// we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
-			adjustPanelForScriptNotice(button_panel_width, button_panel_height);
-			updateButtonsLayout(buttons, h_pad);
-			// save buttons for later use in disableButtons()
-			//mButtons.assign(buttons.begin(), buttons.end());
-		}
-	}
-	// adjust panel's height to the text size
-	snapToMessageHeight(mTextBox, MAX_LENGTH);
+    deleteAllChildren();
+
+    mTextBox = NULL;
+    mInfoPanel = NULL;
+    mControlPanel = NULL;
+    mNumOptions = 0;
+    mNumButtons = 0;
+    mAddedDefaultBtn = false;
+
+    buildFromFile( "panel_notification.xml");
+    if(rect != LLRect::null)
+    {
+        this->setShape(rect);
+    }		 
+    mInfoPanel = getChild<LLPanel>("info_panel");
+    mInfoPanel->setFollowsAll();
+
+    mControlPanel = getChild<LLPanel>("control_panel");
+    BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
+    // customize panel's attributes
+    // is it intended for displaying a tip?
+    mIsTip = mNotification->getType() == "notifytip";
+    // is it a script dialog?
+    mIsScriptDialog = (mNotification->getName() == "ScriptDialog" || mNotification->getName() == "ScriptDialogGroup");
+    // is it a caution?
+    //
+    // caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
+    // notify xml template specifies that it is a caution
+    // tip-style notification handle 'caution' differently -they display the tip in a different color
+    mIsCaution = mNotification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
+
+    // setup parameters
+    // get a notification message
+    mMessage = mNotification->getMessage();
+    // init font variables
+    if (!sFont)
+    {
+        sFont = LLFontGL::getFontSansSerif();
+        sFontSmall = LLFontGL::getFontSansSerifSmall();
+    }
+    // initialize
+    setFocusRoot(!mIsTip);
+    // get a form for the notification
+    LLNotificationFormPtr form(mNotification->getForm());
+    // get number of elements
+    mNumOptions = form->getNumElements();
+
+    // customize panel's outfit
+    // preliminary adjust panel's layout
+    //move to the end 
+    //mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);
+
+    // adjust text options according to the notification type
+    // add a caution textbox at the top of a caution notification
+    if (mIsCaution && !mIsTip)
+    {
+        mTextBox = getChild<LLTextBox>("caution_text_box");
+    }
+    else
+    {
+        mTextBox = getChild<LLTextEditor>("text_editor_box"); 
+    }
+
+    mTextBox->setMaxTextLength(MAX_LENGTH);
+    mTextBox->setVisible(TRUE);
+    mTextBox->setPlainText(!show_images);
+    mTextBox->setValue(mNotification->getMessage());
+
+    // add buttons for a script notification
+    if (mIsTip)
+    {
+        adjustPanelForTipNotice();
+    }
+    else
+    {
+        std::vector<index_button_pair_t> buttons;
+        buttons.reserve(mNumOptions);
+        S32 buttons_width = 0;
+        // create all buttons and accumulate they total width to reshape mControlPanel
+        for (S32 i = 0; i < mNumOptions; i++)
+        {
+            LLSD form_element = form->getElement(i);
+            if (form_element["type"].asString() != "button")
+            {
+                // not a button.
+                continue;
+            }
+            if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
+            {
+                // a textbox pretending to be a button.
+                continue;
+            }
+            LLButton* new_button = createButton(form_element, TRUE);
+            buttons_width += new_button->getRect().getWidth();
+            S32 index = form_element["index"].asInteger();
+            buttons.push_back(index_button_pair_t(index,new_button));
+        }
+        if (buttons.empty())
+        {
+            addDefaultButton();
+        }
+        else
+        {
+            const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
+            S32 button_panel_height = mControlPanel->getRect().getHeight();
+            //try get an average h_pad to spread out buttons
+            S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
+            if(h_pad < 2*HPAD)
+            {
+                /*
+                * Probably it is a scriptdialog toast
+                * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
+                * In last case set default h_pad to avoid heaping of buttons 
+                */
+                S32 button_per_row = button_panel_width / BUTTON_WIDTH;
+                h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1  because we do not need space after last button in a row   
+                if(h_pad < 2*HPAD) // still not enough space between buttons ?
+                {
+                    h_pad = 2*HPAD;
+                }
+            }
+            if (mIsScriptDialog)
+            {
+                // we are using default width for script buttons so we can determinate button_rows
+                //to get a number of rows we divide the required width of the buttons to button_panel_width
+                S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
+                //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
+                //reserve one row for the ignore_btn
+                button_rows++;
+                //calculate required panel height for scripdialog notification.
+                button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
+            }
+            else
+            {
+                // in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
+                //S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
+                S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
+                //calculate required panel height 
+                button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ BOTTOM_PAD;
+            }
+
+            // we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
+            adjustPanelForScriptNotice(button_panel_width, button_panel_height);
+            updateButtonsLayout(buttons, h_pad);
+            // save buttons for later use in disableButtons()
+            //mButtons.assign(buttons.begin(), buttons.end());
+        }
+    }
+    // adjust panel's height to the text size
+    snapToMessageHeight(mTextBox, MAX_LENGTH);
 
 
 }
-- 
cgit v1.2.3


From 856969285e027def5acba6c252dc65a242349d4f Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Thu, 10 Jan 2013 14:56:33 +0200
Subject: CHUI-658 FIXED Don't highlight whole content of the folder after
 right clicking if it is flashing.

---
 indra/llui/llfolderviewitem.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 42e5a6debf..ad18adddd5 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -736,7 +736,7 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
                 getRect().getWidth() - 2,
                 0,
                 focusOutlineColor, FALSE);
-            if (showContent)
+            if (showContent && !isFlashing())
             {
                 gl_rect_2d(FOCUS_LEFT,
                     focus_bottom + 1,
-- 
cgit v1.2.3


From def252341a8c1675405404a6588749d06fa40791 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 8 Jan 2013 23:37:29 +0200
Subject: CHUI-612 FIXED Blank conversation names showing in conversation list

---
 indra/newview/llconversationmodel.cpp  | 129 +++++++++++++++++++++------------
 indra/newview/llconversationmodel.h    |  20 +++--
 indra/newview/llfloaterimcontainer.cpp |   9 ++-
 3 files changed, 102 insertions(+), 56 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 0243fb1c97..a8da4908ce 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -47,7 +47,8 @@ LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& u
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
 	mLastActiveTime(0.0),
-	mDisplayModeratorOptions(false)
+	mDisplayModeratorOptions(false),
+	mAvatarNameCacheConnection()
 {
 }
 
@@ -58,7 +59,8 @@ LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInte
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
 	mLastActiveTime(0.0),
-	mDisplayModeratorOptions(false)
+	mDisplayModeratorOptions(false),
+	mAvatarNameCacheConnection()
 {
 }
 
@@ -69,10 +71,21 @@ LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_mod
 	mNeedsRefresh(true),
 	mConvType(CONV_UNKNOWN),
 	mLastActiveTime(0.0),
-	mDisplayModeratorOptions(false)
+	mDisplayModeratorOptions(false),
+	mAvatarNameCacheConnection()
 {
 }
 
+LLConversationItem::~LLConversationItem()
+{
+	// Disconnect any previous avatar name cache connection to ensure
+	// that the callback method is not called after destruction
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+}
+
 void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
 {
 	LLUUID session_id = (session ? session->getUUID() : LLUUID());
@@ -142,6 +155,37 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
 	}
 }
 
+// method does subscription to changes in avatar name cache for current session/participant conversation item.
+void LLConversationItem::fetchAvatarName(bool isParticipant /*= true*/)
+{
+	LLUUID item_id = getUUID();
+
+	// item should not be null for participants
+	if (isParticipant)
+	{
+		llassert(item_id.notNull());
+	}
+
+	// disconnect any previous avatar name cache connection
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	// exclude nearby chat item
+	if (item_id.notNull())
+	{
+		// for P2P session item, override it as item of called agent
+		if (CONV_SESSION_1_ON_1 == getType())
+		{
+			item_id = LLIMModel::getInstance()->getOtherParticipantID(item_id);
+		}
+
+		// subscribe on avatar name cache changes for participant and session items
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(item_id, boost::bind(&LLConversationItem::onAvatarNameCache, this, _2));
+	}
+}
+
 //
 // LLConversationItemSession
 // 
@@ -169,11 +213,11 @@ void LLConversationItemSession::addParticipant(LLConversationItemParticipant* pa
 	addChild(participant);
 	mIsLoaded = true;
 	mNeedsRefresh = true;
-	updateParticipantName(participant);
+	updateName(participant);
 	postEvent("add_participant", this, participant);
 }
 
-void LLConversationItemSession::updateParticipantName(LLConversationItemParticipant* participant)
+void LLConversationItemSession::updateName(LLConversationItemParticipant* participant)
 {
 	EConversationType conversation_type = getType();
 	// We modify the session name only in the case of an ad-hoc session or P2P session, exit otherwise (nothing to do)
@@ -181,11 +225,13 @@ void LLConversationItemSession::updateParticipantName(LLConversationItemParticip
 	{
 		return;
 	}
+
 	// Avoid changing the default name if no participant present yet
 	if (mChildren.size() == 0)
 	{
 		return;
 	}
+
 	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
 	if (conversation_type == CONV_SESSION_AD_HOC)
 	{
@@ -210,12 +256,14 @@ void LLConversationItemSession::updateParticipantName(LLConversationItemParticip
 	}
 	else if (conversation_type == CONV_SESSION_1_ON_1)
 	{
-		// In the case of a P2P conversersation, we need to grab the name of the other participant in the session instance itself
+		// In the case of a P2P conversation, we need to grab the name of the other participant in the session instance itself
 		// as we do not create participants for such a session.
-        LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(mUUID);
-        LLUUID participantID = conversationFloater->getOtherParticipantUUID();
-        temp_uuids.push_back(participantID);
+		if (gAgentID != participant->getUUID())
+		{
+			temp_uuids.push_back(participant->getUUID());
+		}
 	}
+
 	if (temp_uuids.size() != 0)
 	{
 		std::string new_session_name;
@@ -229,7 +277,7 @@ void LLConversationItemSession::removeParticipant(LLConversationItemParticipant*
 {
 	removeChild(participant);
 	mNeedsRefresh = true;
-	updateParticipantName(participant);
+	updateName(participant);
 	postEvent("remove_participant", this, participant);
 }
 
@@ -393,6 +441,18 @@ void LLConversationItemSession::dumpDebugData(bool dump_children)
 	}
 }
 
+// should be invoked only for P2P sessions
+void LLConversationItemSession::onAvatarNameCache(const LLAvatarName& av_name)
+{
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	renameItem(av_name.getDisplayName());
+	postEvent("update_session", this, NULL);
+}
+
 //
 // LLConversationItemParticipant
 // 
@@ -401,8 +461,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 	LLConversationItem(display_name,uuid,root_view_model),
 	mIsMuted(false),
 	mIsModerator(false),
-	mDistToAgent(-1.0),
-	mAvatarNameCacheConnection()
+	mDistToAgent(-1.0)
 {
 	mDisplayName = display_name;
 	mConvType = CONV_PARTICIPANT;
@@ -412,38 +471,12 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 	LLConversationItem(uuid,root_view_model),
 	mIsMuted(false),
 	mIsModerator(false),
-	mDistToAgent(-1.0),
-	mAvatarNameCacheConnection()
+	mDistToAgent(-1.0)
 {
 	mConvType = CONV_PARTICIPANT;
 }
 
-LLConversationItemParticipant::~LLConversationItemParticipant()
-{
-	// Disconnect any previous avatar name cache connection to ensure
-	// that the callback method is not called after destruction
-	if (mAvatarNameCacheConnection.connected())
-	{
-		mAvatarNameCacheConnection.disconnect();
-	}
-}
-
-void LLConversationItemParticipant::fetchAvatarName()
-{
-	// Request the avatar name from the cache
-	llassert(getUUID().notNull());
-	if (getUUID().notNull())
-	{
-		// Disconnect any previous avatar name cache connection
-		if (mAvatarNameCacheConnection.connected())
-		{
-			mAvatarNameCacheConnection.disconnect();
-		}
-		mAvatarNameCacheConnection = LLAvatarNameCache::get(getUUID(), boost::bind(&LLConversationItemParticipant::onAvatarNameCache, this, _2));
-	}
-}
-
-void LLConversationItemParticipant::updateAvatarName()
+void LLConversationItemParticipant::updateName()
 {
 	llassert(getUUID().notNull());
 	if (getUUID().notNull())
@@ -451,29 +484,33 @@ void LLConversationItemParticipant::updateAvatarName()
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(getUUID(),&av_name))
 		{
-			updateAvatarName(av_name);
+			updateName(av_name);
 		}
 	}
 }
 
 void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
 {
-	mAvatarNameCacheConnection.disconnect();
-	updateAvatarName(av_name);
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	updateName(av_name);
 }
 
-void LLConversationItemParticipant::updateAvatarName(const LLAvatarName& av_name)
+void LLConversationItemParticipant::updateName(const LLAvatarName& av_name)
 {
 	mName = av_name.getUserName();
 	mDisplayName = av_name.getDisplayName();
-	mNeedsRefresh = true;
+	renameItem(mDisplayName);
 	if (mParent != NULL)
 	{
 		LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
 		if (parent_session != NULL)
 		{
 			parent_session->requestSort();
-			parent_session->updateParticipantName(this);
+			parent_session->updateName(this);
 			postEvent("update_participant", parent_session, this);
 		}
 	}
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 01b3850f5e..6aaea041e4 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -64,7 +64,7 @@ public:
 	LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItem(LLFolderViewModelInterface& root_view_model);
-	virtual ~LLConversationItem() {}
+	virtual ~LLConversationItem();
 
 	// Stub those things we won't really be using in this conversation context
 	virtual const std::string& getName() const { return mName; }
@@ -132,27 +132,31 @@ public:
 	
     void buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags);
 
+	void fetchAvatarName(bool isParticipant = true);		// fetch and update the avatar name
+
 protected:
+	virtual void onAvatarNameCache(const LLAvatarName& av_name) {}
+
 	std::string mName;	// Name of the session or the participant
 	LLUUID mUUID;		// UUID of the session or the participant
 	EConversationType mConvType;	// Type of conversation item
 	bool mNeedsRefresh;	// Flag signaling to the view that something changed for this item
 	F64  mLastActiveTime;
 	bool mDisplayModeratorOptions;
-};
+	boost::signals2::connection mAvatarNameCacheConnection;
+};	
 
 class LLConversationItemSession : public LLConversationItem
 {
 public:
 	LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
-	virtual ~LLConversationItemSession() {}
 	
 	/*virtual*/ bool hasChildren() const;
     LLPointer<LLUIImage> getIcon() const { return NULL; }
 	void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; }
 	void addParticipant(LLConversationItemParticipant* participant);
-	void updateParticipantName(LLConversationItemParticipant* participant);
+	void updateName(LLConversationItemParticipant* participant);
 	void removeParticipant(LLConversationItemParticipant* participant);
 	void removeParticipant(const LLUUID& participant_id);
 	void clearParticipants();
@@ -172,6 +176,8 @@ public:
 	void dumpDebugData(bool dump_children = false);
 
 private:
+	/*virtual*/ void onAvatarNameCache(const LLAvatarName& av_name);
+
 	bool mIsLoaded;		// true if at least one participant has been added to the session, false otherwise
 };
 
@@ -180,7 +186,6 @@ class LLConversationItemParticipant : public LLConversationItem
 public:
 	LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
 	LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
-	virtual ~LLConversationItemParticipant();
 	
 	virtual const std::string& getDisplayName() const { return mDisplayName; }
 
@@ -195,8 +200,7 @@ public:
 
 	virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
 
-	void fetchAvatarName();		// fetch and update the avatar name
-	void updateAvatarName();	// get from the cache (do *not* fetch) and update the avatar name
+	void updateName();	// get from the cache (do *not* fetch) and update the avatar name
 	LLConversationItemSession* getParentSession();
 
 	void dumpDebugData();
@@ -204,7 +208,7 @@ public:
 
 private:
 	void onAvatarNameCache(const LLAvatarName& av_name);	// callback used by fetchAvatarName
-	void updateAvatarName(const LLAvatarName& av_name);
+	void updateName(const LLAvatarName& av_name);
 
 	bool mIsMuted;		// default is false
 	bool mIsModerator;	// default is false
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 38528f18f0..a599fb51e1 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -380,7 +380,7 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
 		{
 			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
 			// Get the avatar name for this participant id from the cache and update the model
-			participant_model->updateAvatarName();
+			participant_model->updateName();
 			// Next participant
 			current_participant_model++;
 		}
@@ -1390,7 +1390,7 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 		return NULL;
 	}
 	item->renameItem(display_name);
-	item->updateParticipantName(NULL);
+	item->updateName(NULL);
 	
 	mConversationsItems[uuid] = item;
 
@@ -1419,6 +1419,11 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
 		}
 	}
 
+	if (uuid.notNull() && im_sessionp->isP2PSessionType())
+	{
+		item->fetchAvatarName(false);
+	}
+
 	// Do that too for the conversation dialog
     LLFloaterIMSessionTab *conversation_floater = (uuid.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(uuid)));
 	if (conversation_floater)
-- 
cgit v1.2.3


From b5172de28fd6bb8a833cf93180d2d43dd9d4a073 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 8 Jan 2013 17:06:49 -0800
Subject: CHUI-660: Post code review changes

---
 indra/llui/llnotifications.cpp                     | 51 +++++++++++++---------
 indra/llui/llnotifications.h                       |  4 +-
 .../newview/lldonotdisturbnotificationstorage.cpp  |  2 +-
 3 files changed, 34 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index ebdb4d5024..a5492b46f7 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -279,6 +279,18 @@ bool LLNotificationForm::hasElement(const std::string& element_name) const
 	return false;
 }
 
+void LLNotificationForm::getElements(LLSD& elements, S32 offset)
+{
+    //Finds elements that the template did not add
+    LLSD::array_const_iterator it = mFormData.beginArray() + offset;
+
+    //Keeps track of only the dynamic elements
+    for(; it != mFormData.endArray(); ++it)
+    {
+        elements.append(*it);
+    }
+}
+
 bool LLNotificationForm::getElementEnabled(const std::string& element_name) const
 {
 	for (LLSD::array_const_iterator it = mFormData.beginArray();
@@ -320,11 +332,6 @@ void LLNotificationForm::addElement(const std::string& type, const std::string&
 	mFormData.append(element);
 }
 
-void LLNotificationForm::addElement(const LLSD& element)
-{
-    mFormData.append(element);
-}
-
 void LLNotificationForm::append(const LLSD& sub_form)
 {
 	if (sub_form.isArray())
@@ -508,21 +515,36 @@ LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) :
 }
 
 
-LLSD LLNotification::asLLSD()
+LLSD LLNotification::asLLSD(bool excludeTemplateElements)
 {
 	LLParamSDParser parser;
 
 	Params p;
 	p.id = mId;
 	p.name = mTemplatep->mName;
-	p.form_elements = getForm()->asLLSD();
-	
 	p.substitutions = mSubstitutions;
 	p.payload = mPayload;
 	p.time_stamp = mTimestamp;
 	p.expiry = mExpiresAt;
 	p.priority = mPriority;
 
+    LLNotificationFormPtr templateForm = mTemplatep->mForm;
+    LLSD formElements = mForm->asLLSD();
+
+    //All form elements (dynamic or not)
+    if(!excludeTemplateElements)
+    {
+        p.form_elements = formElements;
+    }
+    //Only dynamic form elements (exclude template elements)
+    else if(templateForm->getNumElements() < formElements.size())
+    {
+        LLSD dynamicElements;
+        //Offset to dynamic elements and store them
+        mForm->getElements(dynamicElements, templateForm->getNumElements());
+        p.form_elements = dynamicElements;
+    }
+    
     if(mResponder)
     {
         p.functor.responder_sd = mResponder->asLLSD();
@@ -823,18 +845,7 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele
 	//mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
 
 	mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
-
-    //Prevents appending elements(buttons) that the template already had
-    if(form_elements.isArray()
-        && mForm->getNumElements() < form_elements.size())
-    {
-        LLSD::array_const_iterator it = form_elements.beginArray() + mForm->getNumElements();;
-
-        for(; it != form_elements.endArray(); ++it)
-        {
-            mForm->addElement(*it);
-        }
-    }
+    mForm->append(form_elements);
 
 	// apply substitution to form labels
 	mForm->formatElements(mSubstitutions);
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 96e0a86b7f..236c2a42d1 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -242,11 +242,11 @@ public:
 	S32 getNumElements() { return mFormData.size(); }
 	LLSD getElement(S32 index) { return mFormData.get(index); }
 	LLSD getElement(const std::string& element_name);
+    void getElements(LLSD& elements, S32 offset = 0);
 	bool hasElement(const std::string& element_name) const;
 	bool getElementEnabled(const std::string& element_name) const;
 	void setElementEnabled(const std::string& element_name, bool enabled);
 	void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD(), bool enabled = true);
-    void addElement(const LLSD &element);
 	void formatElements(const LLSD& substitutions);
 	// appends form elements from another form serialized as LLSD
 	void append(const LLSD& sub_form);
@@ -457,7 +457,7 @@ public:
 	// ["time"] = time at which notification was generated;
 	// ["expiry"] = time at which notification expires;
 	// ["responseFunctor"] = name of registered functor that handles responses to notification;
-	LLSD asLLSD();
+	LLSD asLLSD(bool excludeTemplateElements = false);
 
 	const LLNotificationFormPtr getForm();
 	void updateForm(const LLNotificationFormPtr& form);
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 9bb2f27a46..ac41a3804f 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -77,7 +77,7 @@ void LLDoNotDisturbNotificationStorage::saveNotifications()
 
 		if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && !notificationPtr->isExpired())
 		{
-			data.append(notificationPtr->asLLSD());
+			data.append(notificationPtr->asLLSD(true));
 		}
 	}
 
-- 
cgit v1.2.3


From 4ef1181cdcb03a08fbce8d774cd85ef914bef8f3 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 8 Jan 2013 21:46:00 -0800
Subject: CHUI-659 : Fixed : Reimplemented open selection on hitting return the
 right way

---
 indra/llui/llfolderview.cpp        | 86 --------------------------------------
 indra/llui/llfolderview.h          |  4 --
 indra/llui/llfolderviewmodel.h     |  2 +-
 indra/newview/llinventorypanel.cpp | 20 ++++++++-
 indra/newview/llinventorypanel.h   |  1 +
 5 files changed, 20 insertions(+), 93 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 7ae79d94fe..324142f6c3 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -275,17 +275,6 @@ BOOL LLFolderView::canFocusChildren() const
 void LLFolderView::addFolder( LLFolderViewFolder* folder)
 {
 	LLFolderViewFolder::addFolder(folder);
-		
-	// TODO RN: enforce sort order of My Inventory followed by Library
-	//mFolders.remove(folder);
-	//if (((LLFolderViewModelItemInventory*)folder->getViewModelItem())->getUUID() == gInventory.getLibraryRootFolderID())
-	//{
-	//	mFolders.push_back(folder);
-	//}
-	//else
-	//{
-	//	mFolders.insert(mFolders.begin(), folder);
-	//}
 }
 
 void LLFolderView::closeAllFolders()
@@ -793,76 +782,6 @@ void LLFolderView::removeSelectedItems()
 	}
 }
 
-// TODO RN: abstract 
-// open the selected item.
-void LLFolderView::openSelectedItems( void )
-{
-	//TODO RN: get working again
-	//if(getVisible() && getEnabled())
-	//{
-	//	if (mSelectedItems.size() == 1)
-	//	{
-	//		mSelectedItems.front()->openItem();
-	//	}
-	//	else
-	//	{
-	//		LLMultiPreview* multi_previewp = new LLMultiPreview();
-	//		LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-	//		selected_items_t::iterator item_it;
-	//		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-	//		{
-	//			// IT_{OBJECT,ATTACHMENT} creates LLProperties
-	//			// floaters; others create LLPreviews.  Put
-	//			// each one in the right type of container.
-	//			LLFolderViewModelItemInventory* listener = static_cast<LLFolderViewModelItemInventory*>((*item_it)->getViewModelItem());
-	//			bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
-	//			if (is_prop)
-	//				LLFloater::setFloaterHost(multi_propertiesp);
-	//			else
-	//				LLFloater::setFloaterHost(multi_previewp);
-	//			listener->openItem();
-	//		}
-
-	//		LLFloater::setFloaterHost(NULL);
-	//		// *NOTE: LLMulti* will safely auto-delete when open'd
-	//		// without any children.
-	//		multi_previewp->openFloater(LLSD());
-	//		multi_propertiesp->openFloater(LLSD());
-	//	}
-	//}
-	}
-
-void LLFolderView::propertiesSelectedItems( void )
-{
-	//TODO RN: get working again
-	//if(getVisible() && getEnabled())
-	//{
-	//	if (mSelectedItems.size() == 1)
-	//	{
-	//		LLFolderViewItem* folder_item = mSelectedItems.front();
-	//		if(!folder_item) return;
-	//		folder_item->getViewModelItem()->showProperties();
-	//	}
-	//	else
-	//	{
-	//		LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-	//		LLFloater::setFloaterHost(multi_propertiesp);
-
-	//		selected_items_t::iterator item_it;
-	//		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-	//		{
-	//			(*item_it)->getViewModelItem()->showProperties();
-	//		}
-
-	//		LLFloater::setFloaterHost(NULL);
-	//		multi_propertiesp->openFloater(LLSD());
-	//	}
-	//}
-	}
-
-
 void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
 {
 	if ((mAutoOpenItems.check() == item) || 
@@ -1151,11 +1070,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 				mSearchString.clear();
 				handled = TRUE;
 			}
-			else
-			{
-				LLFolderView::openSelectedItems();
-				handled = TRUE;
-			}
 		}
 		break;
 
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 2ee7417240..a6e0a3b4c0 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -163,10 +163,6 @@ public:
 	// Deletion functionality
  	void removeSelectedItems();
 
-	// Open the selected item
-	void openSelectedItems( void );
-	void propertiesSelectedItems( void );
-
 	void autoOpenItem(LLFolderViewFolder* item);
 	void closeAutoOpenedFolders();
 	BOOL autoOpenTest(LLFolderViewFolder* item);
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 5837052565..1b61212c0e 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -127,7 +127,7 @@ public:
 	virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
 };
 
-// This is am abstract base class that users of the folderview classes
+// This is an abstract base class that users of the folderview classes
 // would use to bridge the folder view with the underlying data
 class LLFolderViewModelItem : public LLRefCount
 {
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 81e7f166e1..25dc365467 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -684,8 +684,9 @@ void LLInventoryPanel::initializeViews()
 	}
 	else
 	{
-		buildNewViews(gInventory.getRootFolderID());
-		buildNewViews(gInventory.getLibraryRootFolderID());
+		// Default case: always add "My Inventory" first, "Library" second
+		buildNewViews(gInventory.getRootFolderID());		// My Inventory
+		buildNewViews(gInventory.getLibraryRootFolderID());	// Library
 	}
 
 	gIdleCallbacks.addFunction(idle, this);
@@ -1354,6 +1355,21 @@ void LLInventoryPanel::doToSelected(const LLSD& userdata)
 	return;
 }
 
+BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
+{
+	BOOL handled = FALSE;
+	switch (key)
+	{
+	case KEY_RETURN:
+		// Open selected items if enter key hit on the inventory panel
+		if (mask == MASK_NONE)
+		{
+			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open");
+			handled = TRUE;
+		}
+	}
+	return handled;
+}
 
 /************************************************************************/
 /* Recent Inventory Panel related class                                 */
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 9639086c11..6eb85fbad2 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -143,6 +143,7 @@ public:
 
 	// LLView methods
 	void draw();
+	/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
 	BOOL handleHover(S32 x, S32 y, MASK mask);
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 								   EDragAndDropType cargo_type,
-- 
cgit v1.2.3


From 3cf2d8e9eac215024bc216958b0920e61aa25de1 Mon Sep 17 00:00:00 2001
From: maximbproductengine <maximbproductengine@lindenlab.com>
Date: Wed, 9 Jan 2013 10:41:09 +0200
Subject: CHUI-665 (Change "Open conversation log" to "Conversation log..." in
 communication floater view/sort menu)

---
 indra/newview/skins/default/xui/en/menu_participant_view.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index 33d7bd7c01..2f2bafb95d 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -76,7 +76,7 @@
          parameter="privacy_preferences" />
     </menu_item_call>
     <menu_item_check
-         label="Open conversation log"
+         label="Conversation log..."
          name="Conversation"
          visible="true">
         <menu_item_check.on_check
-- 
cgit v1.2.3


From bb05a29374b2c9691937ccb15cdbff466fd775f1 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 9 Jan 2013 15:08:58 +0200
Subject: CHUI-638 FIXED Don't force button and widget to flash if the object
 is muted.

---
 indra/newview/llimview.cpp | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 0011f54175..0326235d37 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -225,12 +225,17 @@ void on_new_message(const LLSD& msg)
         //User is not focused on conversation containing the message
         if(session_floater_not_focused)
         {
-            im_box->flashConversationItemWidget(session_id, true);
-
+        	if(!LLMuteList::getInstance()->isMuted(participant_id))
+        	{
+        		im_box->flashConversationItemWidget(session_id, true);
+        	}
             //The conversation floater isn't focused/open
             if(conversation_floater_not_focused)
             {
-                gToolBarView->flashCommand(LLCommandId("chat"), true);
+            	if(!LLMuteList::getInstance()->isMuted(participant_id))
+            	{
+            		gToolBarView->flashCommand(LLCommandId("chat"), true);
+            	}
 
                 //Show IM toasts (upper right toasts)
                 // Skip toasting for system messages and for nearby chat
-- 
cgit v1.2.3


From 9d70bc259a02a0f6dcc6cff1c95a34353e0f1e59 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 9 Jan 2013 12:45:34 -0800
Subject: CHUI-652 : Fixed : Skip the bogus fetching test when adding objects
 to object content.

---
 indra/newview/llviewerobject.cpp | 17 -----------------
 1 file changed, 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 2fe6cd578b..52f73d6c43 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2869,23 +2869,6 @@ void LLViewerObject::updateInventory(
 	U8 key,
 	bool is_new)
 {
-	LLMemType mt(LLMemType::MTYPE_OBJECT);
-
-	std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin();
-	std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end();
-
-	bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end;
-	bool is_fetched = getInventoryItemByAsset(item->getAssetUUID()) != NULL;
-
-	if (is_fetched || is_fetching)
-	{
-		return;
-	}
-	else
-	{
-		mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
-	}
-
 	// This slices the object into what we're concerned about on the
 	// viewer. The simulator will take the permissions and transfer
 	// ownership.
-- 
cgit v1.2.3


From 6a30c4c3c54f3d70d1a10fb76e7c81cd5e36a524 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 9 Jan 2013 13:30:14 -0800
Subject: CHUI-669: Upon DND mode exit, no longer flash IM messages that were
 stored during DND mode.

---
 indra/newview/llimview.cpp | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 0326235d37..a3c338831c 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -129,11 +129,7 @@ void process_dnd_im(const LLSD& notification)
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
     }
 
-    //For now always flash conversation line item
-    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-    im_box->flashConversationItemWidget(sessionID, true);
-
-    //And flash toolbar button
+    //Flash toolbar button for now, eventually the user's preference will be taken into account
     gToolBarView->flashCommand(LLCommandId("chat"), true);
 }
 
-- 
cgit v1.2.3


From 41d5f820ea1859493b7f14d9d81b145a6a3b38b6 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 9 Jan 2013 14:30:10 -0800
Subject: CHUI-670: Prevent flashing of 'Chat' FUI button while in DND mode and
 receive IM.

---
 indra/newview/llimview.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a3c338831c..067f0d1993 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -228,7 +228,8 @@ void on_new_message(const LLSD& msg)
             //The conversation floater isn't focused/open
             if(conversation_floater_not_focused)
             {
-            	if(!LLMuteList::getInstance()->isMuted(participant_id))
+            	if(!LLMuteList::getInstance()->isMuted(participant_id) 
+                    && !gAgent.isDoNotDisturb())
             	{
             		gToolBarView->flashCommand(LLCommandId("chat"), true);
             	}
-- 
cgit v1.2.3


From 60eaa8875df45f023c3bf0fb82863b05cb5a090f Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 9 Jan 2013 19:10:41 -0800
Subject: CHUI-652 : Fixed : Maintain multi selection consistent when click and
 drag an already selected item (drag multi select was broken)

---
 indra/llui/llfolderviewitem.cpp | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index b7165f68b7..42e5a6debf 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -506,13 +506,10 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
 		}
 		make_ui_sound("UISndClick");
 	}
-    //Just re-select the item since it is clicked without ctrl or shift
-    else if(!(mask & (MASK_CONTROL | MASK_SHIFT)))
-    {
-        getRoot()->setSelection(this, FALSE);
-    }
 	else
 	{
+		// If selected, we reserve the decision of deselecting/reselecting to the mouse up moment.
+		// This is necessary so we maintain selection consistent when starting a drag.
 		mSelectPending = TRUE;
 	}
 
-- 
cgit v1.2.3


From be3cfd872be89f30012d66a4b64071e4fe2568cf Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 9 Jan 2013 20:20:32 -0800
Subject: CHUI-649 : WIP : Cleanup code to make it readable

---
 indra/llui/llfolderviewitem.cpp     | 8 ++++----
 indra/newview/llinventorybridge.cpp | 6 ++++--
 2 files changed, 8 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 42e5a6debf..6d3b883b09 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -409,7 +409,7 @@ void LLFolderViewItem::selectItem(void)
 BOOL LLFolderViewItem::isMovable()
 {
 	return getViewModelItem()->isItemMovable();
-	}
+}
 
 BOOL LLFolderViewItem::isRemovable()
 {
@@ -438,19 +438,19 @@ BOOL LLFolderViewItem::remove()
 		return FALSE;
 	}
 	return getViewModelItem()->removeItem();
-	}
+}
 
 // Build an appropriate context menu for the item.
 void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
 	getViewModelItem()->buildContextMenu(menu, flags);
-	}
+}
 
 void LLFolderViewItem::openItem( void )
 {
 	if (mAllowOpen)
 	{
-	getViewModelItem()->openItem();
+		getViewModelItem()->openItem();
 	}
 }
 
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index cb6290368c..837870ae27 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -511,8 +511,10 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
 		// Each item must be copyable to be pastable
 		LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id);
 		if (!item_br.isItemCopyable())
-				return FALSE;
-			}
+		{
+			return FALSE;
+		}
+	}
 	return TRUE;
 }
 
-- 
cgit v1.2.3


From bad4eda43677d26b88c86f4381c6a0f7436f0daf Mon Sep 17 00:00:00 2001
From: maximbproductengine <maximbproductengine@lindenlab.com>
Date: Thu, 10 Jan 2013 13:41:47 +0200
Subject: CHUI-663 (Right click menus on participants inactive in conversation
 floater for torn off conversation)

---
 indra/newview/llfloaterimcontainer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 82563b8736..a21cbf2bb2 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -906,7 +906,7 @@ const LLConversationItem * LLFloaterIMContainer::getCurSelectedViewModelItem()
         mConversationsRoot->getCurSelectedItem()->getViewModelItem())
     {
 		LLFloaterIMSessionTab *selected_session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
-		if (selected_session_floater && !selected_session_floater->getHost())
+		if (selected_session_floater && !selected_session_floater->getHost() && selected_session_floater->getCurSelectedViewModelItem())
 		{
 			conversation_item = selected_session_floater->getCurSelectedViewModelItem();
 		}
-- 
cgit v1.2.3


From b5b44ddf175e46379aa20b79b0abedab6bc05e2e Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 10 Jan 2013 11:10:41 -0800
Subject: CHUI-649 : Fixed : Added the contextual menu to in build content tab

---
 indra/newview/llinventorypanel.cpp       | 4 ++--
 indra/newview/llpanelobjectinventory.cpp | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 25dc365467..c4918f0a31 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -181,7 +181,7 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
 																	LLAssetType::AT_CATEGORY,
 																	LLInventoryType::IT_CATEGORY,
 																	this,
-        &mInventoryViewModel,
+																	&mInventoryViewModel,
 																	NULL,
 																	root_id);
     p.view_model = &mInventoryViewModel;
@@ -218,7 +218,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 		mFolderRoot = createFolderRoot(root_id);
 	
 		addItemID(root_id, mFolderRoot);
-}
+	}
 	mCommitCallbackRegistrar.popScope();
 	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 	
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 527aefe821..7555ac7b2c 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1569,6 +1569,8 @@ void LLPanelObjectInventory::reset()
 	p.folder_indentation = -14; // subtract space normally reserved for folder expanders
 	p.view_model = &mInventoryViewModel;
 	p.root = NULL;
+    p.options_menu = "menu_inventory.xml";
+
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
 
 	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
-- 
cgit v1.2.3


From 2e3113863022a21d2145cc23992d6afab9c6fbcd Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 10 Jan 2013 20:19:26 -0800
Subject: CHUI-672 : Fixed : LLMultiFloater members need to be initialized in
 constructor.

---
 indra/llui/llmultifloater.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index 59faabd482..179b251cdb 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -37,10 +37,12 @@
 //
 
 LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
-	: LLFloater(key)
-	, mTabContainer(NULL)
-	, mTabPos(LLTabContainer::TOP)
-	, mAutoResize(TRUE)
+	: LLFloater(key),
+	  mTabContainer(NULL),
+	  mTabPos(LLTabContainer::TOP),
+	  mAutoResize(TRUE),
+	  mOrigMinWidth(params.min_width),
+	  mOrigMinHeight(params.min_height)
 {
 }
 
-- 
cgit v1.2.3


From 16082462a4d355509338ed28e396c8c81a20712a Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 11 Jan 2013 15:32:05 +0200
Subject: CHUI-650 FIXED Set focus to floater when bringToFront() is
 called(even if it's already in front).

---
 indra/llui/llfloater.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 8f9be5285d..e0e830f742 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2394,6 +2394,7 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 {
 	if (mFrontChild == child)
 	{
+		child->setFocus(true);
 		return;
 	}
 
-- 
cgit v1.2.3


From 88639dd862be6558f0777e99c571dcd807efa4ba Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 11 Jan 2013 17:28:43 -0800
Subject: CHUI-650 : Revert : revert the change as it creates infinite
 recursive calls

---
 indra/llui/llfloater.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index e0e830f742..8f9be5285d 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2394,7 +2394,6 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 {
 	if (mFrontChild == child)
 	{
-		child->setFocus(true);
 		return;
 	}
 
-- 
cgit v1.2.3


From 23ffb7db1bb065b5afbdcb94eab57720d604ae8d Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Sat, 12 Jan 2013 01:51:43 +0200
Subject: CHUI-618 ADD FIX User sees no indication of offline messages received
 with conversation log preference turned off: changed in accordance with a new
 requirements (open conv. floater instead flashing)

---
 indra/newview/llimview.cpp | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 067f0d1993..da811535e5 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -129,8 +129,14 @@ void process_dnd_im(const LLSD& notification)
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
     }
 
-    //Flash toolbar button for now, eventually the user's preference will be taken into account
-    gToolBarView->flashCommand(LLCommandId("chat"), true);
+    // open conversation floater
+	LLFloaterIMContainer* container_floater =
+			LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+	if (container_floater && !(container_floater->isFrontmost()))
+	{
+		container_floater->openFloater();
+		container_floater->setFrontmost(TRUE);
+	}
 }
 
 
@@ -2529,25 +2535,6 @@ void LLIMMgr::addMessage(
 		new_session_id = computeSessionID(dialog, other_participant_id);
 	}
 
-	// Open conversation log if offline messages are present and user allows a Call Log
-	if (is_offline_msg)
-    {
-		if (gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
-		{
-			LLFloaterConversationLog* floater_log =
-					LLFloaterReg::getTypedInstance<LLFloaterConversationLog>("conversation");
-			if (floater_log && !(floater_log->isFrontmost()))
-			{
-				floater_log->openFloater();
-				floater_log->setFrontmost(TRUE);
-			}
-		}
-		else
-		{
-           gToolBarView->flashCommand(LLCommandId("chat"), true);
-		}
-    }
-
 	//*NOTE session_name is empty in case of incoming P2P sessions
 	std::string fixed_session_name = from;
 	bool name_is_setted = false;
@@ -2614,6 +2601,19 @@ void LLIMMgr::addMessage(
 	{
 		LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
 	}
+
+	// Open conversation floater if offline messages are present
+	if (is_offline_msg)
+    {
+		LLFloaterIMContainer* container_floater =
+				LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+		if (container_floater && !(container_floater->isFrontmost()))
+		{
+			container_floater->openFloater();
+			container_floater->setFrontmost(TRUE);
+		}
+    }
+
 }
 
 void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
-- 
cgit v1.2.3


From 69497e645bbefe85d83e85bb353e5fb719263877 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 11 Jan 2013 18:20:29 -0800
Subject: CHUI-668: Not fully complete but as of this commit, have
 functionality to use the user's most intrusive chat notification upon exiting
 from DND mode with IM's. Also if in DND mode, clicking on a conversation line
 item or floater, will flush the DND notifications system of storing that
 conversation. This way upon existing DND mode already responded conversations
 won't be notified to the user.

---
 indra/newview/llcommunicationchannel.cpp           |  8 +++-
 indra/newview/llcommunicationchannel.h             |  1 +
 .../newview/lldonotdisturbnotificationstorage.cpp  | 53 ++++++++++++++++++++++
 indra/newview/lldonotdisturbnotificationstorage.h  |  1 +
 indra/newview/llfloaterimcontainer.cpp             | 10 ++++
 indra/newview/llfloaterpreference.cpp              | 30 ++++++++++++
 indra/newview/llfloaterpreference.h                |  1 +
 indra/newview/llimview.cpp                         | 42 +++++++++++++++--
 8 files changed, 142 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
index 4b0a70ffd8..a99047c163 100644
--- a/indra/newview/llcommunicationchannel.cpp
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -67,12 +67,18 @@ void LLCommunicationChannel::clearHistory()
 	mHistory.clear();
 }
 
+void LLCommunicationChannel::removeItem(history_list_t::const_iterator itemToRemove)
+{
+    mHistory.erase(itemToRemove);
+}
+
 void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
 {
 	std::string notificationType = pNotificationPtr->getType();
 	if ((notificationType == "groupnotify")
 		|| (notificationType == "offer")
-		|| (notificationType == "notifytoast"))
+		|| (notificationType == "notifytoast")
+        && !pNotificationPtr->isCancelled())
 	{
 		mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr));
 	}
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
index 0e15e1cd15..c07933118d 100644
--- a/indra/newview/llcommunicationchannel.h
+++ b/indra/newview/llcommunicationchannel.h
@@ -48,6 +48,7 @@ public:
 	history_list_t::const_iterator endHistory() const;
 	
 	void clearHistory();
+    void removeItem(history_list_t::const_iterator itemToRemove);
 
 protected:
 	virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index ac41a3804f..764da25b08 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -41,6 +41,8 @@
 #include "llsingleton.h"
 #include "lluuid.h"
 
+extern void useMostItrusiveIMNotification();
+
 LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
 	: LLSingleton<LLDoNotDisturbNotificationStorage>()
 	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
@@ -103,15 +105,22 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 	}
 	
 	LLNotifications& instance = LLNotifications::instance();
+    bool imToastExists = false;
 	
 	for (LLSD::array_const_iterator notification_it = data.beginArray();
 		 notification_it != data.endArray();
 		 ++notification_it)
 	{
 		LLSD notification_params = *notification_it;
+        const std::string notificationName = notification_params["name"].asString();
         const LLUUID& notificationID = notification_params["id"];
         LLNotificationPtr notification = instance.find(notificationID);
 		
+        if(notificationName == "IMToast")
+        {
+            imToastExists = true;
+        }
+
         //Notification already exists in notification pipeline (same instance of app running)
 		if (notification)
 		{
@@ -138,6 +147,11 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 		}
 	}
 
+    if(imToastExists)
+    {
+        useMostItrusiveIMNotification();
+    }
+
 	// Clear the communication channel history and rewrite the save file to empty it as well
 	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
 	LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
@@ -154,6 +168,45 @@ LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChan
 	return channelPtr;
 }
 
+void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& session_id)
+{
+    LLNotifications& instance = LLNotifications::instance();
+    LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+    LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+    LLNotificationPtr notification;
+    LLSD substitutions;
+    LLUUID notificationSessionID;
+    LLCommunicationChannel::history_list_t::const_iterator it;
+    std::vector<LLCommunicationChannel::history_list_t::const_iterator> itemsToRemove;
+
+    //Find notification with the matching session id
+    for (it = commChannel->beginHistory();
+        it != commChannel->endHistory(); 
+        ++it)
+    {
+        notification = it->second;
+        substitutions = notification->getSubstitutions();
+        notificationSessionID = substitutions["SESSION_ID"].asUUID();
+
+        if(session_id == notificationSessionID)
+        {
+            itemsToRemove.push_back(it);
+        }
+    }
+
+    //Remove the notification
+    while(itemsToRemove.size())
+    {
+        it = itemsToRemove.back();
+        notification = it->second;
+        commChannel->removeItem(it);
+        //instance.cancel triggers onChannelChanged to be called within LLNotificationChannelBase::updateItem (which save changes to the .xml file)
+        //but this means that saveNotifications write a file each time as well, BAD! Will find a way to prevent this.
+        instance.cancel(notification);
+        itemsToRemove.pop_back();
+    }
+}
+
 
 bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
 {
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index 60bcd89ec3..8edb8569b4 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -45,6 +45,7 @@ public:
 
 	void saveNotifications();
 	void loadNotifications();
+    void removeIMNotification(const LLUUID& session_id);
 
 protected:
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index a17b89af0d..376144951d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -39,6 +39,7 @@
 #include "llavatariconctrl.h"
 #include "llavatarnamecache.h"
 #include "llcallbacklist.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llgroupactions.h"
 #include "llgroupiconctrl.h"
 #include "llflashtimer.h"
@@ -1291,6 +1292,10 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     	if (widget && widget->getParentFolder())
     	{
     		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
+            if(gAgent.isDoNotDisturb())
+            {
+                LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
+            }
     	}
     }
 
@@ -1312,6 +1317,11 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 				// Switch to the conversation floater that is being selected
 				selectFloater(session_floater);
 			}
+
+            if(gAgent.isDoNotDisturb())
+            {
+                LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
+            }
 		}
 
 		// Set the focus on the selected floater
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3d4a1c44d8..9c836489f3 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1624,6 +1624,36 @@ void LLFloaterPreference::selectChatPanel()
 	selectPanel("chat");
 }
 
+S32 LLFloaterPreference::getHighestNotificationIndex() //change this name
+{
+    static const S32 comboBoxNamesLength = 5;
+    static std::string comboBoxNames[comboBoxNamesLength] = {"NearbyChatOptions",
+                                            "FriendIMOptions",
+                                            "NonFriendIMOptions",
+                                            "ConferenceIMOptions",
+                                            "GroupChatOptions"};
+    S32 selectedIndex;
+    S32 priorityindex = 3;
+    LLComboBox * comboBox;
+
+    for(S32 i = 0; i < comboBoxNamesLength; ++i)
+    {
+        comboBox = getChild<LLComboBox>(comboBoxNames[i]);
+
+        if(comboBox)
+        {
+            selectedIndex = comboBox->getCurrentIndex();
+
+            if(selectedIndex < priorityindex)
+            {
+                priorityindex = selectedIndex;
+            }
+        }
+    }
+
+    return priorityindex;
+}
+
 //------------------------------Updater---------------------------------------
 
 static bool handleBandwidthChanged(const LLSD& newvalue)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 37a531e99e..3d5d49294e 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -86,6 +86,7 @@ public:
 	void saveAvatarProperties( void );
 	void selectPrivacyPanel();
 	void selectChatPanel();
+    S32 getHighestNotificationIndex();
 
 protected:	
 	void		onBtnOK();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 067f0d1993..e513d2e6d1 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -52,6 +52,7 @@
 #include "llchat.h"
 #include "llfloaterimsession.h"
 #include "llfloaterimcontainer.h"
+#include "llfloaterpreference.h"
 #include "llgroupiconctrl.h"
 #include "llmd5.h"
 #include "llmutelist.h"
@@ -128,11 +129,46 @@ void process_dnd_im(const LLSD& notification)
             false, 
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
     }
-
-    //Flash toolbar button for now, eventually the user's preference will be taken into account
-    gToolBarView->flashCommand(LLCommandId("chat"), true);
 }
 
+void useMostItrusiveIMNotification()
+{
+    LLFloaterPreference * instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {    
+        LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+
+        //conv. floater is closed
+        bool conversation_floater_is_closed =
+            !(  im_box
+            && im_box->isInVisibleChain()
+            && !im_box->isMinimized());
+
+        //conversation floater not focused (visible or not)
+        bool conversation_floater_not_focused =
+            conversation_floater_is_closed || !im_box->hasFocus();
+
+        switch(instance->getHighestNotificationIndex())
+        {
+            //Highest priority to lowest (cases correspond to options in drop down box inside Preferences->Chat)
+
+            //open conversation floater
+            case 0:
+                    LLFloaterReg::showInstance("im_container");
+                break;
+            //pop up message
+            case 1:
+            //flash toolbar button
+            case 2:
+                if(conversation_floater_not_focused)
+                {
+                    gToolBarView->flashCommand(LLCommandId("chat"), true);
+                }
+                break;
+        }
+    }
+
+}
 
 static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 									   const LLAvatarName& av_name,
-- 
cgit v1.2.3


From e42755dd16195244a6743fc3970f24fec08f03b9 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 11 Jan 2013 19:43:12 -0800
Subject: CHUI-668: Now when exiting DND mode, the user's most intrusive
 notification will be used to notify that user (if received IM's during DND
 mode). Nearby chat messages/settings are ignored.

---
 indra/newview/llfloaterpreference.cpp | 11 +++----
 indra/newview/llimview.cpp            | 59 ++++++++++++++++++++++-------------
 2 files changed, 43 insertions(+), 27 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 9c836489f3..4c74d3a8ef 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1626,12 +1626,11 @@ void LLFloaterPreference::selectChatPanel()
 
 S32 LLFloaterPreference::getHighestNotificationIndex() //change this name
 {
-    static const S32 comboBoxNamesLength = 5;
-    static std::string comboBoxNames[comboBoxNamesLength] = {"NearbyChatOptions",
-                                            "FriendIMOptions",
-                                            "NonFriendIMOptions",
-                                            "ConferenceIMOptions",
-                                            "GroupChatOptions"};
+    static const S32 comboBoxNamesLength = 4;
+    static std::string comboBoxNames[comboBoxNamesLength] = {"FriendIMOptions",
+                                                                "NonFriendIMOptions",
+                                                                "ConferenceIMOptions",
+                                                                "GroupChatOptions"};
     S32 selectedIndex;
     S32 priorityindex = 3;
     LLComboBox * comboBox;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e513d2e6d1..b29c1484cc 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -134,36 +134,32 @@ void process_dnd_im(const LLSD& notification)
 void useMostItrusiveIMNotification()
 {
     LLFloaterPreference * instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
-    if (instance)
-    {    
-        LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
 
-        //conv. floater is closed
-        bool conversation_floater_is_closed =
-            !(  im_box
-            && im_box->isInVisibleChain()
-            && !im_box->isMinimized());
+    //conv. floater is closed
+    bool conversation_floater_is_closed =
+        !(  im_box
+        && im_box->isInVisibleChain()
+        && !im_box->isMinimized());
 
-        //conversation floater not focused (visible or not)
-        bool conversation_floater_not_focused =
-            conversation_floater_is_closed || !im_box->hasFocus();
+    //conversation floater not focused (visible or not)
+    bool conversation_floater_not_focused =
+        conversation_floater_is_closed || !im_box->hasFocus();
 
+    //Only notify user of stored DND IM messages when conversation floater isn't focused
+    if (instance && conversation_floater_not_focused)
+    {
         switch(instance->getHighestNotificationIndex())
         {
-            //Highest priority to lowest (cases correspond to options in drop down box inside Preferences->Chat)
-
             //open conversation floater
             case 0:
-                    LLFloaterReg::showInstance("im_container");
+                LLFloaterReg::showInstance("im_container");
                 break;
             //pop up message
             case 1:
             //flash toolbar button
             case 2:
-                if(conversation_floater_not_focused)
-                {
-                    gToolBarView->flashCommand(LLCommandId("chat"), true);
-                }
+                gToolBarView->flashCommand(LLCommandId("chat"), true);
                 break;
         }
     }
@@ -284,13 +280,22 @@ void on_new_message(const LLSD& msg)
     {
     	if (conversation_floater_not_focused)
     	{
-            if(session_floater_not_focused)
+            if(session_floater_not_focused && !gAgent.isDoNotDisturb())
             {
             	//User is not focused on conversation containing the message
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
             }
 
             im_box->flashConversationItemWidget(session_id, true);
+
+            //If a DND message, allow notification to be stored so upon DND exit 
+            //useMostItrusiveIMNotification will be called to notify user a message exists
+            if(session_id.notNull() 
+                && participant_id.notNull() 
+                && gAgent.isDoNotDisturb())
+            {
+                LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+            }
         }
     }
 
@@ -302,8 +307,20 @@ void on_new_message(const LLSD& msg)
             //Flash line item
             im_box->flashConversationItemWidget(session_id, true);
 
-            //Surface conversations floater
-            LLFloaterReg::showInstance("im_container");
+            if(!gAgent.isDoNotDisturb())
+            {
+                //Surface conversations floater
+                LLFloaterReg::showInstance("im_container");
+            }
+
+            //If in DND mode, allow notification to be stored so upon DND exit 
+            //useMostItrusiveIMNotification will be called to notify user a message exists
+            if(session_id.notNull() 
+                && participant_id.notNull()
+                && gAgent.isDoNotDisturb())
+            {
+                LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+            }
         }
     }
 }
-- 
cgit v1.2.3


From e44677ee79a38741d641fae74ba661b7e6b59794 Mon Sep 17 00:00:00 2001
From: maximbproductengine <maximbproductengine@lindenlab.com>
Date: Mon, 14 Jan 2013 21:48:37 +0200
Subject: CHUI-662 (Multi select across conversations can result in (???) (???)
 in the conversation list)

---
 indra/newview/llfloaterimcontainer.cpp | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index a17b89af0d..f825e253d4 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -893,7 +893,18 @@ void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
     for (; it != it_end; ++it)
     {
         conversationItem = static_cast<LLConversationItem *>((*it)->getViewModelItem());
-        selected_uuids.push_back(conversationItem->getUUID());
+      
+		//When a one-on-one conversation exists, retrieve the participant id from the conversation floater
+		if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+		{
+			LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(conversationItem->getUUID());
+			LLUUID participant_id = conversation_floaterp->getOtherParticipantUUID();
+			selected_uuids.push_back(participant_id);
+		}
+		else
+		{
+			selected_uuids.push_back(conversationItem->getUUID());
+		}
     }
 }
 
@@ -929,17 +940,7 @@ void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
 		return;
 	}
 
-    if (conversation_item->getType() == LLConversationItem::CONV_PARTICIPANT)
-    {
-        getSelectedUUIDs(selected_uuids);
-    }
-    //When a one-on-one conversation exists, retrieve the participant id from the conversation floater
-    else if(conversation_item->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
-    {
-        LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(conversation_item->getUUID());
-        LLUUID participant_id = conversation_floaterp->getOtherParticipantUUID();
-        selected_uuids.push_back(participant_id);
-    }    
+	getSelectedUUIDs(selected_uuids);  
 }
 
 void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
-- 
cgit v1.2.3


From cefcdd445b6bad0e2382d848cd73b20a1a51cc01 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 14 Jan 2013 15:26:59 -0800
Subject: CHUI-458 : WIP : Allow change of the general conversations panel when
 the selected conversation needs it (e.g. P2P is typing)

---
 indra/newview/llfloaterimcontainer.cpp | 6 ++++++
 indra/newview/llfloaterimcontainer.h   | 1 +
 indra/newview/llfloaterimsession.cpp   | 2 +-
 indra/newview/llfloaterimsession.h     | 2 ++
 4 files changed, 10 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index f825e253d4..cf81a2b046 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -238,6 +238,9 @@ BOOL LLFloaterIMContainer::postBuild()
 	// Init the sort order now that the root had been created
 	setSortOrder(LLConversationSort(gSavedSettings.getU32("ConversationSortOrder")));
 	
+	// Keep the xml set title around for when we have to overwrite it
+	mGeneralTitle = getTitle();
+	
 	mInitialized = true;
 
 	// Add callbacks:
@@ -515,6 +518,9 @@ void LLFloaterIMContainer::draw()
 
 			current_participant_model++;
 		}
+		// is P2P? Test if we can change the title
+		LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
+		setTitle(conversation_floaterp && conversation_floaterp->hasSpecialTitle() ? conversation_floaterp->getSpecialTitle() : mGeneralTitle);
 	}
 
 	LLFloater::draw();
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 85d950c58b..06af6c7b51 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -169,6 +169,7 @@ private:
 	bool mInitialized;
 
 	LLUUID mSelectedSession;
+	std::string mGeneralTitle;
 
 	// Conversation list implementation
 public:
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index d36b138c21..931ee0dc66 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -705,7 +705,7 @@ BOOL LLFloaterIMSession::getVisible()
 		// getVisible() returns TRUE when Tabbed IM window is minimized.
 			visible = is_active && !im_container->isMinimized()
 						&& im_container->getVisible();
-	}
+		}
 	}
 	else
 	{
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 6a2f4b29eb..7239481e56 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -132,6 +132,8 @@ public:
 	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
 	static floater_showed_signal_t sIMFloaterShowedSignal;
 
+	bool hasSpecialTitle() { return mOtherTyping; }
+	std::string getSpecialTitle() { return getTitle(); }
 private:
 
 	/*virtual*/ void refresh();
-- 
cgit v1.2.3


From 0e90e94a4d5cbac2d186f0056821a51078e8d1bd Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 14 Jan 2013 17:23:06 -0800
Subject: CHUI-668: The user's most intrusive notification is not used anymore
 when coming out of DND mode with IMs. Adjusted code to just open the
 converseation floater (which was changed also in a prior fix by PE).

---
 indra/newview/lldonotdisturbnotificationstorage.cpp | 13 +++++++++++++
 indra/newview/llimview.cpp                          | 19 +++----------------
 2 files changed, 16 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 5cc0ab2081..12ff308a77 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -33,6 +33,7 @@
 #include "lldir.h"
 #include "llerror.h"
 #include "llfasttimer_class.h"
+#include "llfloaterreg.h"
 #include "llnotifications.h"
 #include "llnotificationhandler.h"
 #include "llnotificationstorage.h"
@@ -103,6 +104,7 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 	}
 	
 	LLNotifications& instance = LLNotifications::instance();
+    bool imToastExists = false;
 	
 	for (LLSD::array_const_iterator notification_it = data.beginArray();
 		 notification_it != data.endArray();
@@ -110,8 +112,14 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 	{
 		LLSD notification_params = *notification_it;
         const LLUUID& notificationID = notification_params["id"];
+        std::string notificationName = notification_params["name"];
         LLNotificationPtr notification = instance.find(notificationID);
 
+        if(notificationName == "IMToast")
+        {
+            imToastExists = true;
+        }
+
         //Notification already exists in notification pipeline (same instance of app running)
 		if (notification)
 		{
@@ -138,6 +146,11 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 		}
 	}
 
+    if(imToastExists)
+    {
+        LLFloaterReg::showInstance("im_container");
+    }
+
 	// Clear the communication channel history and rewrite the save file to empty it as well
 	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
 	LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 32b4afcfef..ff171fc0f8 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -128,18 +128,11 @@ void process_dnd_im(const LLSD& notification)
             false, 
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
     }
-
-    // open conversation floater
-	LLFloaterIMContainer* container_floater =
-			LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-	if (container_floater && !(container_floater->isFrontmost()))
-    {
-		container_floater->openFloater();
-		container_floater->setFrontmost(TRUE);
-    }
 }
 
 
+
+
 static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 									   const LLAvatarName& av_name,
 									   LLSD msg)
@@ -2626,13 +2619,7 @@ void LLIMMgr::addMessage(
 	// Open conversation floater if offline messages are present
 	if (is_offline_msg)
     {
-		LLFloaterIMContainer* container_floater =
-				LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-		if (container_floater && !(container_floater->isFrontmost()))
-		{
-			container_floater->openFloater();
-			container_floater->setFrontmost(TRUE);
-		}
+        LLFloaterReg::showInstance("im_container");
     }
 
 }
-- 
cgit v1.2.3


From b7f4916b3e4af149d6212a701c556915e23e7c0a Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Tue, 15 Jan 2013 02:48:52 +0000
Subject: CHUI-679 FIX Crash when script floater appears in CHUI viewer
 LLPostponedNotification now inherits from LLMortician so it can postpone its
 deletion. This prevents a crash when looking up an avatar name in the case
 where the name already exists in the cache.

---
 indra/llui/llnotifications.cpp | 3 ++-
 indra/llui/llnotifications.h   | 5 +++--
 2 files changed, 5 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index a5492b46f7..ea52bee184 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1852,6 +1852,7 @@ void LLPostponedNotification::fetchAvatarName(const LLUUID& id)
 		{
 			mAvatarNameCacheConnection.disconnect();
 		}
+
 		mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLPostponedNotification::onAvatarNameCache, this, _1, _2));
 	}
 }
@@ -1860,7 +1861,7 @@ void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id,
 												const LLAvatarName& av_name)
 {
 	mAvatarNameCacheConnection.disconnect();
-	
+
 	std::string name = av_name.getCompleteName();
 
 	// from PE merge - we should figure out if this is the right thing to do
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 236c2a42d1..e02c58de44 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -92,6 +92,7 @@
 #include "llevents.h"
 #include "llfunctorregistry.h"
 #include "llinitparam.h"
+#include "llmortician.h"
 #include "llnotificationptr.h"
 #include "llpointer.h"
 #include "llrefcount.h"
@@ -981,7 +982,7 @@ private:
  *  1 create class derived from LLPostponedNotification;
  *  2 call LLPostponedNotification::add method;
  */
-class LLPostponedNotification
+class LLPostponedNotification : public LLMortician
 {
 public:
 	/**
@@ -1014,7 +1015,7 @@ private:
 
 	void cleanup()
 	{
-		delete this;
+		die();
 	}
 
 protected:
-- 
cgit v1.2.3


From a49d3b14254fa5cfac3900e86b2287a016eaf9cc Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 15 Jan 2013 14:07:55 +0200
Subject: CHUI-567 FIXED "Translate chat", "Translation settings..." menu items
 are added.

---
 indra/newview/app_settings/settings_per_account.xml  | 13 ++++++++++++-
 indra/newview/llfloaterimsessiontab.cpp              | 20 ++++++++++++++++++++
 indra/newview/llfloaterimsessiontab.h                |  4 ++++
 indra/newview/llfloatertranslationsettings.cpp       | 18 +++++++++++++-----
 indra/newview/llfloatertranslationsettings.h         |  1 +
 .../default/xui/en/menu_im_session_showmodes.xml     | 20 ++++++++++++++++++--
 6 files changed, 68 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 4ff494fbfb..6864328339 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -270,7 +270,18 @@
         <key>Value</key>
             <integer>0</integer>
         </map>
-      <key>ShowFavoritesOnLogin</key>
+    <key>TranslatingEnabled</key>
+        <map>
+        <key>Comment</key>
+            <string>Translation prefs are set</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>0</integer>
+        </map>
+    <key>ShowFavoritesOnLogin</key>
         <map>
         <key>Comment</key>
              <string>Determines whether favorites of last logged in user will be saved on exit from viewer and shown on login screen</string>
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index d4eb03f95d..06a79836db 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -72,6 +72,12 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck,   this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable,  this, _2));
+	mEnableCallbackRegistrar.add("Translating.Enabled",
+				boost::bind(&LLFloaterIMSessionTab::isTranslatingEnabled,  this, _2));
+	mEnableCallbackRegistrar.add("Translating.On",
+					boost::bind(&LLFloaterIMSessionTab::isTranslationOn,  this, _2));
+	mCommitCallbackRegistrar.add("Translating.Toggle",
+				boost::bind(&LLFloaterIMSessionTab::toggleTranslation,  this, _2));
 
 	// Right click menu handling
     mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem,	this, _2));
@@ -552,6 +558,10 @@ void LLFloaterIMSessionTab::onIMSessionMenuItemClicked(const LLSD& userdata)
 	LLFloaterIMSessionTab::processChatHistoryStyleUpdate();
 }
 
+void LLFloaterIMSessionTab::toggleTranslation(const LLSD& userdata)
+{
+	gSavedSettings.setBOOL("TranslateChat", !gSavedSettings.getBOOL("TranslateChat"));
+}
 
 bool LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
 {
@@ -576,6 +586,16 @@ bool LLFloaterIMSessionTab::onIMShowModesMenuItemEnable(const LLSD& userdata)
 	return (plain_text && (is_not_names || mIsP2PChat));
 }
 
+bool LLFloaterIMSessionTab::isTranslatingEnabled(const LLSD& userdata)
+{
+	return gSavedPerAccountSettings.getBOOL("TranslatingEnabled");
+}
+
+bool LLFloaterIMSessionTab::isTranslationOn(const LLSD& userdata)
+{
+	return gSavedSettings.getBOOL("TranslateChat");
+}
+
 void LLFloaterIMSessionTab::hideOrShowTitle()
 {
 	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 0fa99a46be..05da0f98bc 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -109,8 +109,12 @@ protected:
 	//
 	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
+	bool isTranslatingEnabled(const LLSD& userdata);
+	bool isTranslationOn(const LLSD& userdata);
 	static void onSlide(LLFloaterIMSessionTab *self);
 
+	void toggleTranslation(const LLSD& userdata);
+
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
 
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index 6a9236ce0c..33f2c35239 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -225,11 +225,10 @@ void LLFloaterTranslationSettings::updateControlsEnabledState()
 	mGoogleVerifyBtn->setEnabled(on && google_selected &&
 		!mGoogleKeyVerified && !getEnteredGoogleKey().empty());
 
-	mOKBtn->setEnabled(
-		!on || (
-		(bing_selected && mBingKeyVerified) ||
-		(google_selected && mGoogleKeyVerified)
-	));
+	bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified);
+	gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
+
+	mOKBtn->setEnabled(!on || service_verified);
 }
 
 void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert)
@@ -285,7 +284,16 @@ void LLFloaterTranslationSettings::onBtnGoogleVerify()
 		verifyKey(LLTranslate::SERVICE_GOOGLE, key);
 	}
 }
+void LLFloaterTranslationSettings::onClose(bool app_quitting)
+{
+	std::string service = gSavedSettings.getString("TranslationService");
+	bool bing_selected = service == "bing";
+	bool google_selected = service == "google";
+
+	bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified);
+	gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
 
+}
 void LLFloaterTranslationSettings::onBtnOK()
 {
 	gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean());
diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h
index 9b47ad72ed..b9bfd6265a 100644
--- a/indra/newview/llfloatertranslationsettings.h
+++ b/indra/newview/llfloatertranslationsettings.h
@@ -44,6 +44,7 @@ public:
 
 	void setBingVerified(bool ok, bool alert);
 	void setGoogleVerified(bool ok, bool alert);
+	void onClose(bool app_quitting);
 
 private:
 	std::string getSelectedService() const;
diff --git a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
index 483f24afd0..f2a8b39b04 100644
--- a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
+++ b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
@@ -44,7 +44,23 @@
          parameter="IMShowNamesForP2PConv" />
         <menu_item_check.on_enable
          function="IMSession.Menu.ShowModes.Enable"
-         parameter="IMShowNamesForP2PConv" />
-         
+         parameter="IMShowNamesForP2PConv" />    
     </menu_item_check>
+    <menu_item_separator layout="topleft" />
+    <menu_item_check name="Translate_chat" label="Translate chat">
+        <menu_item_check.on_click
+         function="Translating.Toggle" />
+        <menu_item_check.on_check
+         function="Translating.On" />
+        <menu_item_check.on_enable
+         function="Translating.Enabled" />
+    </menu_item_check>
+    <menu_item_check name="Translation_settings" label="Translation settings...">
+    <menu_item_check.on_check
+         function="Floater.Visible"
+         parameter="prefs_translation" />
+        <menu_item_check.on_click
+         function="Floater.Toggle"
+         parameter="prefs_translation" />
+    </menu_item_check>     
 </toggleable_menu>
-- 
cgit v1.2.3


From 235a3477364c6747d7724a090ca61adbcbeac272 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 15 Jan 2013 14:13:36 -0800
Subject: CHUI-458 : Fixed : Tidy up the title overwrite by the selected
 conversation

---
 indra/newview/llfloaterimcontainer.cpp | 6 +++---
 indra/newview/llfloaterimsession.cpp   | 2 ++
 indra/newview/llfloaterimsession.h     | 4 ++--
 3 files changed, 7 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index cf81a2b046..8264a90325 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -505,10 +505,10 @@ void LLFloaterIMContainer::draw()
 		collapseMessagesPane(true);
 	}
 	
-	//Update moderator options visibility
 	const LLConversationItem *current_session = getCurSelectedViewModelItem();
 	if (current_session)
 	{
+		// Update moderator options visibility
 		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
 		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
 		while (current_participant_model != end_participant_model)
@@ -518,9 +518,9 @@ void LLFloaterIMContainer::draw()
 
 			current_participant_model++;
 		}
-		// is P2P? Test if we can change the title
+		// Update floater's title as required by the currently selected session or use the default title
 		LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
-		setTitle(conversation_floaterp && conversation_floaterp->hasSpecialTitle() ? conversation_floaterp->getSpecialTitle() : mGeneralTitle);
+		setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
 	}
 
 	LLFloater::draw();
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 931ee0dc66..a09dc1914f 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -70,6 +70,7 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
 	mShouldSendTypingState(false),
 	mMeTyping(false),
 	mOtherTyping(false),
+	mSessionNameUpdatedForTyping(false),
 	mTypingTimer(),
 	mTypingTimeoutTimer(),
 	mPositioned(false),
@@ -556,6 +557,7 @@ void LLFloaterIMSession::updateSessionName(const std::string& name)
 		LLFloaterIMSessionTab::updateSessionName(name);
 		mTypingStart.setArg("[NAME]", name);
 		setTitle (mOtherTyping ? mTypingStart.getString() : name);
+		mSessionNameUpdatedForTyping = mOtherTyping;
 	}
 }
 
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 7239481e56..2049cedfd7 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -132,8 +132,7 @@ public:
 	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
 	static floater_showed_signal_t sIMFloaterShowedSignal;
 
-	bool hasSpecialTitle() { return mOtherTyping; }
-	std::string getSpecialTitle() { return getTitle(); }
+	bool needsTitleOverwrite() { return mSessionNameUpdatedForTyping && mOtherTyping; }
 private:
 
 	/*virtual*/ void refresh();
@@ -184,6 +183,7 @@ private:
 	bool mShouldSendTypingState;
 	LLFrameTimer mTypingTimer;
 	LLFrameTimer mTypingTimeoutTimer;
+	bool mSessionNameUpdatedForTyping;
 
 	bool mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
-- 
cgit v1.2.3


From de9e2c38126682e5c6215151e3389380a93b8bc0 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 15 Jan 2013 20:36:48 -0800
Subject: CHUI-668: Code review changes

---
 indra/newview/llagent.cpp                          |   2 +-
 indra/newview/llcommunicationchannel.cpp           |  32 +++++-
 indra/newview/llcommunicationchannel.h             |   8 +-
 .../newview/lldonotdisturbnotificationstorage.cpp  | 108 +++++++++++++++++----
 indra/newview/lldonotdisturbnotificationstorage.h  |  21 +++-
 5 files changed, 146 insertions(+), 25 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index d28af3eff9..094d502078 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -1397,7 +1397,7 @@ void LLAgent::setDoNotDisturb(bool pIsDoNotDisturb)
 	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDoNotDisturb);
 	if (isDoNotDisturbSwitchedOff)
 	{
-		LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
+		LLDoNotDisturbNotificationStorage::getInstance()->updateNotifications();
 	}
 }
 
diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
index a99047c163..0821510645 100644
--- a/indra/newview/llcommunicationchannel.cpp
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -52,6 +52,11 @@ bool LLCommunicationChannel::filterByDoNotDisturbStatus(LLNotificationPtr)
 	return !gAgent.isDoNotDisturb();
 }
 
+S32 LLCommunicationChannel::getHistorySize() const
+{
+    return mHistory.size();
+}
+
 LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::beginHistory() const
 {
 	return mHistory.begin();
@@ -62,14 +67,37 @@ LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::e
 	return mHistory.end();
 }
 
+LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::beginHistory()
+{
+    return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::endHistory()
+{
+    return mHistory.end();
+}
+
 void LLCommunicationChannel::clearHistory()
 {
 	mHistory.clear();
 }
 
-void LLCommunicationChannel::removeItem(history_list_t::const_iterator itemToRemove)
+void LLCommunicationChannel::removeItemFromHistory(LLNotificationPtr p)
+{
+    //Find the notification and removes it from mHistory
+    for(history_list_t::iterator it = beginHistory(); it != endHistory(); ++it)
+    {
+        if(it->second == p)
+        {
+            mHistory.erase(it);
+            break;
+        }
+    }
+}
+
+void LLCommunicationChannel::onDelete(LLNotificationPtr p) 
 {
-    mHistory.erase(itemToRemove);
+    removeItemFromHistory(p);
 }
 
 void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
index c07933118d..0d8f7f4387 100644
--- a/indra/newview/llcommunicationchannel.h
+++ b/indra/newview/llcommunicationchannel.h
@@ -44,13 +44,17 @@ public:
 	static bool filterByDoNotDisturbStatus(LLNotificationPtr);
 
 	typedef std::multimap<LLDate, LLNotificationPtr> history_list_t;
+    S32 getHistorySize() const;	
 	history_list_t::const_iterator beginHistory() const;
 	history_list_t::const_iterator endHistory() const;
-	
+    history_list_t::iterator beginHistory();
+    history_list_t::iterator endHistory();	
+
 	void clearHistory();
-    void removeItem(history_list_t::const_iterator itemToRemove);
+    void removeItemFromHistory(LLNotificationPtr p);
 
 protected:
+    virtual void onDelete(LLNotificationPtr p);
 	virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
 
 private:
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 12ff308a77..42b455c1ce 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -42,9 +42,34 @@
 #include "llsingleton.h"
 #include "lluuid.h"
 
+static const F32 DND_TIMER = 3.0;
+
+LLDoNotDisturbNotificationStorageTimer::LLDoNotDisturbNotificationStorageTimer() : LLEventTimer(DND_TIMER)
+{
+    mEventTimer.start();
+}
+
+LLDoNotDisturbNotificationStorageTimer::~LLDoNotDisturbNotificationStorageTimer()
+{
+    mEventTimer.stop();
+}
+
+BOOL LLDoNotDisturbNotificationStorageTimer::tick()
+{
+    LLDoNotDisturbNotificationStorage * doNotDisturbNotificationStorage =  LLDoNotDisturbNotificationStorage::getInstance();
+
+    if(doNotDisturbNotificationStorage
+        && doNotDisturbNotificationStorage->getDirty())
+    {
+        doNotDisturbNotificationStorage->saveNotifications();
+    }
+    return FALSE;
+}
+
 LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
 	: LLSingleton<LLDoNotDisturbNotificationStorage>()
 	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
+    , mDirty(false)
 {
 }
 
@@ -57,6 +82,16 @@ void LLDoNotDisturbNotificationStorage::initialize()
 	getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
 }
 
+bool LLDoNotDisturbNotificationStorage::getDirty()
+{
+    return mDirty;
+}
+
+void LLDoNotDisturbNotificationStorage::resetDirty()
+{
+    mDirty = false;
+}
+
 static LLFastTimer::DeclareTimer FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications");
 
 void LLDoNotDisturbNotificationStorage::saveNotifications()
@@ -83,6 +118,8 @@ void LLDoNotDisturbNotificationStorage::saveNotifications()
 	}
 
 	writeNotifications(output);
+
+    resetDirty();
 }
 
 static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications");
@@ -120,15 +157,7 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
             imToastExists = true;
         }
 
-        //Notification already exists in notification pipeline (same instance of app running)
-		if (notification)
-		{
-            notification->setDND(true);
-			instance.update(notification);
-		}
-        //Notification doesn't exist (different instance since restarted app while in DND mode)
-		else
-		{
+        //New notification needs to be added
             notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
 			LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
 			if (responder == NULL)
@@ -144,21 +173,58 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 			
 			instance.add(notification);
 		}
-	}
 
     if(imToastExists)
     {
         LLFloaterReg::showInstance("im_container");
     }
 
-	// Clear the communication channel history and rewrite the save file to empty it as well
+    //writes out empty .xml file (since LLCommunicationChannel::mHistory is empty)
+	saveNotifications();
+}
+
+void LLDoNotDisturbNotificationStorage::updateNotifications()
+{
+
 	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
 	LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
 	llassert(commChannel != NULL);
+
+    LLNotifications& instance = LLNotifications::instance();
+    bool imToastExists = false;
+  
+    for (LLCommunicationChannel::history_list_t::const_iterator it = commChannel->beginHistory();
+        it != commChannel->endHistory();
+        ++it)
+    {
+        LLNotificationPtr notification = it->second;
+        std::string notificationName = notification->getName();
+
+        if(notificationName == "IMToast")
+        {
+            imToastExists = true;
+        }
+
+        //Notification already exists in notification pipeline (same instance of app running)
+        if (notification)
+        {
+            notification->setDND(true);
+            instance.update(notification);
+        }
+    }
+
+    if(imToastExists)
+    {   
+        LLFloaterReg::showInstance("im_container");
+    }
+
+    //When exit DND mode, write empty notifications file
+    if(commChannel->getHistorySize())
+    {
 	commChannel->clearHistory();
-	
 	saveNotifications();
 }
+}
 
 LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
 {
@@ -175,8 +241,8 @@ void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& sessi
     LLNotificationPtr notification;
     LLSD substitutions;
     LLUUID notificationSessionID;
-    LLCommunicationChannel::history_list_t::const_iterator it;
-    std::vector<LLCommunicationChannel::history_list_t::const_iterator> itemsToRemove;
+    LLCommunicationChannel::history_list_t::iterator it;
+    std::vector<LLCommunicationChannel::history_list_t::iterator> itemsToRemove;
 
     //Find notification with the matching session id
     for (it = commChannel->beginHistory();
@@ -193,17 +259,21 @@ void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& sessi
         }
     }
 
-    //Remove the notification
+   
+    //Remove the notifications
+    if(itemsToRemove.size())
+    {
     while(itemsToRemove.size())
     {
         it = itemsToRemove.back();
         notification = it->second;
-        commChannel->removeItem(it);
-        //instance.cancel triggers onChannelChanged to be called within LLNotificationChannelBase::updateItem (which save changes to the .xml file)
-        //but this means that saveNotifications write a file each time as well, BAD! Will find a way to prevent this.
+            commChannel->removeItemFromHistory(notification);
         instance.cancel(notification);
         itemsToRemove.pop_back();
     }
+        //Trigger saving of notifications to xml once all have been removed
+        saveNotifications();
+    }
 }
 
 
@@ -211,7 +281,7 @@ bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
 {
 	if (pPayload["sigtype"].asString() != "load")
 	{
-		saveNotifications();
+        mDirty = true;
 	}
 
 	return false;
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index 8edb8569b4..fd03b71357 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -28,12 +28,26 @@
 #define LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
 
 #include "llerror.h"
+#include "lleventtimer.h"
 #include "llnotifications.h"
 #include "llnotificationstorage.h"
 #include "llsingleton.h"
 
 class LLSD;
 
+class LLDoNotDisturbNotificationStorageTimer : public LLEventTimer
+{
+public:
+    LLDoNotDisturbNotificationStorageTimer();
+    ~LLDoNotDisturbNotificationStorageTimer();
+
+public:
+    void startTimer();
+    void stopTimer();
+    bool isRunning();
+    BOOL tick();
+};
+
 class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage
 {
 	LOG_CLASS(LLDoNotDisturbNotificationStorage);
@@ -42,14 +56,19 @@ public:
 	~LLDoNotDisturbNotificationStorage();
 
 	void initialize();
-
+    bool getDirty();
+    void resetDirty();
 	void saveNotifications();
 	void loadNotifications();
+    void updateNotifications();
     void removeIMNotification(const LLUUID& session_id);
 
 protected:
 
 private:
+    bool mDirty;
+    LLDoNotDisturbNotificationStorageTimer mTimer;
+
 	LLNotificationChannelPtr getCommunicationChannel() const;
 	bool                     onChannelChanged(const LLSD& pPayload);
 };
-- 
cgit v1.2.3


From b0774ec9147ddc2c2e5e93e5a74c929c802c32af Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 16 Jan 2013 17:37:13 +0200
Subject: CHUI-650 (Floaters not returning to active transparency after
 becoming inactive) - Checking is added(comparing to previous fix) to avoid
 crash.

---
 indra/llui/llfloater.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 8f9be5285d..d2aae11191 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -655,7 +655,7 @@ void LLFloater::openFloater(const LLSD& key)
 {
 	llinfos << "Opening floater " << getName() << llendl;
 	mKey = key; // in case we need to open ourselves again
-	
+
 	if (getSoundFlags() != SILENT 
 	// don't play open sound for hosted (tabbed) windows
 		&& !getHost() 
@@ -2394,6 +2394,11 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 {
 	if (mFrontChild == child)
 	{
+
+		if (give_focus && !gFocusMgr.childHasKeyboardFocus(child))
+		{
+			child->setFocus(TRUE);
+		}
 		return;
 	}
 
-- 
cgit v1.2.3


From 8c3d3d4b07f12e3462af7745016536389ab7cf73 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 16 Jan 2013 16:40:59 +0200
Subject: CHUI-618 ADD FIX User sees no indication of offline messages received
 with conversation log preference turned off: forced flashing of
 conversation's item when offline message is present

---
 indra/newview/llimview.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index ff171fc0f8..d0a8dfc0c8 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2620,8 +2620,9 @@ void LLIMMgr::addMessage(
 	if (is_offline_msg)
     {
         LLFloaterReg::showInstance("im_container");
+	    LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->
+	    		flashConversationItemWidget(session_id, true);
     }
-
 }
 
 void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
-- 
cgit v1.2.3


From f43f51406b024ed2423e068114ae818bac5c6df5 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 16 Jan 2013 14:53:23 -0800
Subject: CHUI-683 : Default sort order for Blocked was wrong, unrecognized
 value was not tested.

---
 indra/newview/app_settings/settings.xml | 2 +-
 indra/newview/llpanelblockedlist.cpp    | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 126df69519..fd4d1df894 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10215,7 +10215,7 @@
       <key>Type</key>
       <string>U32</string>
       <key>Value</key>
-      <integer>2</integer>
+      <integer>0</integer>
     </map>
     <key>CallLogSortOrder</key>
     <map>
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index df1ccdd9fc..115114bb53 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -89,6 +89,9 @@ BOOL LLPanelBlockedList::postBuild()
 	case E_SORT_BY_TYPE:
 		mBlockedList->sortByType();
 		break;
+	default:
+		llwarns << "Unrecognized sort order for blocked list" << llendl;
+		break;
 	}
 
 	// Use the context menu of the Block list for the Block tab gear menu.
-- 
cgit v1.2.3


From 5083517c7cd6b91b8920ab0f698600abed955280 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Thu, 17 Jan 2013 01:57:19 +0000
Subject: CHUI-292 FIX Extra space in object chiclet toasts in CHUI viewer
 compared with release viewer In LLToastNotifyPanel, moved
 mInfoPanel->SetFollowsAll() immediately before call to snapToMessageHeight()
 as was previously the case in release viewer

---
 indra/newview/lltoastnotifypanel.cpp | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index d494d12903..268b68b539 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -356,9 +356,8 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
     if(rect != LLRect::null)
     {
         this->setShape(rect);
-    }		 
+    }
     mInfoPanel = getChild<LLPanel>("info_panel");
-    mInfoPanel->setFollowsAll();
 
     mControlPanel = getChild<LLPanel>("control_panel");
     BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
@@ -453,10 +452,10 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
             if(h_pad < 2*HPAD)
             {
                 /*
-                * Probably it is a scriptdialog toast
-                * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
-                * In last case set default h_pad to avoid heaping of buttons 
-                */
+                 * Probably it is a scriptdialog toast
+                 * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
+                 * In last case set default h_pad to avoid heaping of buttons 
+                 */
                 S32 button_per_row = button_panel_width / BUTTON_WIDTH;
                 h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1  because we do not need space after last button in a row   
                 if(h_pad < 2*HPAD) // still not enough space between buttons ?
@@ -491,10 +490,10 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
             //mButtons.assign(buttons.begin(), buttons.end());
         }
     }
+
     // adjust panel's height to the text size
+    mInfoPanel->setFollowsAll();
     snapToMessageHeight(mTextBox, MAX_LENGTH);
-
-
 }
 
 
-- 
cgit v1.2.3


From 90adfec715eb93663b424a2ac28a70e965247df4 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 16 Jan 2013 19:22:36 -0800
Subject: CHUI-682 : WIP : Instrument the menu display (or lack thereof).

---
 indra/newview/llpaneloutfitedit.cpp | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index d690a18477..c11539353a 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -155,6 +155,8 @@ class LLPanelOutfitEditGearMenu
 public:
 	static LLToggleableMenu* create()
 	{
+		llinfos << "Merov debug : Create wearable gear menu" << llendl;
+
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
 		registrar.add("Wearable.Create", boost::bind(onCreate, _2));
@@ -169,6 +171,12 @@ public:
 
 		return menu;
 	}
+	
+	static void pressed(LLToggleableMenu* menu)
+	{
+		menu->toggleVisibility();
+		llinfos << "Merov debug : The button is pressed! Show the menu!!!" << llendl;
+	}
 
 private:
 	static void onCreate(const LLSD& param)
@@ -189,6 +197,8 @@ private:
 		LLView* menu_clothes	= gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);
 		LLView* menu_bp			= gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE);
 
+		llinfos << "Merov debug : Populate wearable gear menu" << llendl;
+		
 		for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i)
 		{
 			LLWearableType::EType type = (LLWearableType::EType) i;
@@ -197,6 +207,7 @@ private:
 			LLMenuItemCallGL::Params p;
 			p.name = type_name;
 			p.label = LLTrans::getString(LLWearableType::getTypeDefaultNewName(type));
+			llinfos << "Merov debug :    menu label = " << LLTrans::getString(LLWearableType::getTypeDefaultNewName(type)) << llendl;
 			p.on_click.function_name = "Wearable.Create";
 			p.on_click.parameter = LLSD(type_name);
 
@@ -204,6 +215,8 @@ private:
 				menu_clothes : menu_bp;
 			LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
 		}
+		
+		llinfos << "Merov debug : clothes size = " << menu_clothes->getChildCount() << ", body part size = " << menu_bp->getChildCount() << llendl;
 	}
 };
 
@@ -564,6 +577,7 @@ BOOL LLPanelOutfitEdit::postBuild()
 	mWearablesGearMenuBtn->setMenu(mAddWearablesGearMenu);
 
 	mGearMenu = LLPanelOutfitEditGearMenu::create();
+	mGearMenuBtn->setMouseDownCallback(boost::bind(&LLPanelOutfitEditGearMenu::pressed, mGearMenu));
 	mGearMenuBtn->setMenu(mGearMenu);
 
 	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
-- 
cgit v1.2.3


From 7ec0d837dd2f364a775757b808351fa81c2468a8 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Thu, 17 Jan 2013 19:05:22 +0200
Subject: CHUI-631 (Next conversation in list should be selected in
 Conversations floater after closing a conversation) Don't force selecting
 nearby chat after closing conversation

---
 indra/newview/llfloaterimsessiontab.cpp | 7 -------
 1 file changed, 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 06a79836db..bc5b8c334d 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -88,13 +88,6 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
 {
 	delete mRefreshTimer;
-
-	// Select Nearby Chat session
-	LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
-	if (container)
-	{
-		container->selectConversationPair(LLUUID(NULL), true);
-	}
 }
 
 //static
-- 
cgit v1.2.3


From aabfce7d9f14ff18ea073708d79c6f62118b3453 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 17 Jan 2013 21:40:49 -0800
Subject: CHUI-682 : Fixed : Added LLMenuGL as a possible child of a toggle or
 contextual menu (for dynamic submenus).

---
 indra/llui/llmenugl.cpp             | 28 +++++++++++++++++++++-------
 indra/newview/llpaneloutfitedit.cpp | 14 --------------
 2 files changed, 21 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 93dc13475b..7dcc39950b 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1751,16 +1751,18 @@ void LLMenuGL::setCanTearOff(BOOL tear_off)
 
 bool LLMenuGL::addChild(LLView* view, S32 tab_group)
 {
-	if (LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view))
+	LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
+	if (menup)
 	{
-		appendMenu(menup);
-		return true;
+		return appendMenu(menup);
 	}
-	else if (LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view))
+	
+	LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view);
+	if (itemp)
 	{
-		append(itemp);
-		return true;
+		return append(itemp);
 	}
+	
 	return false;
 }
 
@@ -1771,16 +1773,28 @@ bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)
 {
 	LLContextMenu* context = dynamic_cast<LLContextMenu*>(view);
 	if (context)
+	{
 		return appendContextSubMenu(context);
+	}
 
 	LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view);
 	if (separator)
+	{
 		return append(separator);
+	}
 
 	LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view);
 	if (item)
+	{
 		return append(item);
-
+	}
+	
+	LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
+	if (menup)
+	{
+		return appendMenu(menup);
+	}
+	
 	return false;
 }
 
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index c11539353a..f5db98f831 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -155,8 +155,6 @@ class LLPanelOutfitEditGearMenu
 public:
 	static LLToggleableMenu* create()
 	{
-		llinfos << "Merov debug : Create wearable gear menu" << llendl;
-
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
 		registrar.add("Wearable.Create", boost::bind(onCreate, _2));
@@ -172,12 +170,6 @@ public:
 		return menu;
 	}
 	
-	static void pressed(LLToggleableMenu* menu)
-	{
-		menu->toggleVisibility();
-		llinfos << "Merov debug : The button is pressed! Show the menu!!!" << llendl;
-	}
-
 private:
 	static void onCreate(const LLSD& param)
 	{
@@ -197,8 +189,6 @@ private:
 		LLView* menu_clothes	= gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);
 		LLView* menu_bp			= gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE);
 
-		llinfos << "Merov debug : Populate wearable gear menu" << llendl;
-		
 		for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i)
 		{
 			LLWearableType::EType type = (LLWearableType::EType) i;
@@ -207,7 +197,6 @@ private:
 			LLMenuItemCallGL::Params p;
 			p.name = type_name;
 			p.label = LLTrans::getString(LLWearableType::getTypeDefaultNewName(type));
-			llinfos << "Merov debug :    menu label = " << LLTrans::getString(LLWearableType::getTypeDefaultNewName(type)) << llendl;
 			p.on_click.function_name = "Wearable.Create";
 			p.on_click.parameter = LLSD(type_name);
 
@@ -215,8 +204,6 @@ private:
 				menu_clothes : menu_bp;
 			LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
 		}
-		
-		llinfos << "Merov debug : clothes size = " << menu_clothes->getChildCount() << ", body part size = " << menu_bp->getChildCount() << llendl;
 	}
 };
 
@@ -577,7 +564,6 @@ BOOL LLPanelOutfitEdit::postBuild()
 	mWearablesGearMenuBtn->setMenu(mAddWearablesGearMenu);
 
 	mGearMenu = LLPanelOutfitEditGearMenu::create();
-	mGearMenuBtn->setMouseDownCallback(boost::bind(&LLPanelOutfitEditGearMenu::pressed, mGearMenu));
 	mGearMenuBtn->setMenu(mGearMenu);
 
 	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
-- 
cgit v1.2.3


From 3938f99b5ede5b87315fa18ca24d2deece28b34d Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 18 Jan 2013 14:18:51 +0200
Subject: CHUI-681 FIXED Clear flash state only for selected widget

---
 indra/newview/llconversationview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 903dd2a407..126c73c283 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -246,7 +246,7 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
     if(result && getRoot()->getCurSelectedItem() == this)
 	{
 		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-		im_container->clearAllFlashStates();
+		im_container->flashConversationItemWidget(session_id,false);
 		im_container->selectConversationPair(session_id, false);
 		im_container->collapseMessagesPane(false);
 	}
-- 
cgit v1.2.3


From be7835eec6b6cae12656fede44fc2cda1729e20d Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 17 Jan 2013 16:25:21 +0200
Subject: CHUI-625 Participant drop down icon not visible when conversation is
 highlighted orange: redraw the arrow slightly later

---
 indra/newview/llconversationview.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 126c73c283..16dd0e4565 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -202,14 +202,6 @@ void LLConversationViewSession::draw()
 	const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
 	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
 
-	// we don't draw the open folder arrow in minimized mode
-	if (mHasArrow && !mCollapsedMode)
-	{
-		// update the rotation angle of open folder arrow
-		updateLabelRotation();
-		drawOpenFolderArrow(default_params, sFgColor);
-	}
-
 	// Indicate that flash can start (moot operation if already started, done or not flashing)
 	startFlashing();
 
@@ -232,6 +224,14 @@ void LLConversationViewSession::draw()
 		(*iit)->setVisible(draw_children);
 	}
 
+	// we don't draw the open folder arrow in minimized mode
+	if (mHasArrow && !mCollapsedMode)
+	{
+		// update the rotation angle of open folder arrow
+		updateLabelRotation();
+		drawOpenFolderArrow(default_params, sFgColor);
+	}
+
 	LLView::draw();
 }
 
-- 
cgit v1.2.3


From fdf774f51fd24bb62d1e1fc580bd04df4547b9f8 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 17 Jan 2013 13:52:51 -0800
Subject: CHUI-685 Problem: The notifications .xml file was cleared upon exit
 because removeIMNotification was being called and deleting inventory offers
 becaus they did not have a session id. Resolution: Now check to make sure
 that removeIMNotification only removes IMs (IMToast).

---
 .../newview/lldonotdisturbnotificationstorage.cpp  | 62 ++++++++++++----------
 indra/newview/lldonotdisturbnotificationstorage.h  |  3 --
 indra/newview/llfloaterimcontainer.cpp             | 16 +++---
 3 files changed, 40 insertions(+), 41 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 42b455c1ce..5bea7d41f6 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -43,15 +43,16 @@
 #include "lluuid.h"
 
 static const F32 DND_TIMER = 3.0;
+const std::string toastName = "IMToast";
 
 LLDoNotDisturbNotificationStorageTimer::LLDoNotDisturbNotificationStorageTimer() : LLEventTimer(DND_TIMER)
 {
-    mEventTimer.start();
+    //mEventTimer.start();
 }
 
 LLDoNotDisturbNotificationStorageTimer::~LLDoNotDisturbNotificationStorageTimer()
 {
-    mEventTimer.stop();
+    //mEventTimer.stop();
 }
 
 BOOL LLDoNotDisturbNotificationStorageTimer::tick()
@@ -152,27 +153,27 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
         std::string notificationName = notification_params["name"];
         LLNotificationPtr notification = instance.find(notificationID);
 
-        if(notificationName == "IMToast")
+        if(notificationName == toastName)
         {
             imToastExists = true;
         }
 
         //New notification needs to be added
-            notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
-			LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
-			if (responder == NULL)
-			{
-				LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
-					<< notification->getType() << "'" << LL_ENDL;
-			}
-			else
-			{
-				LLNotificationResponderPtr responderPtr(responder);
-				notification->setResponseFunctor(responderPtr);
-			}
-			
-			instance.add(notification);
+        notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
+		LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
+		if (responder == NULL)
+		{
+			LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
+				<< notification->getType() << "'" << LL_ENDL;
+		}
+		else
+		{
+			LLNotificationResponderPtr responderPtr(responder);
+			notification->setResponseFunctor(responderPtr);
 		}
+			
+		instance.add(notification);
+	}
 
     if(imToastExists)
     {
@@ -200,7 +201,7 @@ void LLDoNotDisturbNotificationStorage::updateNotifications()
         LLNotificationPtr notification = it->second;
         std::string notificationName = notification->getName();
 
-        if(notificationName == "IMToast")
+        if(notificationName == toastName)
         {
             imToastExists = true;
         }
@@ -221,9 +222,9 @@ void LLDoNotDisturbNotificationStorage::updateNotifications()
     //When exit DND mode, write empty notifications file
     if(commChannel->getHistorySize())
     {
-	commChannel->clearHistory();
-	saveNotifications();
-}
+	    commChannel->clearHistory();
+	    saveNotifications();
+    }
 }
 
 LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
@@ -241,6 +242,7 @@ void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& sessi
     LLNotificationPtr notification;
     LLSD substitutions;
     LLUUID notificationSessionID;
+    std::string notificationName;
     LLCommunicationChannel::history_list_t::iterator it;
     std::vector<LLCommunicationChannel::history_list_t::iterator> itemsToRemove;
 
@@ -252,8 +254,10 @@ void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& sessi
         notification = it->second;
         substitutions = notification->getSubstitutions();
         notificationSessionID = substitutions["SESSION_ID"].asUUID();
+        notificationName = notification->getName();
 
-        if(session_id == notificationSessionID)
+        if(notificationName == toastName
+            && session_id == notificationSessionID)
         {
             itemsToRemove.push_back(it);
         }
@@ -263,14 +267,14 @@ void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& sessi
     //Remove the notifications
     if(itemsToRemove.size())
     {
-    while(itemsToRemove.size())
-    {
-        it = itemsToRemove.back();
-        notification = it->second;
+        while(itemsToRemove.size())
+        {
+            it = itemsToRemove.back();
+            notification = it->second;
             commChannel->removeItemFromHistory(notification);
-        instance.cancel(notification);
-        itemsToRemove.pop_back();
-    }
+            instance.cancel(notification);
+            itemsToRemove.pop_back();
+        }
         //Trigger saving of notifications to xml once all have been removed
         saveNotifications();
     }
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index fd03b71357..fd7cc7ee82 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -42,9 +42,6 @@ public:
     ~LLDoNotDisturbNotificationStorageTimer();
 
 public:
-    void startTimer();
-    void stopTimer();
-    bool isRunning();
     BOOL tick();
 };
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index cc23449449..8f290ae7c1 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1299,11 +1299,14 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     	if (widget && widget->getParentFolder())
     	{
     		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
-            if(gAgent.isDoNotDisturb())
-            {
-                LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
-            }
     	}
+
+        //When in DND mode, remove stored IM notifications
+        //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+        if(gAgent.isDoNotDisturb() && session_id.notNull())
+        {
+            LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
+        }
     }
 
     /* floater processing */
@@ -1324,11 +1327,6 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 				// Switch to the conversation floater that is being selected
 				selectFloater(session_floater);
 			}
-
-            if(gAgent.isDoNotDisturb())
-            {
-                LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
-            }
 		}
 
 		// Set the focus on the selected floater
-- 
cgit v1.2.3


From 6a134c92d82746a2bfbf011e53aa04bdec67655f Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Fri, 18 Jan 2013 00:05:51 +0200
Subject: CHUI-661 User cannot select multiple p2p conversation names in list
 to start conference chat

---
 indra/newview/llfloaterimcontainer.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 8264a90325..ac5ecc4b80 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1290,9 +1290,9 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 {
     BOOL handled = TRUE;
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
-
+	
     /* widget processing */
-    if (select_widget)
+    if (select_widget && mConversationsRoot->getSelectedCount() <= 1)
     {
 		LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
     	if (widget && widget->getParentFolder())
-- 
cgit v1.2.3


From 68adda3627b0583e01796b229e1c1f920f28ff37 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 17 Jan 2013 14:12:48 -0800
Subject: CHUI-685 removing some commented out code

---
 indra/newview/lldonotdisturbnotificationstorage.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 5bea7d41f6..824ff67972 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -47,12 +47,12 @@ const std::string toastName = "IMToast";
 
 LLDoNotDisturbNotificationStorageTimer::LLDoNotDisturbNotificationStorageTimer() : LLEventTimer(DND_TIMER)
 {
-    //mEventTimer.start();
+
 }
 
 LLDoNotDisturbNotificationStorageTimer::~LLDoNotDisturbNotificationStorageTimer()
 {
-    //mEventTimer.stop();
+
 }
 
 BOOL LLDoNotDisturbNotificationStorageTimer::tick()
-- 
cgit v1.2.3


From 6c79873d8dcb08c891ecd04f5706e69fe3a75b7d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 17 Jan 2013 15:14:02 -0800
Subject: CHUI-680: Adjusted LLResponderRegistry to be derived from
 LLRegistrySingleton instead of LLResponderRegistry making its over version.

---
 indra/newview/llnotificationstorage.cpp | 93 ++++++++++++---------------------
 1 file changed, 33 insertions(+), 60 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index 4c5b7cc198..b6184f09bf 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -38,30 +38,43 @@
 #include "llsd.h"
 #include "llsdserialize.h"
 #include "llsingleton.h"
-#include "llviewermessage.h"
+#include "llregistry.h"
+#include "llviewermessage.h" 
 
+typedef boost::function<LLNotificationResponderInterface * (const LLSD& pParams)> responder_constructor_t;
 
-class LLResponderRegistry : public LLSingleton<LLResponderRegistry>
+class LLResponderRegistry : public LLRegistrySingleton<std::string, responder_constructor_t, LLResponderRegistry>
 {
-public:
-	LLResponderRegistry();
-	~LLResponderRegistry();
-	
-	LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams);
-	
-protected:
-	
-private:
-	template<typename RESPONDER_TYPE> static LLNotificationResponderInterface* create(const LLSD& pParams);
-	
-	typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
-	
-	void add(const std::string& pNotificationName, const responder_constructor_t& pConstructor);
-	
-	typedef std::map<std::string, responder_constructor_t> build_map_t;
-	build_map_t mBuildMap;
+    public:
+        template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams);
+        LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams);
 };
 
+template<typename RESPONDER_TYPE> LLNotificationResponderInterface * LLResponderRegistry::create(const LLSD& pParams)
+{
+    RESPONDER_TYPE* responder = new RESPONDER_TYPE();
+    responder->fromLLSD(pParams);
+    return responder;
+}
+
+
+LLNotificationResponderInterface * LLResponderRegistry::createResponder(const std::string& pNotificationName, const LLSD& pParams)
+{
+    responder_constructor_t * factoryFunc = (LLResponderRegistry::getValue(pNotificationName));
+
+    if(factoryFunc)
+    {
+        return (*factoryFunc)(pParams);
+    }
+    
+    return NULL;
+}
+
+LLResponderRegistry::StaticRegistrar sRegisterObjectGiveItem("ObjectGiveItem", &LLResponderRegistry::create<LLOfferInfo>);
+LLResponderRegistry::StaticRegistrar sRegisterUserGiveItem("UserGiveItem", &LLResponderRegistry::create<LLOfferInfo>);
+LLResponderRegistry::StaticRegistrar sRegisterOfferInfo("offer_info", &LLResponderRegistry::create<LLOfferInfo>);
+
+
 LLNotificationStorage::LLNotificationStorage(std::string pFileName)
 	: mFileName(pFileName)
 {
@@ -116,47 +129,7 @@ bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
 	return didFileRead;
 }
 
-LLNotificationResponderInterface* LLNotificationStorage::createResponder(const std::string& pNotificationName, const LLSD& pParams) const
+LLNotificationResponderInterface * LLNotificationStorage::createResponder(const std::string& pNotificationName, const LLSD& pParams) const
 {
 	return LLResponderRegistry::getInstance()->createResponder(pNotificationName, pParams);
 }
-
-LLResponderRegistry::LLResponderRegistry()
-	: LLSingleton<LLResponderRegistry>()
-	, mBuildMap()
-{
-	add("ObjectGiveItem", &create<LLOfferInfo>);
-	add("UserGiveItem", &create<LLOfferInfo>);
-    add("offer_info", &create<LLOfferInfo>);
-}
-
-LLResponderRegistry::~LLResponderRegistry()
-{
-}
-
-LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& pNotificationName, const LLSD& pParams)
-{
-	build_map_t::const_iterator it = mBuildMap.find(pNotificationName);
-	if(mBuildMap.end() == it)
-	{
-		return NULL;
-	}
-	responder_constructor_t ctr = it->second;
-	return ctr(pParams);
-}
-
-template<typename RESPONDER_TYPE> LLNotificationResponderInterface* LLResponderRegistry::create(const LLSD& pParams)
-{
-	RESPONDER_TYPE* responder = new RESPONDER_TYPE();
-	responder->fromLLSD(pParams);
-	return responder;
-}
-	
-void LLResponderRegistry::add(const std::string& pNotificationName, const responder_constructor_t& pConstructor)
-{
-	if (mBuildMap.find(pNotificationName) != mBuildMap.end())
-	{
-		LL_ERRS("LLResponderRegistry") << "Responder is already registered : " << pNotificationName << LL_ENDL;
-	}
-	mBuildMap.insert(std::make_pair<std::string, responder_constructor_t>(pNotificationName, pConstructor));
-}
-- 
cgit v1.2.3


From d0235ad1789d05524065307f4514a76d55f4e847 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 17 Jan 2013 16:06:08 -0800
Subject: CHUI-604: Problem: DND response was inside of the responder for the
 inventory offer. Resolution: DND response is now sent upon receiving an offer
 notification from an agent.

---
 indra/newview/llviewermessage.cpp | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index db81e057de..9878f9bc81 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1618,12 +1618,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			{
 				opener = discard_agent_offer;
 			}
-			
-			
-			if (gAgent.isDoNotDisturb() && (!mFromGroup && !mFromObject))
-			{
-				send_do_not_disturb_message(gMessageSystem, mFromID);
-			}
 
 			if (modified_form != NULL)
 			{
@@ -1991,6 +1985,11 @@ void inventory_offer_handler(LLOfferInfo* info)
 		// In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
 		info->send_auto_receive_response();
 
+        if (gAgent.isDoNotDisturb()) 
+        {
+            send_do_not_disturb_message(gMessageSystem, info->mFromID);
+        }
+
 		// Inform user that there is a script floater via toast system
 		{
 			payload["give_inventory_notification"] = TRUE;
-- 
cgit v1.2.3


From 1780e78884c1b111f4a48bea578e28b370fbe45c Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 18 Jan 2013 02:05:09 +0000
Subject: CHUI-688 FIX Viewer crash when blocked user sends friend request
 Added a check for notification_ptr being null in friendship_offer_callback

---
 indra/newview/llviewermessage.cpp | 132 ++++++++++++++++++++------------------
 1 file changed, 68 insertions(+), 64 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index db81e057de..4bff0222bd 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -189,70 +189,74 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 	const LLSD& payload = notification["payload"];
 	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
 
-	// add friend to recent people list
-	LLRecentPeople::instance().add(payload["from_id"]);
-
-	switch(option)
-	{
-	case 0:
-	{
-		// accept
-		LLAvatarTracker::formFriendship(payload["from_id"]);
-
-		const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
-
-		// This will also trigger an onlinenotification if the user is online
-		msg->newMessageFast(_PREHASH_AcceptFriendship);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
-		msg->nextBlockFast(_PREHASH_FolderData);
-		msg->addUUIDFast(_PREHASH_FolderID, fid);
-		msg->sendReliable(LLHost(payload["sender"].asString()));
-
-		LLSD payload = notification["payload"];
-		LLNotificationsUtil::add("FriendshipAcceptedByMe",
-				notification["substitutions"], payload);
-		break;
-	}
-	case 1: // Decline
-	{
-		LLSD payload = notification["payload"];
-		LLNotificationsUtil::add("FriendshipDeclinedByMe",
-				notification["substitutions"], payload);
-	}
-	// fall-through
-	case 2: // Send IM - decline and start IM session
-		{
-			// decline
-			// We no longer notify other viewers, but we DO still send
-			// the rejection to the simulator to delete the pending userop.
-			msg->newMessageFast(_PREHASH_DeclineFriendship);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			msg->nextBlockFast(_PREHASH_TransactionBlock);
-			msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
-			msg->sendReliable(LLHost(payload["sender"].asString()));
-
-			// start IM session
-			if(2 == option)
-			{
-				LLAvatarActions::startIM(payload["from_id"].asUUID());
-			}
-	}
-	default:
-		// close button probably, possibly timed out
-		break;
-	}
-
-	LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
-	modified_form->setElementEnabled("Accept", false);
-	modified_form->setElementEnabled("Decline", false);
-	notification_ptr->updateForm(modified_form);
-	notification_ptr->repost();
+    // this will be skipped if the user offering friendship is blocked
+    if (notification_ptr)
+    {
+	    // add friend to recent people list
+	    LLRecentPeople::instance().add(payload["from_id"]);
+
+	    switch(option)
+	    {
+	    case 0:
+	    {
+		    // accept
+		    LLAvatarTracker::formFriendship(payload["from_id"]);
+
+		    const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+		    // This will also trigger an onlinenotification if the user is online
+		    msg->newMessageFast(_PREHASH_AcceptFriendship);
+		    msg->nextBlockFast(_PREHASH_AgentData);
+		    msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		    msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		    msg->nextBlockFast(_PREHASH_TransactionBlock);
+		    msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+		    msg->nextBlockFast(_PREHASH_FolderData);
+		    msg->addUUIDFast(_PREHASH_FolderID, fid);
+		    msg->sendReliable(LLHost(payload["sender"].asString()));
+
+		    LLSD payload = notification["payload"];
+		    LLNotificationsUtil::add("FriendshipAcceptedByMe",
+				    notification["substitutions"], payload);
+		    break;
+	    }
+	    case 1: // Decline
+	    {
+		    LLSD payload = notification["payload"];
+		    LLNotificationsUtil::add("FriendshipDeclinedByMe",
+				    notification["substitutions"], payload);
+	    }
+	    // fall-through
+	    case 2: // Send IM - decline and start IM session
+		    {
+			    // decline
+			    // We no longer notify other viewers, but we DO still send
+			    // the rejection to the simulator to delete the pending userop.
+			    msg->newMessageFast(_PREHASH_DeclineFriendship);
+			    msg->nextBlockFast(_PREHASH_AgentData);
+			    msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			    msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			    msg->nextBlockFast(_PREHASH_TransactionBlock);
+			    msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+			    msg->sendReliable(LLHost(payload["sender"].asString()));
+
+			    // start IM session
+			    if(2 == option)
+			    {
+				    LLAvatarActions::startIM(payload["from_id"].asUUID());
+			    }
+	    }
+	    default:
+		    // close button probably, possibly timed out
+		    break;
+	    }
+
+	    LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+	    modified_form->setElementEnabled("Accept", false);
+	    modified_form->setElementEnabled("Decline", false);
+	    notification_ptr->updateForm(modified_form);
+	    notification_ptr->repost();
+    }
 
 	return false;
 }
-- 
cgit v1.2.3


From 5eef65e99476b716985eeccfbbcdafdfb664cb1a Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Fri, 18 Jan 2013 03:52:42 +0200
Subject: CHUI-379 FIXED Restore Voice Morphing menu

---
 indra/llui/llmenugl.cpp                            |  53 ++++++++++-
 indra/llui/llmenugl.h                              |   6 ++
 indra/newview/llviewermenu.cpp                     |  16 +++-
 indra/newview/llvoicevivox.cpp                     | 100 +++++++++++++++++++++
 indra/newview/llvoicevivox.h                       |   3 +
 .../skins/default/xui/en/floater_voice_effect.xml  |   3 +-
 indra/newview/skins/default/xui/en/menu_viewer.xml |  39 +++++---
 7 files changed, 207 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 7dcc39950b..2ea25648df 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -2461,6 +2461,56 @@ void LLMenuGL::empty( void )
 	deleteAllChildren();
 }
 
+// erase group of items from menu
+void LLMenuGL::erase( S32 begin, S32 end, bool arrange/* = true*/)
+{
+	S32 items = mItems.size();
+
+	if ( items == 0 || begin >= end || begin < 0 || end > items )
+	{
+		return;
+	}
+
+	item_list_t::const_iterator start_position = mItems.begin();
+	std::advance(start_position, begin);
+
+	item_list_t::const_iterator end_position = mItems.begin();
+	std::advance(end_position, end);
+
+	for (item_list_t::const_iterator position_iter = start_position; position_iter != end_position; position_iter++)
+	{
+		LLUICtrl::removeChild(*position_iter);
+	}
+
+	mItems.erase(start_position, end_position);
+
+	if (arrange)
+	{
+		needsArrange();
+	}
+}
+
+// add new item at position
+void LLMenuGL::insert( S32 position, LLView * ctrl, bool arrange /*= true*/ )
+{
+	LLMenuItemGL * item = dynamic_cast<LLMenuItemGL *>(ctrl);
+
+	if (NULL == item || position < 0 || position >= mItems.size())
+	{
+		return;
+	}
+
+	item_list_t::const_iterator position_iter = mItems.begin();
+	std::advance(position_iter, position);
+	mItems.insert(position_iter, item);
+	LLUICtrl::addChild(item);
+
+	if (arrange)
+	{
+		needsArrange();
+	}
+}
+
 // Adjust rectangle of the menu
 void LLMenuGL::setLeftAndBottom(S32 left, S32 bottom)
 {
@@ -2502,7 +2552,8 @@ BOOL LLMenuGL::append( LLMenuItemGL* item )
 // add a separator to this menu
 BOOL LLMenuGL::addSeparator()
 {
-	LLMenuItemGL* separator = new LLMenuItemSeparatorGL();
+	LLMenuItemSeparatorGL::Params p;
+	LLMenuItemGL* separator = LLUICtrlFactory::create<LLMenuItemSeparatorGL>(p);
 	return addChild(separator);
 }
 
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 3e03232e92..c57e0f0267 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -478,6 +478,12 @@ public:
 	// remove all items on the menu
 	void empty( void );
 
+	// erase group of items from menu
+	void erase( S32 begin, S32 end, bool arrange = true );
+
+	// add new item at position
+	void insert( S32 begin, LLView * ctrl, bool arrange = true );
+
 	void			setItemLastSelected(LLMenuItemGL* item);	// must be in menu
 	U32				getItemCount();				// number of menu items
 	LLMenuItemGL*	getItem(S32 number);		// 0 = first item
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index a0aa639ac6..8b45c44ed0 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -108,6 +108,7 @@
 #include "llviewerparcelmgr.h"
 #include "llviewerstats.h"
 #include "llvoavatarself.h"
+#include "llvoicevivox.h"
 #include "llworldmap.h"
 #include "pipeline.h"
 #include "llviewerjoystick.h"
@@ -8152,6 +8153,11 @@ public:
 	}
 };
 
+void handle_voice_morphing_subscribe()
+{
+	LLWeb::loadURLExternal(LLTrans::getString("voice_morphing_url"));
+}
+
 class LLToggleUIHints : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -8337,7 +8343,15 @@ void initialize_menus()
 	
 	// Me > Movement
 	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
-	
+
+	// Communicate > Voice morphing > Subscribe...
+	commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
+	LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance();
+	enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check"
+		, boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));
+	commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click"
+		, boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing"));
+
 	// World menu
 	view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
 	view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 5e121bbcee..f3342b7ff1 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -34,6 +34,7 @@
 #include "llvoavatarself.h"
 #include "llbufferstream.h"
 #include "llfile.h"
+#include "llmenugl.h"
 #ifdef LL_STANDALONE
 # include "expat.h"
 #else
@@ -70,6 +71,9 @@
 
 #define USE_SESSION_GROUPS 0
 
+extern LLMenuBarGL* gMenuBarView;
+extern void handle_voice_morphing_subscribe();
+
 const F32 VOLUME_SCALE_VIVOX = 0.01f;
 
 const F32 SPEAKING_TIMEOUT = 1.f;
@@ -6739,10 +6743,106 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceEffectObserver* observer)
 	mVoiceFontObservers.erase(observer);
 }
 
+// method checks the item in VoiceMorphing menu for appropriate current voice font
+bool LLVivoxVoiceClient::onCheckVoiceEffect(const std::string& voice_effect_name)
+{
+	LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+	if (NULL != effect_interfacep)
+	{
+		const LLUUID& currect_voice_effect_id = effect_interfacep->getVoiceEffect();
+
+		if (currect_voice_effect_id.isNull())
+		{
+			if (voice_effect_name == "NoVoiceMorphing")
+			{
+				return true;
+			}
+		}
+		else
+		{
+			const LLSD& voice_effect_props = effect_interfacep->getVoiceEffectProperties(currect_voice_effect_id);
+			if (voice_effect_props["name"].asString() == voice_effect_name)
+			{
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+// method changes voice font for selected VoiceMorphing menu item
+void LLVivoxVoiceClient::onClickVoiceEffect(const std::string& voice_effect_name)
+{
+	LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+	if (NULL != effect_interfacep)
+	{
+		if (voice_effect_name == "NoVoiceMorphing")
+		{
+			effect_interfacep->setVoiceEffect(LLUUID());
+			return;
+		}
+		const voice_effect_list_t& effect_list = effect_interfacep->getVoiceEffectList();
+		if (!effect_list.empty())
+		{
+			for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it)
+			{
+				if (voice_effect_name == it->first)
+				{
+					effect_interfacep->setVoiceEffect(it->second);
+					return;
+				}
+			}
+		}
+	}
+}
+
+// it updates VoiceMorphing menu items in accordance with purchased properties 
+void LLVivoxVoiceClient::updateVoiceMorphingMenu()
+{
+	if (mVoiceFontListDirty)
+	{
+		LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+		if (effect_interfacep)
+		{
+			const voice_effect_list_t& effect_list = effect_interfacep->getVoiceEffectList();
+			if (!effect_list.empty())
+			{
+				LLMenuGL * voice_morphing_menup = gMenuBarView->findChildMenuByName("VoiceMorphing", TRUE);
+
+				if (NULL != voice_morphing_menup)
+				{
+					S32 items = voice_morphing_menup->getItemCount();
+					if (items > 0)
+					{
+						voice_morphing_menup->erase(1, items - 3, false);
+
+						S32 pos = 1;
+						for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it)
+						{
+							LLMenuItemCheckGL::Params p;
+							p.name = it->first;
+							p.label = it->first;
+							p.on_check.function(boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, this, it->first));
+							p.on_click.function(boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, this, it->first));
+							LLMenuItemCheckGL * voice_effect_itemp = LLUICtrlFactory::create<LLMenuItemCheckGL>(p);
+							voice_morphing_menup->insert(pos++, voice_effect_itemp, false);
+						}
+
+						voice_morphing_menup->needsArrange();
+					}
+				}
+			}
+		}
+	}
+}
+
 void LLVivoxVoiceClient::notifyVoiceFontObservers()
 {
 	LL_DEBUGS("Voice") << "Notifying voice effect observers. Lists changed: " << mVoiceFontListDirty << LL_ENDL;
 
+	updateVoiceMorphingMenu();
+
 	for (voice_font_observer_set_t::iterator it = mVoiceFontObservers.begin();
 		 it != mVoiceFontObservers.end();
 		 )
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 69f33df94b..574027de42 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -246,6 +246,8 @@ public:
 
 	//@}
 
+	bool onCheckVoiceEffect(const std::string& voice_effect_name);
+	void onClickVoiceEffect(const std::string& voice_effect_name);
 
 protected:
 	//////////////////////
@@ -854,6 +856,7 @@ private:
 	void accountGetTemplateFontsSendMessage();
 	void sessionSetVoiceFontSendMessage(sessionState *session);
 
+	void updateVoiceMorphingMenu();
 	void notifyVoiceFontObservers();
 
 	typedef enum e_voice_font_type
diff --git a/indra/newview/skins/default/xui/en/floater_voice_effect.xml b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
index 35cb2670d0..146c3d7e30 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
@@ -5,12 +5,13 @@
  height="500"
  name="voice_effects"
  help_topic="voice_effects"
- title="VOICE MORPHING"
+ title="VOICE MORPHING PREVIEW"
  background_visible="true"
  label="Places"
  layout="topleft"
  min_height="360"
  min_width="200"
+ save_rect="true"
  width="300">
   <string name="no_voice_effect">
     (No Voice Morph)
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 8d5e3f0b5d..10fd8138d2 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -268,17 +268,36 @@
              parameter="conversation" />
         </menu_item_check>
         <menu_item_separator/>
-        <menu_item_check
-         label="Voice morphing..."
-         name="ShowVoice"
+        <menu
+         label="Voice morphing"
+         name="VoiceMorphing"
          visibility_control="VoiceMorphingEnabled">
-            <menu_item_check.on_check
-             function="Floater.Visible"
-             parameter="voice_effect" />
-            <menu_item_check.on_click
-             function="Floater.Toggle"
-             parameter="voice_effect" />
-        </menu_item_check>
+            <menu_item_check
+             label="No voice morphing"
+             name="NoVoiceMorphing">
+                <menu_item_check.on_check
+                 function="Communicate.VoiceMorphing.NoVoiceMorphing.Check" />
+                <menu_item_check.on_click
+                 function="Communicate.VoiceMorphing.NoVoiceMorphing.Click" />
+            </menu_item_check>
+            <menu_item_separator/>
+            <menu_item_check
+             label="Preview..."
+             name="Preview">
+                <menu_item_check.on_check
+                 function="Floater.Visible"
+                 parameter="voice_effect" />
+                <menu_item_check.on_click
+                 function="Floater.Toggle"
+                 parameter="voice_effect" />
+            </menu_item_check>
+            <menu_item_call
+             label="Subscribe..."
+             name="Subscribe">
+                <menu_item_call.on_click
+                 function="Communicate.VoiceMorphing.Subscribe" />
+            </menu_item_call>
+        </menu>
         <menu_item_check
          label="Gestures..."
          name="Gestures"
-- 
cgit v1.2.3


From 52018b79bdd715dbb7bd42792447566347b641d5 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Sun, 20 Jan 2013 14:16:53 -0800
Subject: CHUI-379 : Fix Mac and Linux build failures

---
 indra/llui/llmenugl.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 2ea25648df..27f6ac5b80 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -2471,13 +2471,13 @@ void LLMenuGL::erase( S32 begin, S32 end, bool arrange/* = true*/)
 		return;
 	}
 
-	item_list_t::const_iterator start_position = mItems.begin();
+	item_list_t::iterator start_position = mItems.begin();
 	std::advance(start_position, begin);
 
-	item_list_t::const_iterator end_position = mItems.begin();
+	item_list_t::iterator end_position = mItems.begin();
 	std::advance(end_position, end);
 
-	for (item_list_t::const_iterator position_iter = start_position; position_iter != end_position; position_iter++)
+	for (item_list_t::iterator position_iter = start_position; position_iter != end_position; position_iter++)
 	{
 		LLUICtrl::removeChild(*position_iter);
 	}
@@ -2500,7 +2500,7 @@ void LLMenuGL::insert( S32 position, LLView * ctrl, bool arrange /*= true*/ )
 		return;
 	}
 
-	item_list_t::const_iterator position_iter = mItems.begin();
+	item_list_t::iterator position_iter = mItems.begin();
 	std::advance(position_iter, position);
 	mItems.insert(position_iter, item);
 	LLUICtrl::addChild(item);
-- 
cgit v1.2.3


From 824457f98c93a2f48f402740982a410b9fbc3487 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Mon, 21 Jan 2013 14:10:12 +0200
Subject: CHUI-567 FIXED Menu items are moved to Participant view menu

---
 indra/newview/llfloaterimcontainer.cpp              | 13 ++++++++++++-
 indra/newview/llfloaterimsessiontab.cpp             | 21 ---------------------
 indra/newview/llfloaterimsessiontab.h               |  4 ----
 .../default/xui/en/menu_im_session_showmodes.xml    | 19 +------------------
 .../skins/default/xui/en/menu_participant_view.xml  | 20 ++++++++++++++++++++
 5 files changed, 33 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 8f290ae7c1..f73db6b166 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -813,6 +813,10 @@ void LLFloaterIMContainer::onCustomAction(const LLSD& userdata)
 			floater_prefp->selectPrivacyPanel();
 		}
 	}
+	if ("Translating.Toggle" == command)
+	{
+		gSavedSettings.setBOOL("TranslateChat", !gSavedSettings.getBOOL("TranslateChat"));
+	}
 }
 
 BOOL LLFloaterIMContainer::isActionChecked(const LLSD& userdata)
@@ -843,7 +847,14 @@ BOOL LLFloaterIMContainer::isActionChecked(const LLSD& userdata)
 	{
 		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE);
 	}
-	
+	if ("Translating.Enabled" == command)
+	{
+		return gSavedPerAccountSettings.getBOOL("TranslatingEnabled");
+	}
+	if ("Translating.On" == command)
+	{
+		return gSavedSettings.getBOOL("TranslateChat");
+	}
 	return FALSE;
 }
 
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index bc5b8c334d..0cdfde3975 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -72,12 +72,6 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck,   this, _2));
 	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
 			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable,  this, _2));
-	mEnableCallbackRegistrar.add("Translating.Enabled",
-				boost::bind(&LLFloaterIMSessionTab::isTranslatingEnabled,  this, _2));
-	mEnableCallbackRegistrar.add("Translating.On",
-					boost::bind(&LLFloaterIMSessionTab::isTranslationOn,  this, _2));
-	mCommitCallbackRegistrar.add("Translating.Toggle",
-				boost::bind(&LLFloaterIMSessionTab::toggleTranslation,  this, _2));
 
 	// Right click menu handling
     mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem,	this, _2));
@@ -551,11 +545,6 @@ void LLFloaterIMSessionTab::onIMSessionMenuItemClicked(const LLSD& userdata)
 	LLFloaterIMSessionTab::processChatHistoryStyleUpdate();
 }
 
-void LLFloaterIMSessionTab::toggleTranslation(const LLSD& userdata)
-{
-	gSavedSettings.setBOOL("TranslateChat", !gSavedSettings.getBOOL("TranslateChat"));
-}
-
 bool LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
 {
 	std::string item = userdata.asString();
@@ -579,16 +568,6 @@ bool LLFloaterIMSessionTab::onIMShowModesMenuItemEnable(const LLSD& userdata)
 	return (plain_text && (is_not_names || mIsP2PChat));
 }
 
-bool LLFloaterIMSessionTab::isTranslatingEnabled(const LLSD& userdata)
-{
-	return gSavedPerAccountSettings.getBOOL("TranslatingEnabled");
-}
-
-bool LLFloaterIMSessionTab::isTranslationOn(const LLSD& userdata)
-{
-	return gSavedSettings.getBOOL("TranslateChat");
-}
-
 void LLFloaterIMSessionTab::hideOrShowTitle()
 {
 	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 05da0f98bc..0fa99a46be 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -109,12 +109,8 @@ protected:
 	//
 	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
-	bool isTranslatingEnabled(const LLSD& userdata);
-	bool isTranslationOn(const LLSD& userdata);
 	static void onSlide(LLFloaterIMSessionTab *self);
 
-	void toggleTranslation(const LLSD& userdata);
-
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
 
diff --git a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
index f2a8b39b04..b0adca0e0e 100644
--- a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
+++ b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
@@ -45,22 +45,5 @@
         <menu_item_check.on_enable
          function="IMSession.Menu.ShowModes.Enable"
          parameter="IMShowNamesForP2PConv" />    
-    </menu_item_check>
-    <menu_item_separator layout="topleft" />
-    <menu_item_check name="Translate_chat" label="Translate chat">
-        <menu_item_check.on_click
-         function="Translating.Toggle" />
-        <menu_item_check.on_check
-         function="Translating.On" />
-        <menu_item_check.on_enable
-         function="Translating.Enabled" />
-    </menu_item_check>
-    <menu_item_check name="Translation_settings" label="Translation settings...">
-    <menu_item_check.on_check
-         function="Floater.Visible"
-         parameter="prefs_translation" />
-        <menu_item_check.on_click
-         function="Floater.Toggle"
-         parameter="prefs_translation" />
-    </menu_item_check>     
+    </menu_item_check>      
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index 2f2bafb95d..7ea87ee05c 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -89,4 +89,24 @@
          function="Avatar.EnableItem"
          parameter="conversation_log" />
     </menu_item_check>
+    <menu_item_separator layout="topleft" />
+    <menu_item_check name="Translate_chat" label="Translate Nearby chat">
+        <menu_item_check.on_click
+         function="IMFloaterContainer.Action" 
+         parameter="Translating.Toggle" />
+        <menu_item_check.on_check
+         function="IMFloaterContainer.Check" 
+         parameter="Translating.On" />
+        <menu_item_check.on_enable
+         function="IMFloaterContainer.Check" 
+         parameter="Translating.Enabled" />
+    </menu_item_check>
+    <menu_item_check name="Translation_settings" label="Translation settings...">
+    <menu_item_check.on_check
+         function="Floater.Visible"
+         parameter="prefs_translation" />
+        <menu_item_check.on_click
+         function="Floater.Toggle"
+         parameter="prefs_translation" />
+    </menu_item_check>
 </toggleable_menu>
-- 
cgit v1.2.3


From dc19930f1586dcc879a8e9c1653be8f1b47e4795 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 21 Jan 2013 18:24:59 +0200
Subject: CHUI-655, CHUI-648 ADD FIX Conversation is not opened while first
 click on message from object; "Nearby Chat" dialog does not open while first
 attempt when pressing Ctrl+H keyboard shortcut : Fixed forced change
 visibility.

---
 indra/newview/llfloaterimcontainer.cpp  |  4 +++-
 indra/newview/llfloaterimsessiontab.cpp | 11 +++++++----
 indra/newview/llfloaterimsessiontab.h   |  1 +
 3 files changed, 11 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index f73db6b166..565063a0ea 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -431,7 +431,9 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 		return false;
 	}
 	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
-    LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id)));
+    LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ?
+    		(LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))
+    		: (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id)));
 
 	if (type == "remove_participant")
 	{
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 0cdfde3975..37404ab716 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -60,6 +60,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
   , mInputEditorTopPad(0)
   , mRefreshTimer(new LLTimer())
   , mIsHostAttached(false)
+  , mHasVisibleBeenInitialized(false)
 {
     setAutoFocus(FALSE);
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
@@ -120,12 +121,14 @@ LLFloaterIMSessionTab* LLFloaterIMSessionTab::getConversation(const LLUUID& uuid
 
 void LLFloaterIMSessionTab::setVisible(BOOL visible)
 {
-	LLTransientDockableFloater::setVisible(visible);
-
-	if(visible)
+	if(visible && !mHasVisibleBeenInitialized)
 	{
-			LLFloaterIMSessionTab::addToHost(mSessionID);
+		mHasVisibleBeenInitialized = true;
+		LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);
+		LLFloaterIMSessionTab::addToHost(mSessionID);
 	}
+
+	LLTransientDockableFloater::setVisible(visible);
 }
 
 /*virtual*/
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 0fa99a46be..beaffc14a6 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -182,6 +182,7 @@ private:
 
 	bool checkIfTornOff();
     bool mIsHostAttached;
+    bool mHasVisibleBeenInitialized;
 
 	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
 };
-- 
cgit v1.2.3


From 9e6677ffc29b779f7b47228cf96c5bcdc867669c Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Tue, 22 Jan 2013 17:53:18 +0200
Subject: CHUI-692 FIXED Arrow keys will move avatar while IM container, nearby
 chat or IM session floater is in focus.

---
 indra/newview/llviewerwindow.cpp | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 2d5634a41d..36ddf26c82 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2503,22 +2503,14 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		return TRUE;
 	}
 
-	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	LLFloater* focused_floaterp = gFloaterView->getFocusedFloater();
+	std::string focusedFloaterName = (focused_floaterp ? focused_floaterp->getInstanceName() : "");
 
-	// Traverses up the hierarchy
 	if( keyboard_focus )
 	{
-		if (nearby_chat)
-		{
-			LLChatEntry* chat_editor = nearby_chat->getChatBox();
-		
-		// arrow keys move avatar while chatting hack
-		if (chat_editor && chat_editor->hasFocus())
+		if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel"))
 		{
-			// If text field is empty, there's no point in trying to move
-			// cursor with arrow keys, so allow movement
-			if (chat_editor->getText().empty() 
-				|| gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
+			if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
 			{
 				// let Control-Up and Control-Down through for chat line history,
 				if (!(key == KEY_UP && mask == MASK_CONTROL)
@@ -2540,7 +2532,6 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 						break;
 					}
 				}
-			}
 		}
 		}
 
@@ -2575,6 +2566,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
 		// Initialize nearby chat if it's missing
+		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 		if (!nearby_chat)
 		{	
 			LLSD name("im_container");
-- 
cgit v1.2.3


From 651f230500646dfcd695a9caa0650f81fa29b9bf Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Wed, 23 Jan 2013 10:23:16 +0200
Subject: CHUI-678 (Voice indicators not shown for participants in torn off
 conference conversations)

---
 indra/newview/llconversationview.cpp         | 32 ++++++++++++++++++++++++++--
 indra/newview/llconversationview.h           |  4 ++++
 indra/newview/llspeakingindicatormanager.cpp | 13 ++---------
 3 files changed, 36 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 903dd2a407..bdd5dfc51a 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -82,6 +82,7 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mVoiceClientObserver(NULL),
 	mCollapsedMode(false),
     mHasArrow(true),
+	mIsInActiveVoiceChannel(false),
 	mFlashStateOn(false),
 	mFlashStarted(false)
 {
@@ -178,6 +179,7 @@ BOOL LLConversationViewSession::postBuild()
 			LLIconCtrl* icon = mItemPanel->getChild<LLIconCtrl>("nearby_chat_icon");
 			icon->setVisible(true);
 			mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true);
+			mIsInActiveVoiceChannel = true;
 			if(LLVoiceClient::instanceExists())
 			{
 				LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
@@ -232,6 +234,8 @@ void LLConversationViewSession::draw()
 		(*iit)->setVisible(draw_children);
 	}
 
+	refresh();
+
 	LLView::draw();
 }
 
@@ -351,6 +355,25 @@ void LLConversationViewSession::refresh()
 
 	// Update all speaking indicators
 	LLSpeakingIndicatorManager::updateSpeakingIndicators();
+
+	// we should show indicator for specified voice session only if this is current channel. EXT-5562.
+	if (!mIsInActiveVoiceChannel)
+	{
+		if (mSpeakingIndicator)
+		{
+			mSpeakingIndicator->setVisible(false);
+		}
+		LLConversationViewParticipant* participant = NULL;
+		items_t::const_iterator iter;
+		for (iter = getItemsBegin(); iter != getItemsEnd(); iter++)
+		{
+			participant = dynamic_cast<LLConversationViewParticipant*>(*iter);
+			if (participant)
+			{
+				participant->hideSpeakingIndicator();
+			}
+		}
+	}
 	
 	// Do the regular upstream refresh
 	LLFolderViewFolder::refresh();
@@ -362,8 +385,8 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
 
 	if (vmi)
 	{
-		bool is_active = vmi->getUUID() == session_id;
-		mCallIconLayoutPanel->setVisible(is_active);
+		mIsInActiveVoiceChannel = vmi->getUUID() == session_id;
+		mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel);
 	}
 }
 
@@ -623,5 +646,10 @@ LLView* LLConversationViewParticipant::getItemChildView(EAvatarListItemChildInde
     return child_view;
 }
 
+void LLConversationViewParticipant::hideSpeakingIndicator()
+{
+	mSpeakingIndicator->setVisible(false);
+}
+
 // EOF
 
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 5f6acfb9ab..f2fa2fb042 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -102,6 +102,8 @@ private:
 	bool					mCollapsedMode;
     bool                    mHasArrow;
 
+	bool					mIsInActiveVoiceChannel;
+
 	LLVoiceClientStatusObserver* mVoiceClientObserver;
 	
 	boost::signals2::connection mActiveVoiceChannelConnection;
@@ -137,6 +139,8 @@ public:
 
     /*virtual*/ S32 getLabelXPos();
 
+	void hideSpeakingIndicator();
+
 protected:
 	friend class LLUICtrlFactory;
 	LLConversationViewParticipant( const Params& p );
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 76da7d1aee..07e9371124 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -237,18 +237,9 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea
 		{
 			was_found = true;
 			LLSpeakingIndicator* indicator = (*it_indicator).second;
+			was_switched_on = was_switched_on || switch_on;
 
-			BOOL switch_current_on = switch_on;
-
-			// we should show indicator for specified voice session only if this is current channel. EXT-5562.
-			if (switch_current_on)
-			{
-				switch_current_on = indicator->getTargetSessionID() == session_id;
-				LL_DEBUGS("SpeakingIndicator") << "Session: " << session_id << ", target: " << indicator->getTargetSessionID() << ", the same? = " << switch_current_on << LL_ENDL;
-			}
-			was_switched_on = was_switched_on || switch_current_on;
-
-			indicator->switchIndicator(switch_current_on);
+			indicator->switchIndicator(switch_on);
 		}
 
 		if (was_found)
-- 
cgit v1.2.3


From e6000d5930dd646bb15951336670bab4950515d8 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Wed, 23 Jan 2013 14:32:18 +0200
Subject: CHUI-424 FIXED Args for appendMessage() are added to respect
 Compact/Expanded mode

---
 indra/newview/llfloaterconversationpreview.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index c93181c0a1..48e0caa0ce 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -152,7 +152,13 @@ void LLFloaterConversationPreview::showHistory()
 			chat.mSourceType = LLFloaterIMNearbyChat::isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
 		}
 
-		mChatHistory->appendMessage(chat);
+		LLSD chat_args;
+		chat_args["use_plain_text_chat_history"] =
+						gSavedSettings.getBOOL("PlainTextChatHistory");
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] = gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+
+		mChatHistory->appendMessage(chat,chat_args);
 	}
 
 }
-- 
cgit v1.2.3


From d0204ab367f5ceb5eab89e2273b897975acbfe5a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 23 Jan 2013 09:51:17 -0800
Subject: CHUI-687: Problem: User sees inventory offer notifications for
 deleted items when logging in from do not disturb mode. Resolution: If an
 item that is deletes has a DND notification saved, then remove that
 notification so that it doesn't appear onec the user exists DND mode.

---
 indra/llui/llfolderview.cpp                        |  6 +++++-
 indra/llui/llfolderview.h                          |  3 ++-
 .../newview/lldonotdisturbnotificationstorage.cpp  | 22 +++++++++++++---------
 indra/newview/lldonotdisturbnotificationstorage.h  |  6 +++++-
 indra/newview/llfloaterimcontainer.cpp             |  2 +-
 indra/newview/llimview.cpp                         |  2 +-
 indra/newview/llinventoryfunctions.cpp             | 22 ++++++++++++++++++++++
 indra/newview/llinventoryfunctions.h               |  1 +
 8 files changed, 50 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 324142f6c3..7c1ca017d7 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -399,6 +399,10 @@ LLFolderViewItem* LLFolderView::getCurSelectedItem( void )
 	return NULL;
 }
 
+LLFolderView::selected_items_t& LLFolderView::getSelectedItems( void )
+{
+    return mSelectedItems;
+}
 
 // Record the selected item and pass it down the hierachy.
 BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
@@ -752,8 +756,8 @@ void LLFolderView::removeSelectedItems()
 				{
 					// change selection on successful delete
 					setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
-					}
 				}
+			}
 			arrangeAll();
 		}
 		else if (count > 1)
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index a6e0a3b4c0..05b2abb9d3 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -101,6 +101,7 @@ public:
 	};
 
 	friend class LLFolderViewScrollContainer;
+    typedef std::deque<LLFolderViewItem*> selected_items_t;
 
 	LLFolderView(const Params&);
 	virtual ~LLFolderView( void );
@@ -138,6 +139,7 @@ public:
 
 	// Get the last selected item
 	virtual LLFolderViewItem* getCurSelectedItem( void );
+    selected_items_t& getSelectedItems( void );
 
 	// Record the selected item and pass it down the hierarchy.
 	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
@@ -261,7 +263,6 @@ protected:
 protected:
 	LLHandle<LLView>					mPopupMenuHandle;
 	
-	typedef std::deque<LLFolderViewItem*> selected_items_t;
 	selected_items_t				mSelectedItems;
 	BOOL							mKeyboardSelection;
 	BOOL							mAllowMultiSelect;
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 824ff67972..abceb5c10d 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -43,7 +43,8 @@
 #include "lluuid.h"
 
 static const F32 DND_TIMER = 3.0;
-const std::string toastName = "IMToast";
+const char * LLDoNotDisturbNotificationStorage::toastName = "IMToast";
+const char * LLDoNotDisturbNotificationStorage::offerName = "UserGiveItem";
 
 LLDoNotDisturbNotificationStorageTimer::LLDoNotDisturbNotificationStorageTimer() : LLEventTimer(DND_TIMER)
 {
@@ -72,6 +73,8 @@ LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
 	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
     , mDirty(false)
 {
+    nameToPayloadParameterMap[toastName] = "SESSION_ID";
+    nameToPayloadParameterMap[offerName] = "object_id";
 }
 
 LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
@@ -234,15 +237,16 @@ LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChan
 	return channelPtr;
 }
 
-void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& session_id)
+void LLDoNotDisturbNotificationStorage::removeNotification(const char * name, const LLUUID& id)
 {
     LLNotifications& instance = LLNotifications::instance();
     LLNotificationChannelPtr channelPtr = getCommunicationChannel();
     LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
     LLNotificationPtr notification;
-    LLSD substitutions;
-    LLUUID notificationSessionID;
+    LLSD payload;
+    LLUUID notificationObjectID;
     std::string notificationName;
+    std::string payloadVariable = nameToPayloadParameterMap[name];
     LLCommunicationChannel::history_list_t::iterator it;
     std::vector<LLCommunicationChannel::history_list_t::iterator> itemsToRemove;
 
@@ -252,18 +256,18 @@ void LLDoNotDisturbNotificationStorage::removeIMNotification(const LLUUID& sessi
         ++it)
     {
         notification = it->second;
-        substitutions = notification->getSubstitutions();
-        notificationSessionID = substitutions["SESSION_ID"].asUUID();
+        payload = notification->getPayload();
+        notificationObjectID = payload[payloadVariable].asUUID();
         notificationName = notification->getName();
 
-        if(notificationName == toastName
-            && session_id == notificationSessionID)
+        if(notificationName == name
+            && id == notificationObjectID)
         {
             itemsToRemove.push_back(it);
         }
     }
 
-   
+
     //Remove the notifications
     if(itemsToRemove.size())
     {
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index fd7cc7ee82..6e68b0d1be 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -49,6 +49,9 @@ class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotif
 {
 	LOG_CLASS(LLDoNotDisturbNotificationStorage);
 public:
+    static const char * toastName;
+    static const char * offerName;
+
 	LLDoNotDisturbNotificationStorage();
 	~LLDoNotDisturbNotificationStorage();
 
@@ -58,7 +61,7 @@ public:
 	void saveNotifications();
 	void loadNotifications();
     void updateNotifications();
-    void removeIMNotification(const LLUUID& session_id);
+    void removeNotification(const char * name, const LLUUID& id);
 
 protected:
 
@@ -68,6 +71,7 @@ private:
 
 	LLNotificationChannelPtr getCommunicationChannel() const;
 	bool                     onChannelChanged(const LLSD& pPayload);
+    std::map<std::string, std::string> nameToPayloadParameterMap;
 };
 
 #endif // LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index f73db6b166..6e9f7a380f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1316,7 +1316,7 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
         //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
         if(gAgent.isDoNotDisturb() && session_id.notNull())
         {
-            LLDoNotDisturbNotificationStorage::getInstance()->removeIMNotification(session_id);
+            LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, session_id);
         }
     }
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d0a8dfc0c8..cb03c1d234 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -144,7 +144,7 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	args["FROM"] = av_name.getCompleteName();
 	args["FROM_ID"] = msg["from_id"];
 	args["SESSION_ID"] = msg["session_id"];
-	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
+	LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
 void on_new_message(const LLSD& msg)
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 6474d56414..7f9474ae70 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -46,6 +46,7 @@
 #include "llappearancemgr.h"
 #include "llappviewer.h"
 #include "llclipboard.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llfloaterinventory.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfocusmgr.h"
@@ -1132,11 +1133,32 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
 	}
 }
 
+void LLInventoryAction::removeItemFromDND(LLFolderView* root)
+{
+    //Get selected items
+    LLFolderView::selected_items_t selectedItems = root->getSelectedItems();
+    LLFolderViewModelItemInventory * viewModel = NULL;
+
+    //If user is in DND and deletes item, make sure the notification is not displayed by removing the notification
+    //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification.
+    for(LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
+    {
+        viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem());
+
+        if(viewModel && viewModel->getUUID().notNull())
+        {
+            //Will remove the item offer notification
+            LLDoNotDisturbNotificationStorage::instance().removeNotification(LLDoNotDisturbNotificationStorage::offerName, viewModel->getUUID());
+        }
+    }
+}
+
 void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, const LLSD& response, LLFolderView* root )
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	if (option == 0)
 	{
+        removeItemFromDND(root);
 		root->removeSelectedItems();
 	}
 }
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 11fc17ce9b..f1066a4dc9 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -433,6 +433,7 @@ struct LLInventoryAction
 	static void doToSelected(class LLInventoryModel* model, class LLFolderView* root, const std::string& action);
 
 	static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLFolderView* root);
+    static void removeItemFromDND(LLFolderView* root);
 };
 
 
-- 
cgit v1.2.3


From 6bb1c88db2b329665d547eb86d083a062732a8dd Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 23 Jan 2013 10:13:20 -0800
Subject: CHUI-480 : Fixed : Fetch group membership when starting group chat
 and populate speakers list

---
 indra/newview/llspeakers.cpp | 51 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 88f29d7587..a90d9111cb 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -31,6 +31,7 @@
 #include "llagent.h"
 #include "llappviewer.h"
 #include "llimview.h"
+#include "llgroupmgr.h"
 #include "llsdutil.h"
 #include "lluicolortable.h"
 #include "llviewerobjectlist.h"
@@ -321,7 +322,11 @@ LLSpeakerMgr::~LLSpeakerMgr()
 
 LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
 {
-	if (id.isNull()) return NULL;
+	LLUUID session_id = getSessionID();
+	if (id.isNull() || (id == session_id))
+	{
+		return NULL;
+	}
 
 	LLPointer<LLSpeaker> speakerp;
 	if (mSpeakers.find(id) == mSpeakers.end())
@@ -527,22 +532,52 @@ void LLSpeakerMgr::updateSpeakerList()
 		LLUUID session_id = getSessionID();
 		if ((mSpeakers.size() == 0) && (!session_id.isNull()))
 		{
-			// If the list is empty, we update it with whatever was used to initiate the call so that it doesn't stay empty too long.
+			// If the list is empty, we update it with whatever we have locally so that it doesn't stay empty too long.
 			// *TODO: Fix the server side code that sometimes forgets to send back the list of agents after a chat started 
 			// (IOW, fix why we get no ChatterBoxSessionAgentListUpdates message after the initial ChatterBoxSessionStartReply)
 			LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
-			for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
+			if (session->isGroupSessionType())
+			{
+				// For groups, we need to hit the group manager
+				LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id);
+				if (!gdatap)
+				{
+					// Request the data the first time around
+					LLGroupMgr::getInstance()->sendCapGroupMembersRequest(session_id);
+				}
+				else if (gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())
+				{
+					LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin();
+					while (member_it != gdatap->mMembers.end())
+					{
+						LLGroupMemberData* member = member_it->second;
+						// Add only the members who are online
+						if (member->getOnlineStatus() == "Online")
+						{
+							setSpeaker(member_it->first, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+						}
+						++member_it;
+					}
+					// Always add the current agent (it has to be there no matter what...)
+					setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+				}
+			}
+			else
 			{
-				// Add buddies if they are on line, add any other avatar.
-				if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it))
+				// For all other types (ad-hoc, P2P, avaline), we use the initial targets list
+				for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
 				{
-					setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+					// Add buddies if they are on line, add any other avatar.
+					if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it))
+					{
+						setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+					}
 				}
+				// Always add the current agent (it has to be there no matter what...)
+				setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 			}
 		}
 	}
-	// Finally, always add the current agent (it has to be there no matter what...)
-	setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 }
 
 void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
-- 
cgit v1.2.3


From 0911dafd81b8360235eb6f6b85fac7153a5d4a02 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 23 Jan 2013 11:39:33 -0800
Subject: CHUI-687: post code review changes. Now upon deletion of an item, DND
 mode must be enabled in order to remove a notification from the DND history.

---
 .../newview/lldonotdisturbnotificationstorage.cpp  |  2 +-
 indra/newview/llinventoryfunctions.cpp             | 27 +++++++++++++---------
 2 files changed, 17 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index abceb5c10d..15c42e8285 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -260,7 +260,7 @@ void LLDoNotDisturbNotificationStorage::removeNotification(const char * name, co
         notificationObjectID = payload[payloadVariable].asUUID();
         notificationName = notification->getName();
 
-        if(notificationName == name
+        if((notificationName == name)
             && id == notificationObjectID)
         {
             itemsToRemove.push_back(it);
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 7f9474ae70..ad0a730dd1 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1135,20 +1135,23 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
 
 void LLInventoryAction::removeItemFromDND(LLFolderView* root)
 {
-    //Get selected items
-    LLFolderView::selected_items_t selectedItems = root->getSelectedItems();
-    LLFolderViewModelItemInventory * viewModel = NULL;
-
-    //If user is in DND and deletes item, make sure the notification is not displayed by removing the notification
-    //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification.
-    for(LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
+    if(gAgent.isDoNotDisturb())
     {
-        viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem());
+        //Get selected items
+        LLFolderView::selected_items_t selectedItems = root->getSelectedItems();
+        LLFolderViewModelItemInventory * viewModel = NULL;
 
-        if(viewModel && viewModel->getUUID().notNull())
+        //If user is in DND and deletes item, make sure the notification is not displayed by removing the notification
+        //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification.
+        for(LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
         {
-            //Will remove the item offer notification
-            LLDoNotDisturbNotificationStorage::instance().removeNotification(LLDoNotDisturbNotificationStorage::offerName, viewModel->getUUID());
+            viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem());
+
+            if(viewModel && viewModel->getUUID().notNull())
+            {
+                //Will remove the item offer notification
+                LLDoNotDisturbNotificationStorage::instance().removeNotification(LLDoNotDisturbNotificationStorage::offerName, viewModel->getUUID());
+            }
         }
     }
 }
@@ -1158,6 +1161,8 @@ void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, co
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	if (option == 0)
 	{
+        //Need to remove item from DND before item is removed from root folder view
+        //because once removed from root folder view the item is no longer a selected item
         removeItemFromDND(root);
 		root->removeSelectedItems();
 	}
-- 
cgit v1.2.3


From 46a74c4e01e19c07b5ee966ebe9882c4209dc89c Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 23 Jan 2013 17:45:25 -0800
Subject: CHUI-480 : Fixed : Flagged when local update is made and prevent
 doing it multiple times, allow group to graw by 1 (me) then the rest (prevent
 having group remaining hidden).

---
 indra/newview/llspeakers.cpp | 34 +++++++++++++++++++++-------------
 indra/newview/llspeakers.h   |  1 +
 2 files changed, 22 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index a90d9111cb..a2d8874cea 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -306,9 +306,10 @@ private:
 //
 
 LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) : 
-	mVoiceChannel(channelp)
-, mVoiceModerated(false)
-, mModerateModeHandledFirstTime(false)
+	mVoiceChannel(channelp),
+	mVoiceModerated(false),
+	mModerateModeHandledFirstTime(false),
+	mSpeakerListUpdated(false)
 {
 	static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
 
@@ -530,15 +531,16 @@ void LLSpeakerMgr::updateSpeakerList()
 	{
 		// If not, check if the list is empty, except if it's Nearby Chat (session_id NULL).
 		LLUUID session_id = getSessionID();
-		if ((mSpeakers.size() == 0) && (!session_id.isNull()))
+		if (!session_id.isNull() && !mSpeakerListUpdated)
 		{
 			// If the list is empty, we update it with whatever we have locally so that it doesn't stay empty too long.
-			// *TODO: Fix the server side code that sometimes forgets to send back the list of agents after a chat started 
+			// *TODO: Fix the server side code that sometimes forgets to send back the list of participants after a chat started.
 			// (IOW, fix why we get no ChatterBoxSessionAgentListUpdates message after the initial ChatterBoxSessionStartReply)
 			LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
-			if (session->isGroupSessionType())
+			if (session->isGroupSessionType() && (mSpeakers.size() <= 1))
 			{
-				// For groups, we need to hit the group manager
+				// For groups, we need to hit the group manager.
+				// Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail.
 				LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id);
 				if (!gdatap)
 				{
@@ -547,6 +549,7 @@ void LLSpeakerMgr::updateSpeakerList()
 				}
 				else if (gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())
 				{
+					// Add group members when we get the complete list (note: can take a while before we get that list)
 					LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin();
 					while (member_it != gdatap->mMembers.end())
 					{
@@ -558,13 +561,12 @@ void LLSpeakerMgr::updateSpeakerList()
 						}
 						++member_it;
 					}
-					// Always add the current agent (it has to be there no matter what...)
-					setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+					mSpeakerListUpdated = true;
 				}
 			}
-			else
+			else if (mSpeakers.size() == 0)
 			{
-				// For all other types (ad-hoc, P2P, avaline), we use the initial targets list
+				// For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list
 				for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
 				{
 					// Add buddies if they are on line, add any other avatar.
@@ -573,11 +575,17 @@ void LLSpeakerMgr::updateSpeakerList()
 						setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 					}
 				}
-				// Always add the current agent (it has to be there no matter what...)
-				setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+				mSpeakerListUpdated = true;
+			}
+			else
+			{
+				// The list has been updated the normal way (i.e. by a ChatterBoxSessionAgentListUpdates received from the server)
+				mSpeakerListUpdated = true;
 			}
 		}
 	}
+	// Always add the current agent (it has to be there...). Will do nothing if already there.
+	setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 }
 
 void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 7d518fe07b..5f5095097e 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -263,6 +263,7 @@ protected:
 
 	typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
 	speaker_map_t		mSpeakers;
+	bool                mSpeakerListUpdated;
 
 	speaker_list_t		mSpeakersSorted;
 	LLFrameTimer		mSpeechTimer;
-- 
cgit v1.2.3


From a6c4d127dd6ad66f9953344387e100bcff000ce5 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Fri, 25 Jan 2013 14:33:44 +0200
Subject: CHUI-697 FIXED We don't need to update form for Inventory offer
 notification

---
 indra/newview/llviewermessage.cpp | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index d235ba5f96..8489e92d15 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1649,12 +1649,6 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 		delete this;
 	}
 
-	if (notification_ptr != NULL)
-	{
-		notification_ptr->updateForm(modified_form);
-		notification_ptr->repost();
-	}
-
 	return false;
 }
 
-- 
cgit v1.2.3


From daa9db305a5ae2c0c5b0c2425d6482de6dee7b2c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 23 Jan 2013 19:47:01 +0200
Subject: CHUI-695 Viewer crashes after attempt to accept a friendship in IM:
 remove an infinity loop of reshape()

---
 indra/newview/lltoastnotifypanel.cpp | 6 ++----
 indra/newview/lltoastpanel.cpp       | 4 +++-
 2 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 268b68b539..0aab514531 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -537,11 +537,9 @@ LLIMToastNotifyPanel::~LLIMToastNotifyPanel()
 }
 
 void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
-	{
-	LLToastPanel::reshape(width, height, called_from_parent);
-
+{
 	snapToMessageHeight(mTextBox, MAX_LENGTH);
-	}
+}
 
 void LLIMToastNotifyPanel::compactButtons()
 {
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index 187aee207c..54d3912136 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -81,7 +81,9 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 		S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
 
 		heightDelta = newTextHeight - oldTextHeight;
-		S32 new_panel_height = llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT);
+		S32 new_panel_height = llmin(
+				llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT),
+				maxTextHeight);
 
 		//reshape the panel with new height
 		if (new_panel_height != getRect().getHeight())
-- 
cgit v1.2.3


From 977d318ac8ccb756bb90a8572f01bc6825b5d0a3 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Wed, 23 Jan 2013 20:22:28 +0000
Subject: CHUI-291 FIX New auto-replace feature does not work with chui text
 input boxes in conversation floater Moved autoreplace hooks from LLLineEditor
 to LLTextEditor, and modified LLAutoReplace accordingly

---
 indra/llui/lllineeditor.cpp             |  9 +-----
 indra/llui/lllineeditor.h               |  3 --
 indra/llui/lltexteditor.cpp             | 10 ++++++-
 indra/llui/lltexteditor.h               |  5 ++++
 indra/newview/llautoreplace.cpp         | 50 ++++++++++++--------------------
 indra/newview/llautoreplace.h           | 51 +++++++++++++++------------------
 indra/newview/llfloaterimnearbychat.cpp |  2 ++
 indra/newview/llfloaterimsession.cpp    |  6 ----
 8 files changed, 58 insertions(+), 78 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 48d49af588..2e64be89fa 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -157,8 +157,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mHighlightColor(p.highlight_color()),
 	mPreeditBgColor(p.preedit_bg_color()),
 	mGLFont(p.font),
-	mContextMenuHandle(),
-	mAutoreplaceCallback()
+	mContextMenuHandle()
 {
 	llassert( mMaxLengthBytes > 0 );
 
@@ -971,12 +970,6 @@ void LLLineEditor::addChar(const llwchar uni_char)
 		LLUI::reportBadKeystroke();
 	}
 
-	if (!mReadOnly && mAutoreplaceCallback != NULL)
-	{
-		// call callback
-		mAutoreplaceCallback(mText, mCursorPos);
-	}
-
 	getWindow()->hideCursorUntilMouseMove();
 }
 
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 71dd53f608..40f931ecc1 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -189,9 +189,6 @@ public:
 	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
 
-	typedef boost::function<void(LLUIString&, S32&)> autoreplace_callback_t;
-	autoreplace_callback_t mAutoreplaceCallback;
-	void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
 	void			setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
 	const std::string& 	getLabel()	{ return mLabel.getString(); }
 
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index d42d6473ed..d297e54f2f 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -246,7 +246,8 @@ LLTextEditor::Params::Params()
 }
 
 LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
-	LLTextBase(p),
+    LLTextBase(p),
+    mAutoreplaceCallback(),
 	mBaseDocIsPristine(TRUE),
 	mPristineCmd( NULL ),
 	mLastCmd( NULL ),
@@ -1097,7 +1098,14 @@ void LLTextEditor::addChar(llwchar wc)
 	}
 
 	setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
+
+    if (!mReadOnly && mAutoreplaceCallback != NULL)
+    {
+        // call callback
+        mAutoreplaceCallback(getViewModel()->getEditableDisplay(), mCursorPos);
+    }
 }
+
 void LLTextEditor::addLineBreakChar()
 {
 	if( !getEnabled() )
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index f8f636b876..ae5a983b60 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -157,6 +157,11 @@ public:
 	BOOL			isPristine() const;
 	BOOL			allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
 
+    // Autoreplace (formerly part of LLLineEditor)
+    typedef boost::function<void(LLWString&, S32&)> autoreplace_callback_t;
+    autoreplace_callback_t mAutoreplaceCallback;
+    void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
+
 	//
 	// Text manipulation
 	//
diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
index d71cf290d6..94773e312c 100644
--- a/indra/newview/llautoreplace.cpp
+++ b/indra/newview/llautoreplace.cpp
@@ -30,29 +30,17 @@
 #include "llviewercontrol.h"
 #include "llnotificationsutil.h"
 
-LLAutoReplace* LLAutoReplace::sInstance;
-
 const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml";
 
-LLAutoReplace::LLAutoReplace()
-{
-}
-
-LLAutoReplace::~LLAutoReplace()
-{
-	sInstance = NULL;
-}
-
-void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
+void LLAutoReplace::autoreplaceCallback(LLWString& inputText, S32& cursorPos)
 {
 	static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
 	if(perform_autoreplace)
 	{
 		S32 wordEnd = cursorPos-1;
-		LLWString text = inputText.getWString();
 
-		bool atSpace  = (text[wordEnd] == ' ');
-		bool haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+		bool atSpace  = (inputText[wordEnd] == ' ');
+		bool haveWord = (LLWStringUtil::isPartOfWord(inputText[wordEnd]));
 
 		if (atSpace || haveWord)
 		{
@@ -60,7 +48,7 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
 			{
 				// find out if this space immediately follows a word
 				wordEnd--;
-				haveWord  = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+				haveWord  = (LLWStringUtil::isPartOfWord(inputText[wordEnd]));
 			}
 			if (haveWord)
 			{
@@ -68,14 +56,14 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
 				std::string word;
 				S32 wordStart = wordEnd;
 				for ( S32 backOne = wordStart - 1;
-					  backOne >= 0 && LLWStringUtil::isPartOfWord(text[backOne]);
+					  backOne >= 0 && LLWStringUtil::isPartOfWord(inputText[backOne]);
 					  backOne--
 					 )
 				{
 					wordStart--; // walk wordStart back to the beginning of the word
 				}
 				LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL;
-				std::string strText  = std::string(text.begin(), text.end());
+				std::string strText  = std::string(inputText.begin(), inputText.end());
 				std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1);
 				std::string replacementWord( mSettings.replaceWord( lastWord ) );
 
@@ -89,8 +77,7 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
 						LLWString strOld = utf8str_to_wstring(lastWord);
 						int size_change = strNew.size() - strOld.size();
 
-						text.replace(wordStart,lastWord.length(),strNew);
-						inputText = wstring_to_utf8str(text);
+						inputText.replace(wordStart,lastWord.length(),strNew);
 						cursorPos+=size_change;
 					}
 				}
@@ -99,16 +86,6 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
 	}
 }
 
-LLAutoReplace* LLAutoReplace::getInstance()
-{
-	if(!sInstance)
-	{
-		sInstance = new LLAutoReplace();
-		sInstance->loadFromSettings();
-	}
-	return sInstance;
-}
-
 std::string LLAutoReplace::getUserSettingsFileName()
 {
 	std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
@@ -147,6 +124,15 @@ void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings)
 	saveToUserSettings();
 }
 
+LLAutoReplace::LLAutoReplace()
+{
+}
+
+void LLAutoReplace::initSingleton()
+{
+    loadFromSettings();
+}
+
 void LLAutoReplace::loadFromSettings()
 {
 	std::string filename=getUserSettingsFileName();
@@ -220,7 +206,7 @@ void LLAutoReplace::saveToUserSettings()
 	std::string filename=getUserSettingsFileName();
 	llofstream file;
 	file.open(filename.c_str());
-	LLSDSerialize::toPrettyXML(mSettings.getAsLLSD(), file);
+	LLSDSerialize::toPrettyXML(mSettings.asLLSD(), file);
 	file.close();
 	LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL;
 }
@@ -801,7 +787,7 @@ LLSD LLAutoReplaceSettings::getExampleLLSD()
 	return example;
 }
 
-const LLSD& LLAutoReplaceSettings::getAsLLSD()
+const LLSD& LLAutoReplaceSettings::asLLSD()
 {
 	return mLists;
 }
diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h
index f720cc4eda..bbb86294bc 100644
--- a/indra/newview/llautoreplace.h
+++ b/indra/newview/llautoreplace.h
@@ -132,7 +132,7 @@ class LLAutoReplaceSettings
 	LLSD getExampleLLSD();
 
 	/// Get the actual settings as LLSD
-	const LLSD& getAsLLSD();
+	const LLSD& asLLSD();
 	///< @note for use only in AutoReplace::saveToUserSettings
 	
   private:
@@ -190,42 +190,37 @@ class LLAutoReplaceSettings
  */
 class LLAutoReplace : public LLSingleton<LLAutoReplace>
 {
-  public:
-	LLAutoReplace();
-	~LLAutoReplace();
-
-	/// @return a pointer to the active instance
-	static LLAutoReplace* getInstance();
+public:
+    /// Callback that provides the hook for use in text entry methods
+    void autoreplaceCallback(LLWString& inputText, S32& cursorPos);
 
-	/// Callback that provides the hook for use in text entry methods
-	void autoreplaceCallback(LLUIString& inputText, S32& cursorPos);
+    /// Get a copy of the current settings
+    LLAutoReplaceSettings getSettings();
 
-	/// Get a copy of the current settings
-	LLAutoReplaceSettings getSettings();
+    /// Commit new settings after making changes
+    void setSettings(const LLAutoReplaceSettings& settings);
 
-	/// Commit new settings after making changes
-	void setSettings(const LLAutoReplaceSettings& settings);
-
-  private:
-	friend class LLSingleton<LLAutoReplace>;
-	static LLAutoReplace* sInstance; ///< the active settings instance
+private:
+    friend class LLSingleton<LLAutoReplace>;
+    LLAutoReplace();
+    /*virtual*/ void initSingleton();
 
-	LLAutoReplaceSettings mSettings; ///< configuration information
+    LLAutoReplaceSettings mSettings; ///< configuration information
 	
-	/// Read settings from persistent storage
-	void loadFromSettings();
+    /// Read settings from persistent storage
+    void loadFromSettings();
 
-	/// Make the newSettings active and write them to user storage
-	void saveToUserSettings();
+    /// Make the newSettings active and write them to user storage
+    void saveToUserSettings();
 
-	/// Compute the user settings file name
-	std::string getUserSettingsFileName();
+    /// Compute the user settings file name
+    std::string getUserSettingsFileName();
 
-	/// Compute the (read-ony) application settings file name
-	std::string getAppSettingsFileName();
+    /// Compute the (read-ony) application settings file name
+    std::string getAppSettingsFileName();
 
-	/// basename for the settings files
-	static const char* SETTINGS_FILE_NAME;
+    /// basename for the settings files
+    static const char* SETTINGS_FILE_NAME;
 };
 
 #endif /* LLAUTOREPLACE_H */
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 797d590e1f..73eb822036 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -66,6 +66,7 @@
 #include "llrootview.h"
 #include "llviewerchat.h"
 #include "lltranslate.h"
+#include "llautoreplace.h"
 
 S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0;
 
@@ -112,6 +113,7 @@ BOOL LLFloaterIMNearbyChat::postBuild()
     setIsSingleInstance(TRUE);
     BOOL result = LLFloaterIMSessionTab::postBuild();
 	
+    mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
 	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
 	mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
 	mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a09dc1914f..a2c7bacb5d 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -332,13 +332,7 @@ BOOL LLFloaterIMSession::postBuild()
 	BOOL result = LLFloaterIMSessionTab::postBuild();
 
 	mInputEditor->setMaxTextLength(1023);
-	// enable line history support for instant message bar
-	// XXX stinson TODO : resolve merge by adding autoreplace to text editors
-#if 0
-	// *TODO Establish LineEditor with autoreplace callback
 	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
-#endif
-	
 	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
 	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
 	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
-- 
cgit v1.2.3


From c3fd7ae17b67568a68ae967cd2d30e20db1f6b6c Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Mon, 28 Jan 2013 19:59:13 +0200
Subject: CHUI-708 FIXED Call doToParticipants() only if selected conversation
 is p2p

---
 indra/newview/llfloaterimcontainer.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index ff6234fa27..c272e5e391 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1086,7 +1086,10 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command,
         }
         else
         {
-            doToParticipants(command, selectedIDS);
+        	if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+        	{
+        		doToParticipants(command, selectedIDS);
+        	}
         }
     }
 }
-- 
cgit v1.2.3


From 2ac99f55f9e562e4ff8ebde4cba8270f1048c28d Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 24 Jan 2013 19:56:13 +0200
Subject: CHUI-578 FIXED Move preferences for conversation logs/transcripts to
 chat tab

---
 indra/llvfs/lldir.cpp                              |  13 +-
 indra/llvfs/lldir.h                                |   2 +
 indra/newview/app_settings/settings.xml            |   4 +-
 indra/newview/llconversationlog.cpp                |  60 +++--
 indra/newview/llconversationlog.h                  |  11 +-
 indra/newview/llfloaterconversationlog.cpp         |  14 +-
 indra/newview/llfloaterconversationlog.h           |   2 +-
 indra/newview/llfloaterimcontainer.cpp             |   6 +-
 indra/newview/llfloaterimnearbychat.cpp            |  27 +-
 indra/newview/llfloaterimnearbychat.h              |   2 +-
 indra/newview/llfloaterimsession.cpp               |  12 +-
 indra/newview/llfloaterimsession.h                 |   2 +-
 indra/newview/llfloaterimsessiontab.cpp            |   6 +-
 indra/newview/llfloaterimsessiontab.h              |   2 +-
 indra/newview/llfloaterpreference.cpp              | 109 +++++---
 indra/newview/llfloaterpreference.h                |  19 +-
 indra/newview/llimview.cpp                         |  37 +--
 indra/newview/llimview.h                           |   2 +
 indra/newview/lllogchat.cpp                        | 235 ++++++++++-------
 indra/newview/lllogchat.h                          |  15 +-
 indra/newview/llviewermessage.cpp                  |   2 +-
 .../newview/skins/default/xui/en/notifications.xml |  26 ++
 .../default/xui/en/panel_preferences_chat.xml      | 284 ++++++++++++++-------
 .../default/xui/en/panel_preferences_privacy.xml   | 226 +++++-----------
 24 files changed, 641 insertions(+), 477 deletions(-)

(limited to 'indra')

diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 5e5aeefba1..f7bc19574a 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -90,7 +90,8 @@ LLDir::LLDir()
 	mCAFile(""),
 	mTempDir(""),
 	mDirDelimiter("/"), // fallback to forward slash if not overridden
-	mLanguage("en")
+	mLanguage("en"),
+	mUserName("undefined")
 {
 }
 
@@ -814,6 +815,11 @@ void LLDir::setChatLogsDir(const std::string &path)
 	}
 }
 
+void LLDir::updatePerAccountChatLogsDir()
+{
+	mPerAccountChatLogsDir = add(getChatLogsDir(), mUserName);
+}
+
 void LLDir::setPerAccountChatLogsDir(const std::string &username)
 {
 	// if both first and last aren't set, assume we're grabbing the cached dir
@@ -824,13 +830,14 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username)
 		std::string userlower(username);
 		LLStringUtil::toLower(userlower);
 		LLStringUtil::replaceChar(userlower, ' ', '_');
-		mPerAccountChatLogsDir = add(getChatLogsDir(), userlower);
+
+		mUserName = userlower;
+		updatePerAccountChatLogsDir();
 	}
 	else
 	{
 		llerrs << "NULL name for LLDir::setPerAccountChatLogsDir" << llendl;
 	}
-	
 }
 
 void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language)
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 300ff1eef6..95cab65149 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -186,6 +186,7 @@ class LLDir
 	virtual std::string getSkinFolder() const;
 	virtual std::string getLanguage() const;
 	virtual bool setCacheDir(const std::string &path);
+	virtual void updatePerAccountChatLogsDir();
 
 	virtual void dumpCurrentDirectories();
 
@@ -243,6 +244,7 @@ protected:
 	std::vector<std::string> mSearchSkinDirs;
 	std::string mLanguage;              // Current viewer language
 	std::string mLLPluginDir;			// Location for plugins and plugin shell
+	std::string mUserName;				// Current user name
 };
 
 void dir_exists_or_crash(const std::string &dir_name);
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index fd4d1df894..dd9a0100c0 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4674,9 +4674,9 @@
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
-      <string>Boolean</string>
+      <string>S32</string>
       <key>Value</key>
-      <integer>1</integer>
+      <integer>2</integer>
     </map>
     <key>LandBrushSize</key>
     <map>
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index ff1f819d7d..8de041f983 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -28,13 +28,14 @@
 #include "llagent.h"
 #include "llavatarnamecache.h"
 #include "llconversationlog.h"
+#include "llnotificationsutil.h"
 #include "lltrans.h"
 
 const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec
 
-struct Conversation_params
+struct ConversationParams
 {
-	Conversation_params(time_t time)
+	ConversationParams(time_t time)
 	:	mTime(time),
 		mTimestamp(LLConversation::createTimestamp(time))
 	{}
@@ -53,7 +54,7 @@ struct Conversation_params
 /*             LLConversation implementation                            */
 /************************************************************************/
 
-LLConversation::LLConversation(const Conversation_params& params)
+LLConversation::LLConversation(const ConversationParams& params)
 :	mTime(params.mTime),
 	mTimestamp(params.mTimestamp),
 	mConversationType(params.mConversationType),
@@ -188,33 +189,24 @@ void LLConversationLogFriendObserver::changed(U32 mask)
 LLConversationLog::LLConversationLog() :
 	mAvatarNameCacheConnection()
 {
-	LLControlVariable* log_instant_message = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
-	LLControlVariable* keep_convers_log = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
-	bool is_log_message = false;
-	bool is_keep_log = false;
+	LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+	S32 log_mode = keep_log_ctrlp->getValue();
 
-	if (log_instant_message)
+	if (log_mode > 0)
 	{
-		log_instant_message->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
-		is_log_message = log_instant_message->getValue().asBoolean();
+		keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+		enableLogging(log_mode);
 	}
-	if (keep_convers_log)
-	{
-		keep_convers_log->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
-		is_keep_log = keep_convers_log->getValue().asBoolean();
-	}
-
-	enableLogging(is_log_message && is_keep_log);
 }
 
-void LLConversationLog::enableLogging(bool enable)
+void LLConversationLog::enableLogging(S32 log_mode)
 {
-	if (enable)
+	if (log_mode > 0)
 	{
 		loadFromFile(getFileName());
 
 		LLIMMgr::instance().addSessionObserver(this);
-		newMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
+		mNewMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
 
 		mFriendObserver = new LLConversationLogFriendObserver;
 		LLAvatarTracker::instance().addObserver(mFriendObserver);
@@ -224,7 +216,7 @@ void LLConversationLog::enableLogging(bool enable)
 		saveToFile(getFileName());
 
 		LLIMMgr::instance().removeSessionObserver(this);
-		newMessageSignalConnection.disconnect();
+		mNewMessageSignalConnection.disconnect();
 		LLAvatarTracker::instance().removeObserver(mFriendObserver);
 		mConversations.clear();
 	}
@@ -377,7 +369,7 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
 
 void LLConversationLog::cache()
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	if (gSavedSettings.getS32("KeepConversationLogTranscripts") > 0)
 	{
 		saveToFile(getFileName());
 	}
@@ -450,9 +442,9 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	char part_id_buffer[MAX_STRING];
 	char conv_id_buffer[MAX_STRING];
 	char history_file_name[MAX_STRING];
-	int has_offline_ims;
-	int stype;
-	time_t time;
+	S32 has_offline_ims;
+	S32 stype;
+	S64 time;
 	// before CHUI-348 it was a flag of conversation voice state
 	int prereserved_unused;
 
@@ -462,7 +454,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 		part_id_buffer[0]	= '\0';
 		conv_id_buffer[0]	= '\0';
 
-		sscanf(buffer, "[%ld] %d %d %d %[^|]| %s %s %[^|]|",
+		sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
 				&time,
 				&stype,
 				&prereserved_unused,
@@ -472,7 +464,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 				conv_id_buffer,
 				history_file_name);
 
-		Conversation_params params(time);
+		ConversationParams params((time_t)time);
 		params.mConversationType = (SessionType)stype;
 		params.mHasOfflineIMs = has_offline_ims;
 		params.mConversationName = std::string(conv_name_buffer);
@@ -530,3 +522,17 @@ void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LL
 	mAvatarNameCacheConnection.disconnect();
 	updateConversationName(session, av_name.getCompleteName());
 }
+
+void LLConversationLog::onClearLog()
+{
+	LLNotificationsUtil::add("PreferenceChatClearLog", LLSD(), LLSD(), boost::bind(&LLConversationLog::onClearLogResponse, this, _1, _2));
+}
+
+void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD& response)
+{
+	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+	{
+		mConversations.clear();
+		notifyObservers();
+	}
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 35462ec3a4..65a18c02e5 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -31,7 +31,7 @@
 #include "llimview.h"
 
 class LLConversationLogObserver;
-struct Conversation_params;
+struct ConversationParams;
 
 typedef LLIMModel::LLIMSession::SType SessionType;
 
@@ -43,7 +43,7 @@ class LLConversation
 {
 public:
 
-	LLConversation(const Conversation_params& params);
+	LLConversation(const ConversationParams& params);
 	LLConversation(const LLIMModel::LLIMSession& session);
 	LLConversation(const LLConversation& conversation);
 
@@ -138,6 +138,9 @@ public:
 	 */
 	void cache();
 
+	void onClearLog();
+	void onClearLogResponse(const LLSD& notification, const LLSD& response);
+
 private:
 
 	LLConversationLog();
@@ -149,7 +152,7 @@ private:
 		}
 	}
 	
-	void enableLogging(bool enable);
+	void enableLogging(S32 log_mode);
 
 	/**
 	 * adds conversation to the conversation list and notifies observers
@@ -182,7 +185,7 @@ private:
 
 	LLFriendObserver* mFriendObserver;		// Observer of the LLAvatarTracker instance
 
-	boost::signals2::connection newMessageSignalConnection;
+	boost::signals2::connection mNewMessageSignalConnection;
 	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index a40a000bab..a44ebcf6ab 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -63,13 +63,9 @@ BOOL LLFloaterConversationLog::postBuild()
 
 	getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
 
-	LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
-	if (ctrl)
-	{
-		ctrl->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
-		onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean()
-				&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"));
-	}
+	LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+	keep_log_ctrlp->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
+	onCallLoggingEnabledDisabled(keep_log_ctrlp->getValue());
 
 	return LLFloater::postBuild();
 }
@@ -139,8 +135,8 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
 	return false;
 }
 
-void LLFloaterConversationLog::onCallLoggingEnabledDisabled(bool enabled)
+void LLFloaterConversationLog::onCallLoggingEnabledDisabled(S32 log_mode)
 {
-	std::string no_items_msg = enabled ? "" : getString("logging_calls_disabled");
+	std::string no_items_msg = log_mode > 0 ? "" : getString("logging_calls_disabled");
 	mConversationLogList->setNoItemsCommentText(no_items_msg);
 }
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
index 9e79cbd7d8..aa0f480aae 100644
--- a/indra/newview/llfloaterconversationlog.h
+++ b/indra/newview/llfloaterconversationlog.h
@@ -49,7 +49,7 @@ private:
 	bool isActionEnabled(const LLSD& userdata);
 	bool isActionChecked(const LLSD& userdata);
 
-	void onCallLoggingEnabledDisabled(bool enabled);
+	void onCallLoggingEnabledDisabled(S32 log_mode);
 
 	LLConversationLogList* mConversationLogList;
 };
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c272e5e391..54e5085490 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -224,7 +224,7 @@ BOOL LLFloaterIMContainer::postBuild()
 
 	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
 	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
-	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
+	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
 	mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
 	if (! mMessagesPane->isCollapsed())
 	{
@@ -1142,7 +1142,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 
 	if ("conversation_log" == item)
 	{
-		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+		return gSavedSettings.getS32("KeepConversationLogTranscripts") > 0;
 	}
 
 	//Enable Chat history item for ad-hoc and group conversations
@@ -1793,7 +1793,7 @@ void LLFloaterIMContainer::updateSpeakBtnState()
 
 bool LLFloaterIMContainer::isConversationLoggingAllowed()
 {
-	return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+	return gSavedSettings.getS32("KeepConversationLogTranscripts") > 0;
 }
 
 void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 797d590e1f..17d2341b3c 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -148,8 +148,14 @@ void LLFloaterIMNearbyChat::refresh()
 	}
 }
 
-void LLFloaterIMNearbyChat::reloadMessages()
+void LLFloaterIMNearbyChat::reloadMessages(bool clean_messages/* = false*/)
 {
+	if (clean_messages)
+	{
+		mMessageArchive.clear();
+		loadHistory();
+	}
+
 	mChatHistory->clear();
 
 	LLSD do_not_log;
@@ -174,11 +180,11 @@ void LLFloaterIMNearbyChat::loadHistory()
 	{
 		const LLSD& msg = *it;
 
-		std::string from = msg[IM_FROM];
+		std::string from = msg[LL_IM_FROM];
 		LLUUID from_id;
-		if (msg[IM_FROM_ID].isDefined())
+		if (msg[LL_IM_FROM_ID].isDefined())
 		{
-			from_id = msg[IM_FROM_ID].asUUID();
+			from_id = msg[LL_IM_FROM_ID].asUUID();
 		}
 		else
  		{
@@ -189,8 +195,8 @@ void LLFloaterIMNearbyChat::loadHistory()
 		LLChat chat;
 		chat.mFromName = from;
 		chat.mFromID = from_id;
-		chat.mText = msg[IM_TEXT].asString();
-		chat.mTimeStr = msg[IM_TIME].asString();
+		chat.mText = msg[LL_IM_TEXT].asString();
+		chat.mTimeStr = msg[LL_IM_TIME].asString();
 		chat.mChatStyle = CHAT_STYLE_HISTORY;
 
 		chat.mSourceType = CHAT_SOURCE_AGENT;
@@ -519,20 +525,21 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type )
 	}
 }
 
-void	LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
 {
 	appendMessage(chat, args);
 
 	if(archive)
 	{
 		mMessageArchive.push_back(chat);
-		if(mMessageArchive.size()>200)
+		if(mMessageArchive.size() > 200)
+		{
 			mMessageArchive.erase(mMessageArchive.begin());
+		}
 	}
 
 	// logging
-	if (!args["do_not_log"].asBoolean()
-			&& gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
+	if (!args["do_not_log"].asBoolean() && gSavedSettings.getS32("KeepConversationLogTranscripts") > 1)
 	{
 		std::string from_name = chat.mFromName;
 
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index f4213eda5a..14c7d01ecd 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -56,7 +56,7 @@ public:
 	/*virtual*/ void setVisible(BOOL visible);
 
 	void loadHistory();
-    void reloadMessages();
+    void reloadMessages(bool clean_messages = false);
 	void removeScreenChat();
 
 	void show();
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a09dc1914f..07f5515582 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -853,8 +853,18 @@ void LLFloaterIMSession::updateMessages()
 	}
 }
 
-void LLFloaterIMSession::reloadMessages()
+void LLFloaterIMSession::reloadMessages(bool clean_messages/* = false*/)
 {
+	if (clean_messages)
+	{
+		LLIMModel::LLIMSession * sessionp = LLIMModel::instance().findIMSession(mSessionID);
+
+		if (NULL != sessionp)
+		{
+			sessionp->loadHistory();
+		}
+	}
+
 	mChatHistory->clear();
 	mLastMessageIndex = -1;
 	updateMessages();
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 2049cedfd7..e7fd6f9ff3 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -86,7 +86,7 @@ public:
 
 	// get new messages from LLIMModel
 	/*virtual*/ void updateMessages();
-	void reloadMessages();
+	void reloadMessages(bool clean_messages = false);
 	static void onSendMsg(LLUICtrl*, void*);
 	void sendMsgFromInputEditor();
 	void sendMsg(const std::string& msg);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 37404ab716..f7c6f19450 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -680,7 +680,7 @@ void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
 }
 
 // static
-void LLFloaterIMSessionTab::processChatHistoryStyleUpdate()
+void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/)
 {
 	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
 	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
@@ -689,14 +689,14 @@ void LLFloaterIMSessionTab::processChatHistoryStyleUpdate()
 		LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
 		if (floater)
 		{
-			floater->reloadMessages();
+			floater->reloadMessages(clean_messages);
 		}
 	}
 
 	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 	if (nearby_chat)
 	{
-             nearby_chat->reloadMessages();
+             nearby_chat->reloadMessages(clean_messages);
 	}
 }
 
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index beaffc14a6..e90fcbb806 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -53,7 +53,7 @@ public:
 	~LLFloaterIMSessionTab();
 
 	// reload all message with new settings of visual modes
-	static void processChatHistoryStyleUpdate();
+	static void processChatHistoryStyleUpdate(bool clean_messages = false);
 
 	/**
 	 * Returns true if chat is displayed in multi tabbed floater
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3d4a1c44d8..7742e5b3c3 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -306,7 +306,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mAvatarDataInitialized(false),
 	mClickActionDirty(false)
 {
-	
+	LLConversationLog::instance().addObserver(this);
+
 	//Build Floater is now Called from 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
 	
 	static bool registered_dialog = false;
@@ -329,8 +330,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.VoiceSetKey",			boost::bind(&LLFloaterPreference::onClickSetKey, this));
 	mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse",	boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
 	mCommitCallbackRegistrar.add("Pref.SetSounds",				boost::bind(&LLFloaterPreference::onClickSetSounds, this));
-//	mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs",		boost::bind(&LLFloaterPreference::onClickSkipDialogs, this));
-//	mCommitCallbackRegistrar.add("Pref.ClickResetDialogs",		boost::bind(&LLFloaterPreference::onClickResetDialogs, this));
 	mCommitCallbackRegistrar.add("Pref.ClickEnablePopup",		boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
 	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	
 	mCommitCallbackRegistrar.add("Pref.LogPath",				boost::bind(&LLFloaterPreference::onClickLogPath, this));
@@ -351,13 +350,16 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 
 	sSkin = gSavedSettings.getString("SkinCurrent");
 
-	mCommitCallbackRegistrar.add("Pref.ClickActionChange",				boost::bind(&LLFloaterPreference::onClickActionChange, this));
+	mCommitCallbackRegistrar.add("Pref.ClickActionChange",		boost::bind(&LLFloaterPreference::onClickActionChange, this));
 
 	gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));
 	
 	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
+
+	mCommitCallbackRegistrar.add("Pref.ClearLog",				boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
+	mCommitCallbackRegistrar.add("Pref.DeleteTranscripts",      boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
 }
 
 void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
@@ -425,7 +427,7 @@ void LLFloaterPreference::saveAvatarProperties( void )
 
 BOOL LLFloaterPreference::postBuild()
 {
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
+	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
 
@@ -455,9 +457,24 @@ BOOL LLFloaterPreference::postBuild()
 		gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
 	}
 
+	// set 'enable' property for 'Clear log...' button
+	changed();
+
+	// set 'enable' property for 'Delete transcripts...' button
+	updateDeleteTranscriptsButton();
+
+	LLLogChat::setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this));
+
 	return TRUE;
 }
 
+void LLFloaterPreference::updateDeleteTranscriptsButton()
+{
+	std::vector<std::string> list_of_transcriptions_file_names;
+	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
+	getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+}
+
 void LLFloaterPreference::onDoNotDisturbResponseChanged()
 {
 	// set "DoNotDisturbResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
@@ -476,6 +493,8 @@ LLFloaterPreference::~LLFloaterPreference()
 	{
 		ctrl_window_size->setCurrentByIndex(i);
 	}
+
+	LLConversationLog::instance().removeObserver(this);
 }
 
 void LLFloaterPreference::draw()
@@ -833,12 +852,12 @@ void LLFloaterPreference::onBtnCancel()
 }
 
 // static 
-void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email)
 {
 	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
 	if (instance)
 	{
-		instance->setPersonalInfo(visibility, im_via_email, email);	
+		instance->setPersonalInfo(visibility, im_via_email);	
 	}
 }
 
@@ -1425,10 +1444,21 @@ void LLFloaterPreference::onClickLogPath()
 		return; //Canceled!
 	}
 
-	gSavedPerAccountSettings.setString("InstantMessageLogPath", picker.getDirName());
+	std::string dir_name = picker.getDirName();
+	gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+	
+	gDirUtilp->setChatLogsDir(dir_name);
+	gDirUtilp->updatePerAccountChatLogsDir();
+	LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
+
+	// refresh IM floaters with new logs from files from new selected directory
+	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+
+	// enable/disable 'Delete transcripts button
+	updateDeleteTranscriptsButton();
 }
 
-void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email)
 {
 	mGotPersonalInfo = true;
 	mOriginalIMViaEmail = im_via_email;
@@ -1450,32 +1480,14 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	}
 	
 	getChild<LLUICtrl>("online_searchresults")->setEnabled(TRUE);
-
-	getChildView("include_im_in_chat_history")->setEnabled(TRUE);
-	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
 	getChildView("friends_online_notify_checkbox")->setEnabled(TRUE);
-	
 	getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus); 	 
 	getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
 	getChildView("send_im_to_email")->setEnabled(TRUE);
 	getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
-	getChildView("log_instant_messages")->setEnabled(TRUE);
-//	getChildView("log_chat")->setEnabled(TRUE);
-//	getChildView("log_instant_messages_timestamp")->setEnabled(TRUE);
-//	getChildView("log_chat_timestamp")->setEnabled(TRUE);
-	getChildView("log_chat_IM")->setEnabled(TRUE);
-	getChildView("log_date_timestamp")->setEnabled(TRUE);
-	
 	getChildView("favorites_on_login_check")->setEnabled(TRUE);
-	getChildView("log_nearby_chat")->setEnabled(TRUE);
-	getChildView("log_instant_messages")->setEnabled(TRUE);
-	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
 	getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
 	getChildView("log_path_button")->setEnabled(TRUE);
-	childEnable("logfile_name_datestamp");	
-	std::string display_email(email);
-	getChild<LLUICtrl>("email_address")->setValue(display_email);
-
 }
 
 void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)
@@ -1566,6 +1578,35 @@ void LLFloaterPreference::onClickActionChange()
 	mClickActionDirty = true;
 }
 
+void LLFloaterPreference::onDeleteTranscripts()
+{
+	LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", LLSD(), LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
+}
+
+void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response)
+{
+	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+	{
+		gDirUtilp->deleteFilesInDir(gDirUtilp->getPerAccountChatLogsDir(), "*." + LL_TRANSCRIPT_FILE_EXTENSION);
+
+		std::vector<std::string> list_of_transcriptions_file_names;
+		LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
+		getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+
+		LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+	}
+}
+
+void LLFloaterPreference::onLogChatHistorySaved()
+{
+	LLButton * delete_transcripts_buttonp = getChild<LLButton>("delete_transcripts");
+
+	if (!delete_transcripts_buttonp->getEnabled())
+	{
+		delete_transcripts_buttonp->setEnabled(true);
+	}
+}
+
 void LLFloaterPreference::updateClickActionSettings()
 {
 	const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
@@ -1624,6 +1665,11 @@ void LLFloaterPreference::selectChatPanel()
 	selectPanel("chat");
 }
 
+void LLFloaterPreference::changed()
+{
+	getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
+}
+
 //------------------------------Updater---------------------------------------
 
 static bool handleBandwidthChanged(const LLSD& newvalue)
@@ -1717,11 +1763,6 @@ BOOL LLPanelPreference::postBuild()
 
 	}
 
-	if (hasChild("online_visibility") && hasChild("send_im_to_email"))
-	{
-		getChild<LLUICtrl>("email_address")->setValue(getString("log_in_to_change") );
-	}
-	
 	//////////////////////PanelPrivacy ///////////////////
 	if (hasChild("media_enabled"))
 	{
@@ -1898,7 +1939,7 @@ public:
 			for (control_values_map_t::iterator it = mSavedValues.begin(); it != mSavedValues.end(); )
 			{
 				const std::string setting = it->first->getName();
-				if (std::find(mAccountIndependentSettings.begin(),
+				if (find(mAccountIndependentSettings.begin(),
 					mAccountIndependentSettings.end(), setting) == mAccountIndependentSettings.end())
 				{
 					mSavedValues.erase(it++);
@@ -2187,4 +2228,4 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()
 		otherHttpProxy->selectFirstItem();
 	}
 
-};
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 37a531e99e..f9f1d52244 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -35,7 +35,9 @@
 
 #include "llfloater.h"
 #include "llavatarpropertiesprocessor.h"
+#include "llconversationlog.h"
 
+class LLConversationLogObserver;
 class LLPanelPreference;
 class LLPanelLCD;
 class LLPanelDebug;
@@ -58,7 +60,7 @@ typedef enum
 
 
 // Floater to control preferences (display, audio, bandwidth, general.
-class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
+class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, public LLConversationLogObserver
 {
 public: 
 	LLFloaterPreference(const LLSD& key);
@@ -70,9 +72,11 @@ public:
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/	void onClose(bool app_quitting);
+	/*virtual*/ void changed();
+	/*virtual*/ void changed(const LLUUID& session_id, U32 mask) {};
 
 	// static data update, called from message handler
-	static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+	static void updateUserInfo(const std::string& visibility, bool im_via_email);
 
 	// refresh all the graphics preferences menus
 	static void refreshEnabledGraphics();
@@ -134,15 +138,13 @@ public:
 	void setKey(KEY key);
 	void onClickSetMiddleMouse();
 	void onClickSetSounds();
-//	void onClickSkipDialogs();
-//	void onClickResetDialogs();
 	void onClickEnablePopup();
 	void onClickDisablePopup();	
 	void resetAllIgnored();
 	void setAllIgnored();
 	void onClickLogPath();	
 	void enableHistory();
-	void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+	void setPersonalInfo(const std::string& visibility, bool im_via_email);
 	void refreshEnabledState();
 	void disableUnavailableSettings();
 	void onCommitWindowedMode();
@@ -166,12 +168,17 @@ public:
 	void onClickSpellChecker();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
-	
+	void onLogChatHistorySaved();	
 	void buildPopupLists();
 	static void refreshSkin(void* data);
 	void selectPanel(const LLSD& name);
 
 private:
+
+	void onDeleteTranscripts();
+	void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
+	void updateDeleteTranscriptsButton();
+
 	static std::string sSkin;
 	notifications_map mNotificationOptions;
 	bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 433ddad35d..37c9ee8c99 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -378,15 +378,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 	}
 
 	buildHistoryFileName();
-
-	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
-	{
-		std::list<LLSD> chat_history;
-
-		//involves parsing of a chat history
-		LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
-		addMessagesFromHistory(chat_history);
-	}
+	loadHistory();
 
 	// Localizing name of ad-hoc session. STORM-153
 	// Changing name should happen here- after the history file was created, so that
@@ -579,11 +571,11 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
 	{
 		const LLSD& msg = *it;
 
-		std::string from = msg[IM_FROM];
+		std::string from = msg[LL_IM_FROM];
 		LLUUID from_id;
-		if (msg[IM_FROM_ID].isDefined())
+		if (msg[LL_IM_FROM_ID].isDefined())
 		{
-			from_id = msg[IM_FROM_ID].asUUID();
+			from_id = msg[LL_IM_FROM_ID].asUUID();
 		}
 		else
 		{
@@ -592,8 +584,8 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
  			gCacheName->getUUID(legacy_name, from_id);
 		}
 
-		std::string timestamp = msg[IM_TIME];
-		std::string text = msg[IM_TEXT];
+		std::string timestamp = msg[LL_IM_TIME];
+		std::string text = msg[LL_IM_TEXT];
 
 		addMessage(from, from_id, text, timestamp, true);
 
@@ -617,6 +609,20 @@ void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const
 	}
 }
 
+void LLIMModel::LLIMSession::loadHistory()
+{
+	mMsgs.clear();
+
+	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+	{
+		std::list<LLSD> chat_history;
+
+		//involves parsing of a chat history
+		LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
+		addMessagesFromHistory(chat_history);
+	}
+}
+
 LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
 {
 	return get_if_there(mId2SessionMap, session_id,
@@ -921,8 +927,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 
 bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")
-			&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
+	if (gSavedSettings.getS32("KeepConversationLogTranscripts") > 1)
 	{	
 		std::string from_name = from;
 
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 8578fa8c06..da6039a3ae 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -101,6 +101,8 @@ public:
 		/** ad-hoc sessions involve sophisticated chat history file naming schemes */
 		void buildHistoryFileName();
 
+		void loadHistory();
+
 		LLUUID mSessionID;
 		std::string mName;
 		EInstantMessage mType;
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 3692658e9e..545b44ef92 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -58,10 +58,11 @@
 
 const S32 LOG_RECALL_SIZE = 2048;
 
-const std::string IM_TIME("time");
-const std::string IM_TEXT("message");
-const std::string IM_FROM("from");
-const std::string IM_FROM_ID("from_id");
+const std::string LL_IM_TIME("time");
+const std::string LL_IM_TEXT("message");
+const std::string LL_IM_FROM("from");
+const std::string LL_IM_FROM_ID("from_id");
+const std::string LL_TRANSCRIPT_FILE_EXTENSION("ll.txt");
 
 const static std::string IM_SEPARATOR(": ");
 const static std::string NEW_LINE("\n");
@@ -116,6 +117,15 @@ const static int IDX_TEXT = 3;
 using namespace boost::posix_time;
 using namespace boost::gregorian;
 
+void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
+{
+	if (!messages.size()) return;
+
+	std::string im_text = messages.back()[LL_IM_TEXT].asString();
+	im_text.append(line);
+	messages.back()[LL_IM_TEXT] = im_text;
+}
+
 class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 {
 public:
@@ -191,15 +201,17 @@ private:
 	std::stringstream mTimeStream;
 };
 
+LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL;
+
 //static
 std::string LLLogChat::makeLogFileName(std::string filename)
 {
 	/**
-	* Testing for in bound and out bound ad-hoc file names
-	* if it is then skip date stamping.
-	**/
-	//LL_INFOS("") << "Befor:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-    boost::match_results<std::string::const_iterator> matches;
+	 * Testing for in bound and out bound ad-hoc file names
+	 * if it is then skip date stamping.
+	 **/
+
+	boost::match_results<std::string::const_iterator> matches;
 	bool inboundConf = boost::regex_match(filename, matches, INBOUND_CONFERENCE);
 	bool outboundConf = boost::regex_match(filename, matches, OUTBOUND_CONFERENCE);
 	if (!(inboundConf || outboundConf))
@@ -220,17 +232,17 @@ std::string LLLogChat::makeLogFileName(std::string filename)
 			filename += dbuffer;
 		}
 	}
-	//LL_INFOS("") << "After:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+
 	filename = cleanFileName(filename);
-	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename);
-	filename += ".txt";
-	//LL_INFOS("") << "Full:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
+	filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+
 	return filename;
 }
 
 std::string LLLogChat::cleanFileName(std::string filename)
 {
-    std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
+	std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
 	std::string::size_type position = filename.find_first_of(invalidChars);
 	while (position != filename.npos)
 	{
@@ -242,27 +254,24 @@ std::string LLLogChat::cleanFileName(std::string filename)
 
 std::string LLLogChat::timestamp(bool withdate)
 {
-	time_t utc_time;
-	utc_time = time_corrected();
-
 	std::string timeStr;
-	LLSD substitution;
-	substitution["datetime"] = (S32) utc_time;
-
 	if (withdate)
 	{
-		timeStr = "["+LLTrans::getString ("TimeYear")+"]/["
-		          +LLTrans::getString ("TimeMonth")+"]/["
-				  +LLTrans::getString ("TimeDay")+"] ["
-				  +LLTrans::getString ("TimeHour")+"]:["
-				  +LLTrans::getString ("TimeMin")+"]";
+		timeStr = "[" + LLTrans::getString ("TimeYear") + "]/["
+				  + LLTrans::getString ("TimeMonth") + "]/["
+				  + LLTrans::getString ("TimeDay") + "] ["
+				  + LLTrans::getString ("TimeHour") + "]:["
+				  + LLTrans::getString ("TimeMin") + "]";
 	}
 	else
 	{
 		timeStr = "[" + LLTrans::getString("TimeHour") + "]:["
-			      + LLTrans::getString ("TimeMin")+"]";
+				  + LLTrans::getString ("TimeMin")+"]";
 	}
 
+	LLSD substitution;
+	substitution["datetime"] = (S32)time_corrected();
+
 	LLStringUtil::format (timeStr, substitution);
 	return timeStr;
 }
@@ -270,9 +279,9 @@ std::string LLLogChat::timestamp(bool withdate)
 
 //static
 void LLLogChat::saveHistory(const std::string& filename,
-			    const std::string& from,
-			    const LLUUID& from_id,
-			    const std::string& line)
+							const std::string& from,
+							const LLUUID& from_id,
+							const std::string& line)
 {
 	std::string tmp_filename = filename;
 	LLStringUtil::trim(tmp_filename);
@@ -312,6 +321,11 @@ void LLLogChat::saveHistory(const std::string& filename,
 	file << LLChatLogFormatter(item) << std::endl;
 
 	file.close();
+
+	if (NULL != sSaveHistorySignal)
+	{
+		(*sSaveHistorySignal)();
+	}
 }
 
 void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLineType, const LLSD&, void*), void* userdata)
@@ -321,7 +335,7 @@ void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLi
 		llwarns << "Filename is Empty!" << llendl;
 		return ;
 	}
-        
+		
 	LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "r");		/*Flawfinder: ignore*/
 	if (!fptr)
 	{
@@ -377,15 +391,6 @@ void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLi
 	}
 }
 
-void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
-{
-	if (!messages.size()) return;
-
-	std::string im_text = messages.back()[IM_TEXT].asString();
-	im_text.append(line);
-	messages.back()[IM_TEXT] = im_text;
-}
-
 // static
 void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
 {
@@ -397,19 +402,16 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 
 	bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
 
-	//LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-	//LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
 	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
 	if (!fptr)
-    {
+	{
 		fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
-        if (!fptr)
-        {
-			if (!fptr) return;      //No previous conversation with this name.
-        }
+		if (!fptr)
+		{
+			return;						//No previous conversation with this name.
+		}
 	}
  
-    //LL_INFOS("") << "Reading:" << file_name << LL_ENDL;
 	char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
 	char *bptr;
 	S32 len;
@@ -454,7 +456,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 			LLSD item;
 			if (!LLChatLogParser::parse(line, item, load_params))
 			{
-				item[IM_TEXT] = line;
+				item[LL_IM_TEXT] = line;
 			}
 			messages.push_back(item);
 		}
@@ -462,9 +464,78 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 	fclose(fptr);
 }
 
+// static
+std::string LLLogChat::oldLogFileName(std::string filename)
+{
+	// get Users log directory
+	std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+
+	// add final OS dependent delimiter
+	directory += gDirUtilp->getDirDelimiter();
+
+	// lest make sure the file name has no invalid characters before making the pattern
+	filename = cleanFileName(filename);
+
+	// create search pattern
+	std::string pattern = filename + ( filename == "chat" ? "-???\?-?\?-??.txt" : "-???\?-??.txt");
+
+	std::vector<std::string> allfiles;
+	LLDirIterator iter(directory, pattern);
+	std::string scanResult;
+
+	while (iter.next(scanResult))
+	{
+		allfiles.push_back(scanResult);
+	}
+
+	if (allfiles.size() == 0)  // if no result from date search, return generic filename
+	{
+		scanResult = directory + filename + '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+	}
+	else 
+	{
+		sort(allfiles.begin(), allfiles.end());
+		scanResult = directory + allfiles.back();
+		// this file is now the most recent version of the file.
+	}
+
+	return scanResult;
+}
+
+// static
+void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions)
+{
+	// get Users log directory
+	std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+
+	// add final OS dependent delimiter
+	directory += gDirUtilp->getDirDelimiter();
+
+	// create search pattern
+	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
+
+	LLDirIterator iter(directory, pattern);
+	std::string scanResult;
+	while (iter.next(scanResult))
+	{
+		list_of_transcriptions.push_back(scanResult);
+	}
+}
+
+//static
+boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_signal_t::slot_type& cb)
+{
+	if (NULL == sSaveHistorySignal)
+	{
+		sSaveHistorySignal = new save_history_signal_t();
+	}
+
+	return sSaveHistorySignal->connect(cb);
+}
+
 //*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
 //which are more strict by its nature (only firstname and secondname)
-//Example, an object's name can be writen like "Object <actual_object's_name>"
+//Example, an object's name can be written like "Object <actual_object's_name>"
 void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 {
 	if (!im.isMap())
@@ -473,19 +544,19 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 		return;
 	}
 
-	if (im[IM_TIME].isDefined())
+	if (im[LL_IM_TIME].isDefined())
 {
-		std::string timestamp = im[IM_TIME].asString();
+		std::string timestamp = im[LL_IM_TIME].asString();
 		boost::trim(timestamp);
 		ostr << '[' << timestamp << ']' << TWO_SPACES;
 	}
 	
 	//*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
 	//which are more strict by its nature (only firstname and secondname)
-	//Example, an object's name can be writen like "Object <actual_object's_name>"
-	if (im[IM_FROM].isDefined())
+	//Example, an object's name can be written like "Object <actual_object's_name>"
+	if (im[LL_IM_FROM].isDefined())
 	{
-		std::string from = im[IM_FROM].asString();
+		std::string from = im[LL_IM_FROM].asString();
 		boost::trim(from);
 		if (from.size())
 		{
@@ -493,9 +564,9 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 		}
 	}
 
-	if (im[IM_TEXT].isDefined())
+	if (im[LL_IM_TEXT].isDefined())
 	{
-		std::string im_text = im[IM_TEXT].asString();
+		std::string im_text = im[LL_IM_TEXT].asString();
 
 		//multilined text will be saved with prepended spaces
 		boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX);
@@ -528,12 +599,12 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 			LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
 		}
 
-		im[IM_TIME] = timestamp;
+		im[LL_IM_TIME] = timestamp;
 	}
 	else
 	{
 		//timestamp is optional
-		im[IM_TIME] = "";
+		im[LL_IM_TIME] = "";
 	}
 
 	bool has_stuff = matches[IDX_STUFF].matched;
@@ -559,8 +630,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 	if (!has_name || name == SYSTEM_FROM)
 	{
 		//name is optional too
-		im[IM_FROM] = SYSTEM_FROM;
-		im[IM_FROM_ID] = LLUUID::null;
+		im[LL_IM_FROM] = SYSTEM_FROM;
+		im[LL_IM_FROM_ID] = LLUUID::null;
 	}
 
 	//possibly a case of complex object names consisting of 3+ words
@@ -569,8 +640,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 		U32 divider_pos = stuff.find(NAME_TEXT_DIVIDER);
 		if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length()))
 		{
-			im[IM_FROM] = stuff.substr(0, divider_pos);
-			im[IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
+			im[LL_IM_FROM] = stuff.substr(0, divider_pos);
+			im[LL_IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
 			return true;
 		}
 	}
@@ -578,7 +649,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 	if (!has_name)
 	{
 		//text is mandatory
-		im[IM_TEXT] = stuff;
+		im[LL_IM_TEXT] = stuff;
 		return true; //parse as a message from Second Life
 	}
 	
@@ -590,45 +661,15 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 	{
 		std::string agent_name;
 		LLAgentUI::buildFullname(agent_name);
-		im[IM_FROM] = agent_name;
-		im[IM_FROM_ID] = gAgentID;
+		im[LL_IM_FROM] = agent_name;
+		im[LL_IM_FROM_ID] = gAgentID;
 	}
 	else
 	{
-		im[IM_FROM] = name;
+		im[LL_IM_FROM] = name;
 	}
 	
 
-	im[IM_TEXT] = name_and_text[IDX_TEXT];
+	im[LL_IM_TEXT] = name_and_text[IDX_TEXT];
 	return true;  //parsed name and message text, maybe have a timestamp too
 }
-std::string LLLogChat::oldLogFileName(std::string filename)
-{
-    std::string scanResult;
-	std::string directory = gDirUtilp->getPerAccountChatLogsDir();/* get Users log directory */
-	directory += gDirUtilp->getDirDelimiter();/* add final OS dependent delimiter */
-	filename=cleanFileName(filename);/* lest make shure the file name has no invalad charecters befor making the pattern */
-	std::string pattern = (filename+(( filename == "chat" ) ? "-???\?-?\?-??.txt" : "-???\?-??.txt"));/* create search pattern*/
-	//LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-	std::vector<std::string> allfiles;
-
-	LLDirIterator iter(directory, pattern);
-	while (iter.next(scanResult))
-    {
-		//LL_INFOS("") << "Found   :" << scanResult << LL_ENDL;
-        allfiles.push_back(scanResult);
-    }
-
-    if (allfiles.size() == 0)  // if no result from date search, return generic filename
-    {
-        scanResult = directory + filename + ".txt";
-    }
-    else 
-    {
-        std::sort(allfiles.begin(), allfiles.end());
-        scanResult = directory + allfiles.back();
-        // thisfile is now the most recent version of the file.
-    }
-	//LL_INFOS("") << "Reading:" << scanResult << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-    return scanResult;
-}
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index d3e9adcc37..b35a94b4b3 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -49,6 +49,7 @@ public:
 				const std::string& from,
 				const LLUUID& from_id,
 				const std::string& line);
+	static void getListOfTranscriptFiles(std::vector<std::string>& list);
 
 	/** @deprecated @see loadChatHistory() */
 	static void loadHistory(const std::string& filename, 
@@ -56,8 +57,13 @@ public:
 							void* userdata);
 
 	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
+
+	typedef boost::signals2::signal<void ()> save_history_signal_t;
+	static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
+
 private:
 	static std::string cleanFileName(std::string filename);
+	static save_history_signal_t * sSaveHistorySignal;
 };
 
 /**
@@ -113,9 +119,10 @@ protected:
 };
 
 // LLSD map lookup constants
-extern const std::string IM_TIME; //("time");
-extern const std::string IM_TEXT; //("message");
-extern const std::string IM_FROM; //("from");
-extern const std::string IM_FROM_ID; //("from_id");
+extern const std::string LL_IM_TIME; //("time");
+extern const std::string LL_IM_TEXT; //("message");
+extern const std::string LL_IM_FROM; //("from");
+extern const std::string LL_IM_FROM_ID; //("from_id");
+extern const std::string LL_TRANSCRIPT_FILE_EXTENSION; //("ll.txt");
 
 #endif
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8489e92d15..f141419c43 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -6943,7 +6943,7 @@ void process_user_info_reply(LLMessageSystem* msg, void**)
 	std::string dir_visibility;
 	msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
 
-	LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
+	LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email);
 	LLFloaterSnapshot::setAgentEmail(email);
 }
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6a464ccdc4..9c36873141 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -8316,4 +8316,30 @@ Attempt cancelled.
      yestext="Yes"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="PreferenceChatClearLog"
+   type="alertmodal">
+    This will delete the log of previous conversations, and all transcripts of those conversations. Proceed?
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm before I delete the log of previous conversations."
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
+    
+  <notification
+   icon="alertmodal.tga"
+   name="PreferenceChatDeleteTranscripts"
+   type="alertmodal">
+    This will delete transcripts for all previous conversations. The list of conversations will not be affected. Proceed?
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm before I delete transcripts."
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
+
 </notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 37bfbae991..4f33699aa6 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
     border="true"
-    follows="left|top|right|bottom"
+    has_border="true"
     height="408"
     label="Text Chat"
     layout="topleft"
@@ -12,8 +12,7 @@
 
   <panel
       border="false"
-      follows="left|top"
-      height="90"
+      height="60"
       layout="topleft"
       top="10"
       left="13"
@@ -27,7 +26,9 @@
         layout="topleft"
         top="0"
         name="play_typing_animation"
-        width="330" />
+        width="330">
+    </check_box>
+
     <check_box
         enabled="false"
         height="16"
@@ -35,26 +36,21 @@
         layout="topleft"
         name="send_im_to_email"
         top_pad="6"
-        width="330" />
-    <check_box
-        control_name="KeepConversationLogTranscripts"
-        height="16"
-        label="Keep a conversation log and transcripts"
-        layout="topleft"
-        name="keep_convo_log_and_transcripts"
-        top_pad="6"
-        width="330" />
+        width="330">
+    </check_box>
+
     <check_box
-        control_name="UseChatBubbles"
-        follows="left|top"
+        control_name="VoiceCallsFriendsOnly"
         height="16"
-        label="Bubble Chat"
+        label="Only friends and groups can call or IM me"
         layout="topleft"
+        name="voice_call_friends_only_check"
         top_pad="6"
-        name="bubble_text_chat"
-        width="330" />
+        width="350">
+      <check_box.label_text text_color="White" />
+    </check_box>
+
     <text
-        follows="left|top"
         layout="topleft"
         left="345"
         height="12"
@@ -63,67 +59,65 @@
         top="0">
       Font size:
     </text>
-    <radio_group
-        height="90"
-        layout="topleft"
-        left="352"
+
+    <combo_box
         control_name="ChatFontSize"
+        height="23"
+        layout="topleft"
+        left="341"
         name="chat_font_size"
-        top_pad="0"
-        width="50">
-      <radio_item
-          height="16"
+        top_pad="5"
+        width="100">
+      <item
           label="Small"
-          layout="topleft"
-          name="radio"
-          value="0"
-          top="10"
-          width="125" />
-      <radio_item
-          height="16"
+          name="Small"
+          value="0"/>
+      <item
           label="Medium"
-          layout="topleft"
-          name="radio2"
-          value="1"
-          top_pad="6"
-          width="125" />
-      <radio_item
-          height="16"
+          name="Medium"
+          value="1"/>
+      <item
           label="Large"
-          layout="topleft"
-          name="radio3"
-          value="2"
-          top_pad="6"
-          width="125" />
-    </radio_group>    
-    
-  </panel>  
+          name="Large"
+          value="2"/>
+      <combo_box.drop_down_button label_color="White" />
+    </combo_box>
+
+    <check_box
+        control_name="UseChatBubbles"
+        height="16"
+        label="Bubble Chat"
+        layout="topleft"
+        top_pad="4"
+        name="bubble_text_chat"
+        width="330">
+    </check_box>
+      
+  </panel>
 
   <panel
       border="false"
-      follows="left|top"
-      height="198"
+      height="165"
       layout="topleft"
       left="13"
       width="517">
 
     <text
-        follows="left|top"
         layout="topleft"
         height="12"
         name="notifications"
         left="0"
+        text_color="White"
         width="120">
-      Notifications:
+      Notifications
     </text>
     <text
-        follows="left|top"
         layout="topleft"
         height="12"
         name="friend_ims"
         width="145"
         left="0"
-        top_pad="15">
+        top_pad="13">
       Friend IMs:
     </text>
     <combo_box
@@ -134,31 +128,30 @@
         top_delta="-6"
         name="FriendIMOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>      
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolbarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         height="12"
         name="non_friend_ims"
         width="145"
         left="0"
-        top_pad="15">
+        top_pad="9">
       Non-friend IMs:
     </text>
     <combo_box
@@ -169,31 +162,30 @@
         top_delta="-6"
         name="NonFriendIMOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolbarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         height="13"
         name="conference_ims"
         width="145"
-        top_pad="14">
+        top_pad="9">
       Conference IMs:
     </text>
     <combo_box
@@ -204,31 +196,30 @@
         top_delta="-6"
         name="ConferenceIMOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolbarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         height="13"
         name="group_chat"
         width="145"
-        top_pad="14">
+        top_pad="9">
       Group chat:
     </text>
     <combo_box
@@ -239,31 +230,30 @@
         top_delta="-6"
         name="GroupChatOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolbarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         height="12"
         name="nearby_chat"
         width="145"
-        top_pad="14">
+        top_pad="9">
       Nearby chat:
     </text>
     <combo_box
@@ -274,31 +264,30 @@
         top_delta="-6"
         name="NearbyChatOptions"
         width="223">
-      <combo_box.item
+      <item
           label="Open Conversations window"
           name="OpenConversationsWindow"
           value="openconversations"/>
-      <combo_box.item
+      <item
           label="Pop up the message"
           name="PopUpMessage"
           value="toast"/>
-      <combo_box.item
+      <item
           label="Flash toolbar button"
           name="FlashToolBarButton"
           value="flash"/>
-      <combo_box.item
+      <item
           label="None"
           name="None"
           value="none"/>
     </combo_box>
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         height="13"
         name="notifications_alert"
         width="500"
-        top_pad="11"
+        top_pad="9"
         visible="true"
         text_color="DrYellow">
       To temporarily stop all notifications, use Communicate &gt; Do Not Disturb.
@@ -308,14 +297,13 @@
 
   <panel
       border="false"
-      follows="left|top"
-      height="67"
+      height="50"
       layout="topleft"
       left="13"
+      top_pad="10"
       width="517">
 
     <text
-        follows="left|top"
         layout="topleft"
         left="0"
         name="play_sound"
@@ -360,9 +348,123 @@
         width="150" />
 
   </panel>
+
+  <view_border
+      bevel_style="none"
+      height="0"
+      layout="topleft"
+      left="13"
+      name="cost_text_border"
+      top_pad="5"
+      width="495"/>
+
+  <panel
+      height="50"
+      layout="topleft"
+      left="13"
+      top_pad="10"
+      width="505">
+
+    <text
+        layout="topleft"
+        left="0"
+        text_color="White"
+        height="12"
+        top="5"
+        width="55">
+        Save:
+    </text>
+
+    <combo_box
+        control_name="KeepConversationLogTranscripts"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        name="chat_font_size"
+        top="0"
+        width="165">
+        <item
+            label="Log and transcripts"
+            value="2"/>
+        <item
+            label="Log only"
+            value="1"/>
+        <item
+            label="No log or transcripts"
+            value="0"/>
+        <drop_down_button label_color="White" />
+    </combo_box>
+
+    <button
+        enabled="false"
+        height="23"
+        label="Clear log..."
+        label_color="White"
+        layout="topleft"
+        left_pad="5"
+        top="0"
+        name="clear_log"
+        width="110">
+        <commit_callback
+            function="Pref.ClearLog" />
+    </button>
+  
+    <button
+        enabled="false"
+        height="23"
+        label="Delete transcripts..."
+        label_color="White"
+        layout="topleft"
+        left_pad="5"
+        top="0"
+        name="delete_transcripts"
+        width="147">
+        <button.commit_callback
+            function="Pref.DeleteTranscripts" />
+    </button>
+  
+    <text
+        layout="topleft"
+        left="0"
+        text_color="White"
+        height="12"
+        top_pad="15"
+        width="55">
+        Location:
+    </text>
+  
+    <line_editor
+        control_name="InstantMessageLogPath"
+        border_style="line"
+        border_thickness="1"
+        font="SansSerif"
+        height="23"
+        layout="topleft"
+        left_pad="55"
+        max_length="4096"
+        name="log_path_string"
+        top_delta="-5"
+        width="185">
+    </line_editor>
+  
+    <button
+        enabled="false"
+        follows="left|top"
+        height="23"
+        label="Browse..."
+        label_color="White"
+        label_selected="Browse"
+        layout="topleft"
+        left_pad="5"
+        name="log_path_button"
+        top_delta="0"
+        width="112">
+      <commit_callback function="Pref.LogPath" />
+    </button>
+
+  </panel>
   
   <button
-      follows="left|top"
       height="23"
       label="Translation..."
       layout="topleft"
@@ -370,11 +472,10 @@
       name="ok_btn"
       top="-29"
       width="170">
-    <button.commit_callback
+    <commit_callback
         function="Pref.TranslationSettings" />
   </button>
   <button
-      follows="top|left"
       height="23"
       layout="topleft"
       top_pad="-23"
@@ -385,7 +486,6 @@
       width="150">
   </button>
   <button
-      follows="top|left"
       height="23"
       layout="topleft"
       top_pad="-23"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 587c461bee..78743d26bb 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -1,72 +1,69 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Communication"
- layout="topleft"
- left="102"
- name="im"
- top="1"
- width="517">
-    <panel.string
-     name="log_in_to_change">
-        log in to change
-    </panel.string>
-    <button
-     follows="left|bottom"
-     height="23"
-     label="Clear History"
-     tool_tip="Clear login image, last location, teleport history, web, and texture cache"
-     layout="topleft"
-     left="30"
-     name="clear_cache"
-     top="10"
-     width="145">
-        <button.commit_callback
-         function="Pref.WebClearCache" />
-    </button>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="10"
-     mouse_opaque="false"
-     name="cache_size_label_l"
-     top_delta="3"
-     text_color="LtGray_50"
-     width="300">
-       (Locations, images, web, search history)
-    </text>
-    <check_box
-	 height="16"
-     enabled="false"
-     label="Show me in Search results"
-     layout="topleft"
-     left="30"
-     name="online_searchresults"
-     top_pad="20"
-     width="350" />
-    <check_box
-	 height="16"
-	 enabled="false"
-     label="Only friends and groups know I'm online"
-     layout="topleft"
-     left="30"
-     name="online_visibility"
-     top_pad="30"
-     width="350" />
-    <check_box
-     control_name="VoiceCallsFriendsOnly"
-     height="16"
-     label="Only friends and groups can call or IM me"
-     layout="topleft"
-     left="30"
-     name="voice_call_friends_only_check"
-     top_pad="10"
-     width="350" />
+    border="true"
+    follows="left|top|right|bottom"
+    height="408"
+    label="Communication"
+    layout="topleft"
+    left="102"
+    name="im"
+    top="1"
+    width="517">
+
+  <panel.string
+      name="log_in_to_change">
+    log in to change
+  </panel.string>
+
+  <button
+      follows="left|bottom"
+      height="23"
+      label="Clear History"
+      tool_tip="Clear login image, last location, teleport history, web, and texture cache"
+      layout="topleft"
+      left="30"
+      name="clear_cache"
+      top="10"
+      width="145">
+    <button.commit_callback
+        function="Pref.WebClearCache" />
+  </button>
+
+  <text
+      type="string"
+      length="1"
+      follows="left|top"
+      height="10"
+      layout="topleft"
+      left_pad="10"
+      mouse_opaque="false"
+      name="cache_size_label_l"
+      top_delta="3"
+      text_color="LtGray_50"
+      width="300">
+    (Locations, images, web, search history)
+  </text>
+
+  <check_box
+      height="16"
+      enabled="false"
+      label="Show me in Search results"
+      layout="topleft"
+      left="30"
+      name="online_searchresults"
+      top_pad="20"
+      width="350" />
+
+  <check_box
+      height="16"
+      enabled="false"
+      label="Only friends and groups know I'm online"
+      layout="topleft"
+      left="30"
+      name="online_visibility"
+      top_pad="30"
+      width="350" />
+    
     <check_box
      enabled_control="EnableVoiceChat"
      control_name="AutoDisengageMic"
@@ -87,100 +84,7 @@
      name="favorites_on_login_check"
      top_pad="10"
      width="350" />
-	<text
-      type="string"
-    length="1"
-    follows="left|top"
-     height="10"
-     layout="topleft"
-     left="30"
-     mouse_opaque="false"
-     name="Logs:"
-     top_pad="20"
-     width="350">
-        Chat Logs:
-    </text>
-    <check_box
-	 enabled="false"
-     control_name="LogNearbyChat"
-     height="16"
-     label="Save nearby chat logs on my computer"
-     layout="topleft"
-     left="30"
-     name="log_nearby_chat"
-     top_pad="10"
-     width="350">
-    </check_box>
-    <check_box
-	 enabled="false"
-     control_name="LogInstantMessages"
-     height="16"
-     label="Save IM logs on my computer"
-     layout="topleft"
-     left="30"
-     name="log_instant_messages"
-     top_pad="10"
-     width="350">
-    </check_box>
-    <check_box
-     control_name="LogTimestamp"
-	 enabled="false"
-     height="16"
-     label="Add timestamp to each line in chat log"
-     layout="topleft"
-     left_delta="0"
-     name="show_timestamps_check_im"
-     top_pad="10"
-     width="237" />
-	<check_box
-     control_name="LogFileNamewithDate"
-     enabled="false"
-     height="16"
-     label="Add datestamp to log file name."
-     layout="topleft"
-     left_delta="5"
-     name="logfile_name_datestamp"
-     top_pad="10"
-     width="350"/>
-	<text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_delta="0"
-     mouse_opaque="false"
-     name="log_path_desc"
-     top_pad="30"
-     width="128">
-        Location of logs:
-    </text>    
-    <line_editor
-     bottom="366"
-     control_name="InstantMessageLogPath"
-     follows="top|left|right"
-     halign="right"
-     height="23"
-     layout="topleft"
-     left_delta="0"
-     mouse_opaque="false"
-     name="log_path_string"
-     top_pad="5"
-     width="250"/>
-    <button
-	 enabled="false"
-     follows="right|bottom"
-     height="23"
-     label="Browse"
-     label_selected="Browse"
-     layout="topleft"
-     left_pad="5"
-     name="log_path_button"
-     top_delta="0"
-     width="145">
-        <button.commit_callback
-         function="Pref.LogPath" />
-    </button>
+
     <button
      follows="left|bottom"
      height="23"
-- 
cgit v1.2.3


From d67804543d4042c1196c05db5303b76089d4ade2 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 25 Jan 2013 01:57:56 +0000
Subject: CHUI-291 FIX New auto-replace feature does not work with chui text
 input boxes in conversation floater Fixed autoreplace in LLTextEditor so it
 updates correctly and works with undo

---
 indra/llui/lltexteditor.cpp             | 24 +++++++++++++++++-------
 indra/llui/lltexteditor.h               |  8 ++++----
 indra/newview/llfloaterimnearbychat.cpp |  4 ++--
 3 files changed, 23 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index d297e54f2f..42c5f150dc 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -246,8 +246,8 @@ LLTextEditor::Params::Params()
 }
 
 LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
-    LLTextBase(p),
-    mAutoreplaceCallback(),
+	LLTextBase(p),
+	mAutoreplaceCallback(),
 	mBaseDocIsPristine(TRUE),
 	mPristineCmd( NULL ),
 	mLastCmd( NULL ),
@@ -1099,11 +1099,21 @@ void LLTextEditor::addChar(llwchar wc)
 
 	setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
 
-    if (!mReadOnly && mAutoreplaceCallback != NULL)
-    {
-        // call callback
-        mAutoreplaceCallback(getViewModel()->getEditableDisplay(), mCursorPos);
-    }
+	if (!mReadOnly && mAutoreplaceCallback != NULL)
+	{
+		// autoreplace on a copy of the text (so we can go through proper channels to set it later)
+		LLWString new_text(getWText());
+		S32 new_cursor_pos(mCursorPos);
+		mAutoreplaceCallback(new_text, new_cursor_pos);
+		
+		if (new_text != getWText())
+		{
+			// setText() might be simpler here but it wipes the undo stack (bad)
+			remove(0, getWText().length(), true);
+			insert(0, new_text, false, LLTextSegmentPtr());
+			setCursorPos(new_cursor_pos);
+		}
+	}
 }
 
 void LLTextEditor::addLineBreakChar()
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index ae5a983b60..7f0dbc9865 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -157,10 +157,10 @@ public:
 	BOOL			isPristine() const;
 	BOOL			allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
 
-    // Autoreplace (formerly part of LLLineEditor)
-    typedef boost::function<void(LLWString&, S32&)> autoreplace_callback_t;
-    autoreplace_callback_t mAutoreplaceCallback;
-    void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
+	// Autoreplace (formerly part of LLLineEditor)
+	typedef boost::function<void(LLWString&, S32&)> autoreplace_callback_t;
+	autoreplace_callback_t mAutoreplaceCallback;
+	void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
 
 	//
 	// Text manipulation
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 73eb822036..38f49e76d4 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -112,8 +112,8 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 {
     setIsSingleInstance(TRUE);
     BOOL result = LLFloaterIMSessionTab::postBuild();
-	
-    mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
+
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
 	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
 	mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
 	mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
-- 
cgit v1.2.3


From 163f3de73d93be8f5e482be03a1952244cadee68 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 25 Jan 2013 19:53:12 +0000
Subject: CHUI-291 FIX New auto-replace feature does not work with chui text
 input boxes in conversation floater Modified LLAutoReplace to pass back a
 string for replacement instead of modifying the input string

---
 indra/llui/lltexteditor.cpp             | 19 +++++-----
 indra/llui/lltexteditor.h               |  2 +-
 indra/newview/llautoreplace.cpp         | 65 ++++++++++++++++++---------------
 indra/newview/llautoreplace.h           |  5 ++-
 indra/newview/llfloaterimnearbychat.cpp |  2 +-
 indra/newview/llfloaterimsession.cpp    |  2 +-
 6 files changed, 51 insertions(+), 44 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 42c5f150dc..562bbc7100 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1101,16 +1101,17 @@ void LLTextEditor::addChar(llwchar wc)
 
 	if (!mReadOnly && mAutoreplaceCallback != NULL)
 	{
-		// autoreplace on a copy of the text (so we can go through proper channels to set it later)
-		LLWString new_text(getWText());
-		S32 new_cursor_pos(mCursorPos);
-		mAutoreplaceCallback(new_text, new_cursor_pos);
-		
-		if (new_text != getWText())
+		// autoreplace the text, if necessary
+		S32 replacement_start;
+		S32 replacement_length;
+		LLWString replacement_string;
+		S32 new_cursor_pos = mCursorPos;
+		mAutoreplaceCallback(replacement_start, replacement_length, replacement_string, new_cursor_pos, getWText());
+
+		if (replacement_length > 0 || !replacement_string.empty())
 		{
-			// setText() might be simpler here but it wipes the undo stack (bad)
-			remove(0, getWText().length(), true);
-			insert(0, new_text, false, LLTextSegmentPtr());
+			remove(replacement_start, replacement_length, true);
+			insert(replacement_start, replacement_string, false, LLTextSegmentPtr());
 			setCursorPos(new_cursor_pos);
 		}
 	}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 7f0dbc9865..5e189070fa 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -158,7 +158,7 @@ public:
 	BOOL			allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
 
 	// Autoreplace (formerly part of LLLineEditor)
-	typedef boost::function<void(LLWString&, S32&)> autoreplace_callback_t;
+	typedef boost::function<void(S32&, S32&, LLWString&, S32&, const LLWString&)> autoreplace_callback_t;
 	autoreplace_callback_t mAutoreplaceCallback;
 	void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
 
diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
index 94773e312c..1d72397cbc 100644
--- a/indra/newview/llautoreplace.cpp
+++ b/indra/newview/llautoreplace.cpp
@@ -32,53 +32,58 @@
 
 const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml";
 
-void LLAutoReplace::autoreplaceCallback(LLWString& inputText, S32& cursorPos)
+void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text)
 {
+	// make sure these returned values are cleared in case there is no replacement
+	replacement_start = 0;
+	replacement_length = 0;
+	replacement_string.clear();
+
 	static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
-	if(perform_autoreplace)
+	if (perform_autoreplace)
 	{
-		S32 wordEnd = cursorPos-1;
+		S32 word_end = cursor_pos - 1;
 
-		bool atSpace  = (inputText[wordEnd] == ' ');
-		bool haveWord = (LLWStringUtil::isPartOfWord(inputText[wordEnd]));
+		bool at_space  = (input_text[word_end] == ' ');
+		bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end]));
 
-		if (atSpace || haveWord)
+		if (at_space || have_word)
 		{
-			if (atSpace && wordEnd > 0)
+			if (at_space && word_end > 0)
 			{
 				// find out if this space immediately follows a word
-				wordEnd--;
-				haveWord  = (LLWStringUtil::isPartOfWord(inputText[wordEnd]));
+				word_end--;
+				have_word  = (LLWStringUtil::isPartOfWord(input_text[word_end]));
 			}
-			if (haveWord)
+			if (have_word)
 			{
-				// wordEnd points to the end of a word, now find the start of the word
+				// word_end points to the end of a word, now find the start of the word
 				std::string word;
-				S32 wordStart = wordEnd;
-				for ( S32 backOne = wordStart - 1;
-					  backOne >= 0 && LLWStringUtil::isPartOfWord(inputText[backOne]);
-					  backOne--
-					 )
+				S32 word_start = word_end;
+				for (S32 back_one = word_start - 1;
+					 back_one >= 0 && LLWStringUtil::isPartOfWord(input_text[back_one]);
+					 back_one--
+					)
 				{
-					wordStart--; // walk wordStart back to the beginning of the word
+					word_start--; // walk word_start back to the beginning of the word
 				}
-				LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL;
-				std::string strText  = std::string(inputText.begin(), inputText.end());
-				std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1);
-				std::string replacementWord( mSettings.replaceWord( lastWord ) );
+				LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL;
+				std::string str_text  = std::string(input_text.begin(), input_text.end());
+				std::string last_word = str_text.substr(word_start, word_end - word_start + 1);
+				std::string replacement_word(mSettings.replaceWord(last_word));
 
-				if ( replacementWord != lastWord )
+				if (replacement_word != last_word)
 				{
 					// The last word is one for which we have a replacement
-					if (atSpace)
+					if (at_space)
 					{
-						// replace the last word in the input
-						LLWString strNew = utf8str_to_wstring(replacementWord);
-						LLWString strOld = utf8str_to_wstring(lastWord);
-						int size_change = strNew.size() - strOld.size();
-
-						inputText.replace(wordStart,lastWord.length(),strNew);
-						cursorPos+=size_change;
+						// return the replacement string
+						replacement_start = word_start;
+						replacement_length = last_word.length();
+						replacement_string = utf8str_to_wstring(replacement_word);
+						LLWString old_string = utf8str_to_wstring(last_word);
+						S32 size_change = replacement_string.size() - old_string.size();
+						cursor_pos += size_change;
 					}
 				}
 			}
diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h
index bbb86294bc..9eecc2d981 100644
--- a/indra/newview/llautoreplace.h
+++ b/indra/newview/llautoreplace.h
@@ -183,7 +183,8 @@ class LLAutoReplaceSettings
  * When the end of a word is detected (defined as any punctuation character,
  * or any whitespace except newline or return), the preceding word is used
  * as a lookup key in an ordered list of maps.  If a match is found in any
- * map, the keyword is replaced by the associated value from the map.
+ * map, the replacement start index and length are returned along with the
+ * new replacement string.
  *
  * See the autoreplaceCallback method for how to add autoreplace functionality
  * to a text entry tool.
@@ -192,7 +193,7 @@ class LLAutoReplace : public LLSingleton<LLAutoReplace>
 {
 public:
     /// Callback that provides the hook for use in text entry methods
-    void autoreplaceCallback(LLWString& inputText, S32& cursorPos);
+    void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text);
 
     /// Get a copy of the current settings
     LLAutoReplaceSettings getSettings();
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 38f49e76d4..a2dfd4b53e 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -113,7 +113,7 @@ BOOL LLFloaterIMNearbyChat::postBuild()
     setIsSingleInstance(TRUE);
     BOOL result = LLFloaterIMSessionTab::postBuild();
 
-	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
 	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
 	mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
 	mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a2c7bacb5d..a08479c7be 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -332,7 +332,7 @@ BOOL LLFloaterIMSession::postBuild()
 	BOOL result = LLFloaterIMSessionTab::postBuild();
 
 	mInputEditor->setMaxTextLength(1023);
-	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
 	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
 	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
 	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
-- 
cgit v1.2.3


From fa54b50e029c963d90b5533174a29eefc22227e5 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Sat, 26 Jan 2013 00:19:29 +0000
Subject: CHUI-644 FIX [CHUIBUG]Received IM's Don't Always Appear in
 Communication Console Immediately. Added call to
 LLFloaterIMContainer::selectConversation() in on_new_message for LLIMView

---
 indra/newview/llimview.cpp | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cb03c1d234..c94f2e967e 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -144,7 +144,7 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	args["FROM"] = av_name.getCompleteName();
 	args["FROM_ID"] = msg["from_id"];
 	args["SESSION_ID"] = msg["session_id"];
-	LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
+	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
 void on_new_message(const LLSD& msg)
@@ -239,6 +239,12 @@ void on_new_message(const LLSD& msg)
                 {
                     LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
                 }
+
+				// Make sure the message actually appears, without having to click on the conversation
+				if(!conversation_floater_is_closed)
+				{
+					im_box->selectConversation(session_id);
+				}
             }
         }
     }
@@ -276,9 +282,9 @@ void on_new_message(const LLSD& msg)
 
             if(!gAgent.isDoNotDisturb())
             {
-            //Surface conversations floater
-            LLFloaterReg::showInstance("im_container");
-        }
+				//Surface conversations floater
+				LLFloaterReg::showInstance("im_container");
+			}
 
             //If in DND mode, allow notification to be stored so upon DND exit 
             //useMostItrusiveIMNotification will be called to notify user a message exists
@@ -287,8 +293,8 @@ void on_new_message(const LLSD& msg)
                 && gAgent.isDoNotDisturb())
             {
                 LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
-    }
-}
+			}
+		}
     }
 }
 
-- 
cgit v1.2.3


From c1b8e4b1ffcb9c759d109d603004f363dbb0df63 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Sat, 26 Jan 2013 00:36:49 +0000
Subject: undid accidental revert of someone else's fix

---
 indra/newview/llimview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c94f2e967e..acbf5fcde4 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -144,7 +144,7 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	args["FROM"] = av_name.getCompleteName();
 	args["FROM_ID"] = msg["from_id"];
 	args["SESSION_ID"] = msg["session_id"];
-	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
+	LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
 void on_new_message(const LLSD& msg)
-- 
cgit v1.2.3


From c418d616276ce16d910c6e5528f6aa058803e1c7 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 25 Jan 2013 17:47:36 -0800
Subject: CHUI-667 Upon exit from DND mode, a maximum of one sound should be
 played. Solution. Added a deferred sound class which will have sound id's
 added to it and upon unmuting the deferred sounds will be played.

---
 indra/llui/llui.cpp                                | 31 +++++++++++++--
 indra/llui/llui.h                                  |  3 ++
 indra/newview/CMakeLists.txt                       |  2 +
 indra/newview/llappviewer.cpp                      | 14 ++++++-
 indra/newview/lldeferredsounds.cpp                 | 45 ++++++++++++++++++++++
 indra/newview/lldeferredsounds.h                   | 44 +++++++++++++++++++++
 .../newview/lldonotdisturbnotificationstorage.cpp  | 20 ++++++++++
 indra/newview/llnotificationofferhandler.cpp       |  3 +-
 indra/newview/llprogressview.cpp                   |  4 +-
 indra/newview/llvieweraudio.cpp                    |  7 ++++
 10 files changed, 165 insertions(+), 8 deletions(-)
 create mode 100644 indra/newview/lldeferredsounds.cpp
 create mode 100644 indra/newview/lldeferredsounds.h

(limited to 'indra')

diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index ee09625890..2a774d54a3 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -77,6 +77,7 @@ std::list<std::string> gUntranslated;
 /*static*/ LLUI::settings_map_t LLUI::sSettingGroups;
 /*static*/ LLImageProviderInterface* LLUI::sImageProvider = NULL;
 /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
+/*static*/ LLUIAudioCallback LLUI::sDeferredAudioCallback = NULL;
 /*static*/ LLVector2		LLUI::sGLScaleFactor(1.f, 1.f);
 /*static*/ LLWindow*		LLUI::sWindow = NULL;
 /*static*/ LLView*			LLUI::sRootView = NULL;
@@ -101,16 +102,18 @@ static LLDefaultChildRegistry::Register<LLToolBar> register_toolbar("toolbar");
 //
 // Functions
 //
-void make_ui_sound(const char* namep)
+
+LLUUID find_ui_sound(const char * namep)
 {
 	std::string name = ll_safe_string(namep);
+	LLUUID uuid = LLUUID(NULL);
 	if (!LLUI::sSettingGroups["config"]->controlExists(name))
 	{
 		llwarns << "tried to make UI sound for unknown sound name: " << name << llendl;	
 	}
 	else
 	{
-		LLUUID uuid(LLUI::sSettingGroups["config"]->getString(name));
+		uuid = LLUUID(LLUI::sSettingGroups["config"]->getString(name));
 		if (uuid.isNull())
 		{
 			if (LLUI::sSettingGroups["config"]->getString(name) == LLUUID::null.asString())
@@ -124,7 +127,6 @@ void make_ui_sound(const char* namep)
 			{
 				llwarns << "UI sound named: " << name << " does not translate to a valid uuid" << llendl;	
 			}
-
 		}
 		else if (LLUI::sAudioCallback != NULL)
 		{
@@ -132,9 +134,28 @@ void make_ui_sound(const char* namep)
 			{
 				llinfos << "UI sound name: " << name << llendl;	
 			}
-			LLUI::sAudioCallback(uuid);
 		}
 	}
+
+	return uuid;
+}
+
+void make_ui_sound(const char* namep)
+{
+	LLUUID soundUUID = find_ui_sound(namep);
+	if(soundUUID.notNull())
+	{
+		LLUI::sAudioCallback(soundUUID);
+	}
+}
+
+void make_ui_sound_deferred(const char* namep)
+{
+	LLUUID soundUUID = find_ui_sound(namep);
+	if(soundUUID.notNull())
+	{
+		LLUI::sDeferredAudioCallback(soundUUID);
+	}
 }
 
 BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
@@ -1608,6 +1629,7 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv
 void LLUI::initClass(const settings_map_t& settings,
 					 LLImageProviderInterface* image_provider,
 					 LLUIAudioCallback audio_callback,
+					 LLUIAudioCallback deferred_audio_callback,
 					 const LLVector2* scale_factor,
 					 const std::string& language)
 {
@@ -1622,6 +1644,7 @@ void LLUI::initClass(const settings_map_t& settings,
 
 	sImageProvider = image_provider;
 	sAudioCallback = audio_callback;
+	sDeferredAudioCallback = deferred_audio_callback;
 	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
 	sWindow = NULL; // set later in startup
 	LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index e54cae1d78..4c1703392a 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -62,6 +62,7 @@ class LLHelp;
 // UI colors
 extern const LLColor4 UI_VERTEX_COLOR;
 void make_ui_sound(const char* name);
+void make_ui_sound_deferred(const char * name);
 
 BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
 void gl_state_for_2d(S32 width, S32 height);
@@ -274,6 +275,7 @@ public:
 	static void initClass(const settings_map_t& settings,
 						  LLImageProviderInterface* image_provider,
 						  LLUIAudioCallback audio_callback = NULL,
+						  LLUIAudioCallback deferred_audio_callback = NULL,
 						  const LLVector2 *scale_factor = NULL,
 						  const std::string& language = LLStringUtil::null);
 	static void cleanupClass();
@@ -359,6 +361,7 @@ public:
 	//
 	static settings_map_t sSettingGroups;
 	static LLUIAudioCallback sAudioCallback;
+	static LLUIAudioCallback sDeferredAudioCallback;
 	static LLVector2		sGLScaleFactor;
 	static LLWindow*		sWindow;
 	static LLView*			sRootView;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d40537fc78..bd4cdac5f2 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -151,6 +151,7 @@ set(viewer_SOURCE_FILES
     lldaycyclemanager.cpp
     lldebugmessagebox.cpp
     lldebugview.cpp
+    lldeferredsounds.cpp
     lldelayedgestureerror.cpp
     lldirpicker.cpp
     lldonotdisturbnotificationstorage.cpp
@@ -739,6 +740,7 @@ set(viewer_HEADER_FILES
     lldaycyclemanager.h
     lldebugmessagebox.h
     lldebugview.h
+    lldeferredsounds.h
     lldelayedgestureerror.h
     lldirpicker.h
     lldonotdisturbnotificationstorage.h
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 3c42734e6e..a291fac5a1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -201,6 +201,7 @@
 #include "llviewercontrol.h"
 #include "lleventnotifier.h"
 #include "llcallbacklist.h"
+#include "lldeferredsounds.h"
 #include "pipeline.h"
 #include "llgesturemgr.h"
 #include "llsky.h"
@@ -220,6 +221,7 @@
 #include "llmachineid.h"
 #include "llmainlooprepeater.h"
 
+#include <queue>
 
 // *FIX: These extern globals should be cleaned up.
 // The globals either represent state/config/resource-storage of either 
@@ -456,7 +458,7 @@ void idle_afk_check()
 }
 
 // A callback set in LLAppViewer::init()
-static void ui_audio_callback(const LLUUID& uuid)
+void ui_audio_callback(const LLUUID& uuid)
 {
 	if (gAudiop)
 	{
@@ -464,6 +466,15 @@ static void ui_audio_callback(const LLUUID& uuid)
 	}
 }
 
+// A callback set in LLAppViewer::init()
+static void deferred_ui_audio_callback(const LLUUID& uuid)
+{
+	if (gAudiop)
+	{
+		LLDeferredSounds::instance().deferSound(uuid);
+	}
+}
+
 bool	create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base)
 {
 	if(!match || !base || base->getPlainText())
@@ -778,6 +789,7 @@ bool LLAppViewer::init()
 	LLUI::initClass(settings_map,
 		LLUIImageList::getInstance(),
 		ui_audio_callback,
+		deferred_ui_audio_callback,
 		&LLUI::sGLScaleFactor);
 	LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
 
diff --git a/indra/newview/lldeferredsounds.cpp b/indra/newview/lldeferredsounds.cpp
new file mode 100644
index 0000000000..2b2b493875
--- /dev/null
+++ b/indra/newview/lldeferredsounds.cpp
@@ -0,0 +1,45 @@
+/** 
+* @file lldeferredsounds.cpp
+* @brief Implementation of lldeferredsounds
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldeferredsounds.h"
+
+void ui_audio_callback(const LLUUID& uuid);
+
+void LLDeferredSounds::deferSound(LLUUID sound)
+{
+	soundQueue.push(sound);
+}
+void LLDeferredSounds::playdeferredSounds()
+{
+	while(soundQueue.size())
+	{
+		ui_audio_callback(soundQueue.front());
+		soundQueue.pop();
+	}
+}
diff --git a/indra/newview/lldeferredsounds.h b/indra/newview/lldeferredsounds.h
new file mode 100644
index 0000000000..50da9acf2b
--- /dev/null
+++ b/indra/newview/lldeferredsounds.h
@@ -0,0 +1,44 @@
+/** 
+* @file   lldeferredsounds.h
+* @brief  Header file for lldeferredsounds
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLDEFERREDSOUNDS_H
+#define LL_LLDEFERREDSOUNDS_H
+
+#include "llsingleton.h"
+
+class LLDeferredSounds : public LLSingleton<LLDeferredSounds>
+{
+private:
+	std::queue<LLUUID> soundQueue;
+public:
+	//Add sounds to be played once progress bar is hidden (such as after teleport or loading screen)
+	void deferSound(LLUUID sound);
+
+	void playdeferredSounds();
+};
+
+#endif // LL_LLDEFERREDSOUNDS_H
+
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 15c42e8285..6e39d049a5 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -146,6 +146,7 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 	
 	LLNotifications& instance = LLNotifications::instance();
     bool imToastExists = false;
+    bool offerExists = false;
 	
 	for (LLSD::array_const_iterator notification_it = data.beginArray();
 		 notification_it != data.endArray();
@@ -160,6 +161,10 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
         {
             imToastExists = true;
         }
+        else if(notificationName == offerName)
+        {
+            offerExists = true;
+        }
 
         //New notification needs to be added
         notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
@@ -183,6 +188,11 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
         LLFloaterReg::showInstance("im_container");
     }
 
+    if(imToastExists || offerExists)
+    {
+		make_ui_sound_deferred("UISndNewIncomingIMSession");
+    }
+
     //writes out empty .xml file (since LLCommunicationChannel::mHistory is empty)
 	saveNotifications();
 }
@@ -196,6 +206,7 @@ void LLDoNotDisturbNotificationStorage::updateNotifications()
 
     LLNotifications& instance = LLNotifications::instance();
     bool imToastExists = false;
+    bool offerExists = false;
   
     for (LLCommunicationChannel::history_list_t::const_iterator it = commChannel->beginHistory();
         it != commChannel->endHistory();
@@ -208,6 +219,10 @@ void LLDoNotDisturbNotificationStorage::updateNotifications()
         {
             imToastExists = true;
         }
+        else if(notificationName == offerName)
+        {
+            offerExists = true;
+        }
 
         //Notification already exists in notification pipeline (same instance of app running)
         if (notification)
@@ -222,6 +237,11 @@ void LLDoNotDisturbNotificationStorage::updateNotifications()
         LLFloaterReg::showInstance("im_container");
     }
 
+    if(imToastExists || offerExists)
+    {
+        make_ui_sound("UISndNewIncomingIMSession");
+    }
+
     //When exit DND mode, write empty notifications file
     if(commChannel->getHistorySize())
     {
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index da38c9063b..cde7bb18ce 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -120,7 +120,8 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 				channel->addToast(p);
 
             //Will not play a notification sound for inventory and teleport offer based upon chat preference
-            bool playSound = !((notification->getName() == "UserGiveItem"
+            bool playSound = !((notification->isDND())
+                               && (notification->getName() == "UserGiveItem"
                                     && gSavedSettings.getBOOL("PlaySoundInventoryOffer") == FALSE)
                                 ||  notification->getName() == "TeleportOffered"
                                     && gSavedSettings.getBOOL("PlaySoundTeleportOffer") == FALSE);
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index f86e583b9e..989f0b0e60 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -96,7 +96,7 @@ BOOL LLProgressView::postBuild()
 	getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this);
 
 	// hidden initially, until we need it
-	LLPanel::setVisible(FALSE);
+	setVisible(FALSE);
 
 	LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLProgressView::onAlertModal, this, _1));
 
@@ -265,7 +265,7 @@ void LLProgressView::draw()
 			gFocusMgr.releaseFocusIfNeeded( this );
 
 			// turn off panel that hosts intro so we see the world
-			LLPanel::setVisible(FALSE);
+			setVisible(FALSE);
 
 			// stop observing events since we no longer care
 			mMediaCtrl->remObserver( this );
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 8d8c401dac..564bf7997a 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -30,6 +30,7 @@
 #include "llagent.h"
 #include "llagentcamera.h"
 #include "llappviewer.h"
+#include "lldeferredsounds.h"
 #include "llvieweraudio.h"
 #include "llviewercamera.h"
 #include "llviewercontrol.h"
@@ -388,6 +389,12 @@ void audio_update_volume(bool force_update)
 		gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
 		gAudiop->setMuted(mute_audio || progress_view_visible);
 		
+		//Play any deferred sounds when unmuted
+		if(!gAudiop->getMuted())
+		{
+			LLDeferredSounds::instance().playdeferredSounds();
+		}
+
 		if (force_update)
 		{
 			audio_update_wind(true);
-- 
cgit v1.2.3


From aa524b18e5486b19aede990cb30fb89a0b48c083 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Mon, 28 Jan 2013 14:57:51 +0200
Subject: CHUI-701 FIXED Don't show toasts and flashing, if conversation is
 opened but isn't focused.

---
 indra/newview/llfloaterimnearbychathandler.cpp |  8 ++++++++
 indra/newview/llimview.cpp                     | 19 ++++++++-----------
 2 files changed, 16 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index f64cfd0245..8870d54cd2 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -604,6 +604,14 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
 			toast_msg = chat_msg.mText;
 		}
 
+		//Don't show nearby toast, if conversation is visible but not focused
+		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(LLUUID());
+		if (session_floater
+		    && session_floater->isInVisibleChain() && !session_floater->isMinimized()
+		    && !(session_floater->getHost() && session_floater->getHost()->isMinimized()))
+		{
+			return;
+		}
 
         //Will show toast when chat preference is set        
         if(gSavedSettings.getString("NotificationNearbyChatOptions") == "toast")
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cb03c1d234..433ddad35d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -204,19 +204,16 @@ void on_new_message(const LLSD& msg)
     bool conversation_floater_not_focused =
     		conversation_floater_is_closed || !im_box->hasFocus();
 
+    // Skip toasting and flashing if we have open window of IM with this session id
+    if (session_floater
+    && session_floater->isInVisibleChain()
+    && !session_floater->isMinimized()
+    && !(session_floater->getHost() && session_floater->getHost()->isMinimized()))
+    {
+       return;
+    }
     if ("toast" == action)
     {
-        // Skip toasting and flashing if we have open window of IM with this session id
-        if (session_floater
-            && session_floater->isInVisibleChain()
-            && session_floater->hasFocus()
-            && !session_floater->isMinimized()
-            && !(session_floater->getHost() && session_floater->getHost()->isMinimized())
-            )
-        {
-            return;
-        }
-
         //User is not focused on conversation containing the message
         if(session_floater_not_focused)
         {
-- 
cgit v1.2.3


From 4a96941b73254538c27a83fe28c637065e93f2e2 Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Mon, 28 Jan 2013 18:06:27 +0200
Subject: CHUI-395 (Group moderators are not shown as Moderators in group
 conversation)

---
 indra/newview/llconversationmodel.cpp   | 18 ++++++++++++++++++
 indra/newview/llconversationmodel.h     |  6 ++++--
 indra/newview/llfloaterimsessiontab.cpp | 22 ++++++++++++++++++++++
 3 files changed, 44 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index a8da4908ce..7184a70db5 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -35,6 +35,7 @@
 #include "llsdutil.h"
 #include "llconversationmodel.h"
 #include "llimview.h" //For LLIMModel
+#include "lltrans.h"
 
 //
 // Conversation items : common behaviors
@@ -461,6 +462,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 	LLConversationItem(display_name,uuid,root_view_model),
 	mIsMuted(false),
 	mIsModerator(false),
+	mDisplayModeratorLabel(false),
 	mDistToAgent(-1.0)
 {
 	mDisplayName = display_name;
@@ -471,6 +473,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid,
 	LLConversationItem(uuid,root_view_model),
 	mIsMuted(false),
 	mIsModerator(false),
+	mDisplayModeratorLabel(false),
 	mDistToAgent(-1.0)
 {
 	mConvType = CONV_PARTICIPANT;
@@ -503,6 +506,12 @@ void LLConversationItemParticipant::updateName(const LLAvatarName& av_name)
 {
 	mName = av_name.getUserName();
 	mDisplayName = av_name.getDisplayName();
+	
+	if (mDisplayModeratorLabel)
+	{
+		mDisplayName += " " + LLTrans::getString("IM_moderator_label");
+	}
+	
 	renameItem(mDisplayName);
 	if (mParent != NULL)
 	{
@@ -541,6 +550,15 @@ void LLConversationItemParticipant::dumpDebugData()
 	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
 }
 
+void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole)
+{ 
+	if (displayRole != mDisplayModeratorLabel)
+	{
+		mDisplayModeratorLabel = displayRole;
+		updateName();
+	}
+}
+
 //
 // LLConversationSort
 // 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 6aaea041e4..c907d1d6d2 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -205,13 +205,15 @@ public:
 
 	void dumpDebugData();
 	void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; }
+	void setDisplayModeratorRole(bool displayRole);
 
 private:
 	void onAvatarNameCache(const LLAvatarName& av_name);	// callback used by fetchAvatarName
 	void updateName(const LLAvatarName& av_name);
 
-	bool mIsMuted;		// default is false
-	bool mIsModerator;	// default is false
+	bool mIsMuted;		         // default is false
+	bool mIsModerator;	         // default is false
+	bool mDisplayModeratorLabel; // default is false
 	std::string mDisplayName;
 	F64  mDistToAgent;  // Distance to the agent. A negative (meaningless) value means the distance has not been set.
 	boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 37404ab716..2f6a9d22c1 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -497,6 +497,28 @@ void LLFloaterIMSessionTab::refreshConversation()
 		}
 		updateSessionName(session_name);
 	}
+
+	LLParticipantList* participant_list = getParticipantList();
+	if (participant_list)
+	{
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = participant_list->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = participant_list->getChildrenEnd();
+		LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+			if (speaker_mgr && participant_model)
+			{
+				LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID());
+				LLSpeaker *agent_speaker = speaker_mgr->findSpeaker(gAgentID);
+				if (participant_speaker && agent_speaker)
+				{
+					participant_model->setDisplayModeratorRole(agent_speaker->mIsModerator && participant_speaker->mIsModerator);
+				}
+			}
+			current_participant_model++;
+		}
+	}
 	
 	mConversationViewModel.requestSortAll();
 	if(mConversationsRoot != NULL)
-- 
cgit v1.2.3


From 57795d3c89b6eee3ff68f327d2a6c840350d8dcb Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Mon, 28 Jan 2013 18:53:46 +0200
Subject: CHUI-706 FIXED Appropriate function is now called in xml

---
 indra/newview/skins/default/xui/en/menu_url_group.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_url_group.xml b/indra/newview/skins/default/xui/en/menu_url_group.xml
index 2cb125ce09..c5eaf94d22 100644
--- a/indra/newview/skins/default/xui/en/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_group.xml
@@ -7,7 +7,7 @@
      layout="topleft"
      name="show_group">
         <menu_item_call.on_click
-         function="Url.ShowProfile" />
+         function="Url.Execute" />
     </menu_item_call>
     <menu_item_separator
      layout="topleft" />
-- 
cgit v1.2.3


From af969270990ca719277def274b8ebf20539cc435 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 28 Jan 2013 15:41:01 -0800
Subject: Fix test failure

---
 indra/viewer_components/updater/tests/llupdaterservice_test.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index a49bc4161e..de07beee7c 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -83,6 +83,7 @@ std::string LLDir::getSkinFolder() const { return "default"; }
 std::string LLDir::getLanguage() const { return "en"; }
 bool LLDir::setCacheDir(const std::string &path){ return true; }
 void LLDir::dumpCurrentDirectories() {}
+void LLDir::updatePerAccountChatLogsDir() {}
 
 std::string LLDir::getExpandedFilename(ELLPath location, 
 									   const std::string &filename) const 
-- 
cgit v1.2.3


From 44b681f5db9435f98d52525621aa98b0a8ed3063 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Tue, 29 Jan 2013 00:16:40 +0000
Subject: CHUI-644 FIX [CHUIBUG]Received IM's Don't Always Appear in
 Communication Console Immediately. Removed new code from on_new_message in
 LLIMView and instead, changed condition in LLFloaterIMSession::newIMCallback
 to update messages whenever the floater is visible

---
 indra/newview/llfloaterimsession.cpp | 2 +-
 indra/newview/llimview.cpp           | 8 +-------
 2 files changed, 2 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a08479c7be..31d2c67e29 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -162,7 +162,7 @@ void LLFloaterIMSession::newIMCallback(const LLSD& data)
 		LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
 
         // update if visible, otherwise will be updated when opened
-		if (floater && (floater->getHost()? floater->hasFocus() : floater->getVisible()))
+		if (floater && floater->isInVisibleChain())
 		{
 			floater->updateMessages();
 		}
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index acbf5fcde4..ffbb8471c2 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -239,14 +239,8 @@ void on_new_message(const LLSD& msg)
                 {
                     LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
                 }
-
-				// Make sure the message actually appears, without having to click on the conversation
-				if(!conversation_floater_is_closed)
-				{
-					im_box->selectConversation(session_id);
-				}
             }
-        }
+		}
     }
 
     else if ("flash" == action)
-- 
cgit v1.2.3


From 4c5790d4bf24d80fd88f36e85a4aa51d4dc06c30 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 28 Jan 2013 18:27:54 -0800
Subject: CHUI-667: Post code review changes

---
 indra/llaudio/llaudioengine.cpp    |  4 ++++
 indra/llaudio/llaudioengine.h      | 24 ++++++++++++++++++++++++
 indra/newview/llappviewer.cpp      |  8 +++-----
 indra/newview/lldeferredsounds.cpp | 12 ++++++------
 indra/newview/lldeferredsounds.h   |  6 ++++--
 5 files changed, 41 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index ef560cd7fc..06e752cf34 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -839,6 +839,10 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
 	asp->play(audio_uuid);
 }
 
+void LLAudioEngine::triggerSound(SoundData& soundData)
+{
+	triggerSound(soundData.audio_uuid, soundData.owner_id, soundData.gain, soundData.type, soundData.pos_global);
+}
 
 void LLAudioEngine::setListenerPos(LLVector3 aVec)
 {
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index df1e4dc305..99b96c3c38 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -66,6 +66,7 @@ class LLAudioChannel;
 class LLAudioChannelOpenAL;
 class LLAudioBuffer;
 class LLStreamingAudioInterface;
+struct SoundData;
 
 
 //
@@ -144,6 +145,8 @@ public:
 	void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
 					  const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
 					  const LLVector3d &pos_global = LLVector3d::zero);
+	void triggerSound(SoundData& soundData);
+
 	bool preloadSound(const LLUUID &id);
 
 	void addAudioSource(LLAudioSource *asp);
@@ -456,6 +459,27 @@ protected:
 	LLFrameTimer mLastUseTimer;
 };
 
+struct SoundData
+{
+	LLUUID audio_uuid;
+	LLUUID owner_id;
+	F32 gain;
+	S32 type;
+	LLVector3d pos_global;
+
+	SoundData(const LLUUID &audio_uuid, 
+		const LLUUID& owner_id, 
+		const F32 gain, 					  
+		const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
+		const LLVector3d &pos_global = LLVector3d::zero)
+	{
+		this->audio_uuid = audio_uuid;
+		this->owner_id = owner_id;
+		this->gain = gain;
+		this->type = type;
+		this->pos_global = pos_global;
+	}
+};
 
 
 extern LLAudioEngine* gAudiop;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index a291fac5a1..d09c835e41 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -221,8 +221,6 @@
 #include "llmachineid.h"
 #include "llmainlooprepeater.h"
 
-#include <queue>
-
 // *FIX: These extern globals should be cleaned up.
 // The globals either represent state/config/resource-storage of either 
 // this app, or another 'component' of the viewer. App globals should be 
@@ -458,11 +456,11 @@ void idle_afk_check()
 }
 
 // A callback set in LLAppViewer::init()
-void ui_audio_callback(const LLUUID& uuid)
+static void ui_audio_callback(const LLUUID& uuid)
 {
 	if (gAudiop)
 	{
-		gAudiop->triggerSound(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+		gAudiop->triggerSound(SoundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI));
 	}
 }
 
@@ -471,7 +469,7 @@ static void deferred_ui_audio_callback(const LLUUID& uuid)
 {
 	if (gAudiop)
 	{
-		LLDeferredSounds::instance().deferSound(uuid);
+		LLDeferredSounds::instance().deferSound(SoundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI));
 	}
 }
 
diff --git a/indra/newview/lldeferredsounds.cpp b/indra/newview/lldeferredsounds.cpp
index 2b2b493875..9416e7cd29 100644
--- a/indra/newview/lldeferredsounds.cpp
+++ b/indra/newview/lldeferredsounds.cpp
@@ -29,17 +29,17 @@
 
 #include "lldeferredsounds.h"
 
-void ui_audio_callback(const LLUUID& uuid);
+#include "llaudioengine.h"
 
-void LLDeferredSounds::deferSound(LLUUID sound)
+void LLDeferredSounds::deferSound(SoundData& sound)
 {
-	soundQueue.push(sound);
+	soundVector.push_back(sound);
 }
 void LLDeferredSounds::playdeferredSounds()
 {
-	while(soundQueue.size())
+	while(soundVector.size())
 	{
-		ui_audio_callback(soundQueue.front());
-		soundQueue.pop();
+		gAudiop->triggerSound(soundVector.back());
+		soundVector.pop_back();
 	}
 }
diff --git a/indra/newview/lldeferredsounds.h b/indra/newview/lldeferredsounds.h
index 50da9acf2b..bf1eb62957 100644
--- a/indra/newview/lldeferredsounds.h
+++ b/indra/newview/lldeferredsounds.h
@@ -29,13 +29,15 @@
 
 #include "llsingleton.h"
 
+struct SoundData;
+
 class LLDeferredSounds : public LLSingleton<LLDeferredSounds>
 {
 private:
-	std::queue<LLUUID> soundQueue;
+	std::vector<SoundData> soundVector;
 public:
 	//Add sounds to be played once progress bar is hidden (such as after teleport or loading screen)
-	void deferSound(LLUUID sound);
+	void deferSound(SoundData& sound);
 
 	void playdeferredSounds();
 };
-- 
cgit v1.2.3


From e179add865fef30f6ad86ffd074f267fd01cb41d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 29 Jan 2013 11:02:23 -0800
Subject: CHUI-667: Attempting to correct Mac/Linux build issue.

---
 indra/newview/llappviewer.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d09c835e41..2fd9dd0dce 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -460,7 +460,8 @@ static void ui_audio_callback(const LLUUID& uuid)
 {
 	if (gAudiop)
 	{
-		gAudiop->triggerSound(SoundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI));
+		SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+		gAudiop->triggerSound(soundData);
 	}
 }
 
@@ -469,7 +470,8 @@ static void deferred_ui_audio_callback(const LLUUID& uuid)
 {
 	if (gAudiop)
 	{
-		LLDeferredSounds::instance().deferSound(SoundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI));
+		SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+		LLDeferredSounds::instance().deferSound(soundData);
 	}
 }
 
-- 
cgit v1.2.3


From edb5be4ec0a88931933a27dc7e94d45ea249591d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 29 Jan 2013 14:41:37 -0800
Subject: CHUI-88 I shouldn't see Conference IMs from people I muted. Fix: In
 order to mute a user who initiated a conference/group chat, the session must
 be created on the server side and then left.

---
 indra/newview/llimview.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 8f010850f7..3a5743f309 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -3454,12 +3454,10 @@ public:
 				(time_t) message_params["timestamp"].asInteger();
 
 			BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
-			BOOL is_muted = LLMuteList::getInstance()->isMuted(
-				from_id,
-				name,
-				LLMute::flagTextChat);
 
-			if (is_do_not_disturb || is_muted)
+			//don't return if user is muted b/c proper way to ignore a muted user who
+			//initiated an adhoc/group conference is to create then leave the session (see STORM-1731)
+			if (is_do_not_disturb)
 			{
 				return;
 			}
-- 
cgit v1.2.3


From df84e3c1876c5d2b321f0a8596e7e2a936073156 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 29 Jan 2013 17:47:34 -0800
Subject: CHUI-436 : Fixed : Do not skip yourself or group chat when checked
 Only friends and groups can call or IM me pref.

---
 indra/newview/llimview.cpp | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 8f010850f7..4a1b15f82b 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2610,8 +2610,15 @@ void LLIMMgr::addMessage(
         }
 	}
 
-	bool skip_message = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") &&
-		LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL);
+	bool skip_message = false;
+	if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
+	{
+		// Evaluate if we need to skip this message when that setting is true (default is false)
+		LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
+		skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL);	// Skip non friends...
+		skip_message &= !session->isGroupSessionType();			// Do not skip group chats...
+		skip_message &= !(other_participant_id == gAgentID);	// You are your best friend... Don't skip yourself
+	}
 
 	if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message)
 	{
-- 
cgit v1.2.3


From 4f0237007a3a21cc502a1a15b0530bceaf5217db Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Wed, 30 Jan 2013 02:54:59 +0000
Subject: CHUI-647 FIX "Conversations" floater is not opened when user wants to
 share something via "Conversation log" floater Added call to show
 conversations floater in LLAvatarActions::share

---
 indra/newview/llavataractions.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 83b2888ca8..d6e457887b 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -443,6 +443,7 @@ void LLAvatarActions::share(const LLUUID& id)
 {
 	LLSD key;
 	LLFloaterSidePanelContainer::showPanel("inventory", key);
+	LLFloaterReg::showInstance("im_container");
 
 	LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,id);
 
-- 
cgit v1.2.3


From b96f04a1bb0577d42059246d15c244702ff02f88 Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Wed, 30 Jan 2013 08:16:47 +0200
Subject: CHUI-704 (Entry in 'Conversation Log' floater with your avatar's name
 appears, after ejecting any member from group)

---
 indra/newview/llconversationlog.cpp | 2 +-
 indra/newview/llimview.cpp          | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index ff1f819d7d..65374b67f8 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -237,7 +237,7 @@ void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offli
 	const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 	LLConversation* conversation = findConversation(session);
 
-    if (session)
+	if (session)
 	{
     	if (conversation)
 		{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cb03c1d234..4c3d385d2d 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2542,6 +2542,13 @@ void LLIMMgr::addMessage(
 	bool link_name) // If this is true, then we insert the name and link it to a profile
 {
 	LLUUID other_participant_id = target_id;
+
+	// Agent can't create session with himself
+	if (other_participant_id == gAgentID)
+	{
+		return;
+	}
+
 	LLUUID new_session_id = session_id;
 	if (new_session_id.isNull())
 	{
-- 
cgit v1.2.3


From d2a17e20ca889851406f22907df35b17f5030279 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 31 Jan 2013 03:16:25 +0200
Subject: CHUI-612 FIXED Blank conversation names showing in conversation list

---
 indra/newview/llconversationmodel.cpp   | 29 +++++++++++++++--------------
 indra/newview/llfloaterimsessiontab.cpp | 29 ++++++++++++++++-------------
 indra/newview/llimview.cpp              |  5 +++--
 3 files changed, 34 insertions(+), 29 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 7184a70db5..bfc564f407 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -37,6 +37,8 @@
 #include "llimview.h" //For LLIMModel
 #include "lltrans.h"
 
+#include <boost/foreach.hpp>
+
 //
 // Conversation items : common behaviors
 //
@@ -234,15 +236,19 @@ void LLConversationItemSession::updateName(LLConversationItemParticipant* partic
 	}
 
 	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
-	if (conversation_type == CONV_SESSION_AD_HOC)
+	if (conversation_type == CONV_SESSION_AD_HOC || conversation_type == CONV_SESSION_1_ON_1)
 	{
 		// Build a string containing the participants UUIDs (minus own agent) and check if ready for display (we don't want "(waiting)" in there)
 		// Note: we don't bind ourselves to the LLAvatarNameCache event as updateParticipantName() is called by
 		// onAvatarNameCache() which is itself attached to the same event.
-		child_list_t::iterator iter = mChildren.begin();
-		while (iter != mChildren.end())
+
+		// In the case of a P2P conversation, we need to grab the name of the other participant in the session instance itself
+		// as we do not create participants for such a session.
+
+		LLFolderViewModelItem * itemp;
+		BOOST_FOREACH(itemp, mChildren)
 		{
-			LLConversationItemParticipant* current_participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+			LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp);
 			// Add the avatar uuid to the list (except if it's the own agent uuid)
 			if (current_participant->getUUID() != gAgentID)
 			{
@@ -250,18 +256,13 @@ void LLConversationItemSession::updateName(LLConversationItemParticipant* partic
 				if (LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
 				{
 					temp_uuids.push_back(current_participant->getUUID());
+
+					if (conversation_type == CONV_SESSION_1_ON_1)
+					{
+						break;
+					}
 				}
 			}
-			iter++;
-		}
-	}
-	else if (conversation_type == CONV_SESSION_1_ON_1)
-	{
-		// In the case of a P2P conversation, we need to grab the name of the other participant in the session instance itself
-		// as we do not create participants for such a session.
-		if (gAgentID != participant->getUUID())
-		{
-			temp_uuids.push_back(participant->getUUID());
 		}
 	}
 
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index f52cf3b8f0..6dbcdb4474 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -498,25 +498,28 @@ void LLFloaterIMSessionTab::refreshConversation()
 		updateSessionName(session_name);
 	}
 
-	LLParticipantList* participant_list = getParticipantList();
-	if (participant_list)
+	if (mSessionID.notNull())
 	{
-		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = participant_list->getChildrenBegin();
-		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = participant_list->getChildrenEnd();
-		LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		while (current_participant_model != end_participant_model)
+		LLParticipantList* participant_list = getParticipantList();
+		if (participant_list)
 		{
-			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
-			if (speaker_mgr && participant_model)
+			LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = participant_list->getChildrenBegin();
+			LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = participant_list->getChildrenEnd();
+			LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+			while (current_participant_model != end_participant_model)
 			{
-				LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID());
-				LLSpeaker *agent_speaker = speaker_mgr->findSpeaker(gAgentID);
-				if (participant_speaker && agent_speaker)
+				LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+				if (speaker_mgr && participant_model)
 				{
-					participant_model->setDisplayModeratorRole(agent_speaker->mIsModerator && participant_speaker->mIsModerator);
+					LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID());
+					LLSpeaker *agent_speaker = speaker_mgr->findSpeaker(gAgentID);
+					if (participant_speaker && agent_speaker)
+					{
+						participant_model->setDisplayModeratorRole(agent_speaker->mIsModerator && participant_speaker->mIsModerator);
+					}
 				}
+				current_participant_model++;
 			}
-			current_participant_model++;
 		}
 	}
 	
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5dd5704916..aaddcacbb5 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -847,8 +847,9 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co
 
 bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice, bool has_offline_msg)
 {
-	uuid_vec_t no_ids;
-	return newSession(session_id, name, type, other_participant_id, no_ids, voice, has_offline_msg);
+	uuid_vec_t ids;
+	ids.push_back(other_participant_id);
+	return newSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg);
 }
 
 bool LLIMModel::clearSession(const LLUUID& session_id)
-- 
cgit v1.2.3


From a12200b91b0ca20dfff2df8aa71c6f53ac0603ee Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Thu, 31 Jan 2013 10:04:15 +0200
Subject: CHUI-718 (User does not see own chat in conference IM) CHUI-704
 (Entry in 'Conversation Log' floater with your avatar's name appears, after
 ejecting any member from group)

---
 indra/newview/llconversationlog.cpp | 2 +-
 indra/newview/llimview.cpp          | 6 ------
 2 files changed, 1 insertion(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 772753e7d1..fb654985e5 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -229,7 +229,7 @@ void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offli
 	const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 	LLConversation* conversation = findConversation(session);
 
-	if (session)
+	if (session && session->mOtherParticipantID != gAgentID)
 	{
     	if (conversation)
 		{
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5dd5704916..3f9fb02368 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2545,12 +2545,6 @@ void LLIMMgr::addMessage(
 {
 	LLUUID other_participant_id = target_id;
 
-	// Agent can't create session with himself
-	if (other_participant_id == gAgentID)
-	{
-		return;
-	}
-
 	LLUUID new_session_id = session_id;
 	if (new_session_id.isNull())
 	{
-- 
cgit v1.2.3


From 0aa68e46fb67db3c90ac3d193bfa99509dca8100 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Thu, 31 Jan 2013 14:57:09 +0200
Subject: CHUI-711 FIXED Load logs from file only once to avoid duplicating.
 This will also solve problem with chui-710.

---
 indra/newview/llconversationlog.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 772753e7d1..c68a96ef5d 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -194,6 +194,7 @@ LLConversationLog::LLConversationLog() :
 
 	if (log_mode > 0)
 	{
+		loadFromFile(getFileName());
 		keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
 		enableLogging(log_mode);
 	}
@@ -203,8 +204,6 @@ void LLConversationLog::enableLogging(S32 log_mode)
 {
 	if (log_mode > 0)
 	{
-		loadFromFile(getFileName());
-
 		LLIMMgr::instance().addSessionObserver(this);
 		mNewMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
 
-- 
cgit v1.2.3


From 8714b610149a5ae7b6f248023722f237c9336472 Mon Sep 17 00:00:00 2001
From: "maxim@mnikolenko" <maxim@mnikolenko>
Date: Thu, 31 Jan 2013 19:05:15 +0200
Subject: CHUI-719 FIXED Font color was changed.

---
 indra/newview/skins/default/xui/en/panel_preferences_chat.xml | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 4f33699aa6..9b22c8c6dd 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -46,8 +46,7 @@
         layout="topleft"
         name="voice_call_friends_only_check"
         top_pad="6"
-        width="350">
-      <check_box.label_text text_color="White" />
+        width="350">     
     </check_box>
 
     <text
@@ -79,8 +78,7 @@
       <item
           label="Large"
           name="Large"
-          value="2"/>
-      <combo_box.drop_down_button label_color="White" />
+          value="2"/>  
     </combo_box>
 
     <check_box
@@ -107,7 +105,6 @@
         height="12"
         name="notifications"
         left="0"
-        text_color="White"
         width="120">
       Notifications
     </text>
@@ -392,14 +389,12 @@
         <item
             label="No log or transcripts"
             value="0"/>
-        <drop_down_button label_color="White" />
     </combo_box>
 
     <button
         enabled="false"
         height="23"
         label="Clear log..."
-        label_color="White"
         layout="topleft"
         left_pad="5"
         top="0"
@@ -413,7 +408,6 @@
         enabled="false"
         height="23"
         label="Delete transcripts..."
-        label_color="White"
         layout="topleft"
         left_pad="5"
         top="0"
@@ -452,7 +446,6 @@
         follows="left|top"
         height="23"
         label="Browse..."
-        label_color="White"
         label_selected="Browse"
         layout="topleft"
         left_pad="5"
-- 
cgit v1.2.3


From 97930c72b6f869e9bb47cda7d9ecfccf1a25a3fa Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 1 Feb 2013 15:11:43 +0200
Subject: CHUI-715 FIXED Disable Gear button if no conversation is selected

---
 indra/newview/llfloaterconversationlog.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index a44ebcf6ab..07723ce44d 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -72,6 +72,7 @@ BOOL LLFloaterConversationLog::postBuild()
 
 void LLFloaterConversationLog::draw()
 {
+	getChild<LLMenuButton>("conversations_gear_btn")->setEnabled(mConversationLogList->getSelectedItem() != NULL);
 	LLFloater::draw();
 }
 
-- 
cgit v1.2.3


From 56b158e486f97f26c87ac37923f5dfbc2cc7548a Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 1 Feb 2013 18:54:15 +0000
Subject: CHUI-675 FIX You can select multiple users in people floater but can
 only drag and drop one name to conversation Moved drag and drop start in
 LLAvatarListItem instead of LLAvatarList, and made LLFloaterIMSession handle
 multiple dropped participants correctly

---
 indra/newview/llavatarlist.cpp       | 52 ++++++++++++++++++++++++++++++++++
 indra/newview/llavatarlist.h         |  3 ++
 indra/newview/llavatarlistitem.cpp   | 55 ------------------------------------
 indra/newview/llavatarlistitem.h     |  3 --
 indra/newview/llfloaterimsession.cpp | 17 ++++++++++-
 indra/newview/llfloaterimsession.h   | 15 +++++-----
 6 files changed, 79 insertions(+), 66 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index e54e47180f..9f02f301a1 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -46,6 +46,7 @@
 #include "lluuid.h"
 #include "llvoiceclient.h"
 #include "llviewercontrol.h"	// for gSavedSettings
+#include "lltooldraganddrop.h"
 
 static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
 
@@ -462,6 +463,57 @@ BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	return handled;
 }
 
+BOOL LLAvatarList::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	gFocusMgr.setMouseCapture(this);
+
+	S32 screen_x;
+	S32 screen_y;
+	localPointToScreen(x, y, &screen_x, &screen_y);
+	LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y);
+
+	return LLFlatListViewEx::handleMouseDown(x, y, mask);
+}
+
+BOOL LLAvatarList::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+	if(hasMouseCapture())
+	{
+		gFocusMgr.setMouseCapture(NULL);
+	}
+
+	return LLFlatListViewEx::handleMouseUp(x, y, mask);
+}
+
+BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
+{
+	bool handled = hasMouseCapture();
+	if(handled)
+	{
+		S32 screen_x;
+		S32 screen_y;
+		localPointToScreen(x, y, &screen_x, &screen_y);
+
+		if(LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y))
+		{
+			// First, create the global drag and drop object
+			std::vector<EDragAndDropType> types;
+			uuid_vec_t cargo_ids;
+			getSelectedUUIDs(cargo_ids);
+			types.resize(cargo_ids.size(), DAD_PERSON);
+			LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE;
+			LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src);
+		}
+	}
+
+	if(!handled)
+	{
+		handled = LLFlatListViewEx::handleHover(x, y, mask);
+	}
+
+	return handled;
+}
+
 bool LLAvatarList::isAvalineItemSelected()
 {
 	std::vector<LLPanel*> selected_items;
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 4814a88a79..3542577ae3 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -84,6 +84,9 @@ public:
 	bool getIconsVisible() const { return mShowIcons; }
 	const std::string getIconParamName() const{return mIconParamName;}
 	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 
 	// Return true if filter has at least one match.
 	bool filterHasMatches();
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 3ed0c7c482..3e6c817dd6 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -368,61 +368,6 @@ BOOL LLAvatarListItem::handleDoubleClick(S32 x, S32 y, MASK mask)
 	return LLPanel::handleDoubleClick(x, y, mask);
 }
 
-BOOL LLAvatarListItem::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	if (LLUICtrl::handleMouseDown(x, y, mask))
-	{
-		return TRUE;
-	}
-
-	gFocusMgr.setMouseCapture(this);
-
-	S32 screen_x;
-	S32 screen_y;
-	localPointToScreen(x, y, &screen_x, &screen_y);
-	LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y);
-
-	return TRUE;
-}
-
-BOOL LLAvatarListItem::handleMouseUp( S32 x, S32 y, MASK mask )
-{
-	if (LLUICtrl::childrenHandleMouseUp(x, y, mask))
-	{
-		return TRUE;
-	}
-
-	if(hasMouseCapture())
-	{
-		gFocusMgr.setMouseCapture(NULL);
-	}
-	return TRUE;
-}
-
-BOOL LLAvatarListItem::handleHover(S32 x, S32 y, MASK mask)
-{
-	bool handled = hasMouseCapture();
-	if(handled)
-	{
-		S32 screen_x;
-		S32 screen_y;
-		localPointToScreen(x, y, &screen_x, &screen_y);
-
-		if(LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y))
-		{
-			// First, create the global drag and drop object
-			std::vector<EDragAndDropType> types;
-			uuid_vec_t cargo_ids;
-			types.push_back(DAD_PERSON);
-			cargo_ids.push_back(mAvatarId);
-			LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE;
-			LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src);
-		}
-	}
-
-	return handled;
-}
-
 void LLAvatarListItem::setValue( const LLSD& value )
 {
 	if (!value.isMap()) return;;
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 96aed20016..7ef35a746e 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -115,9 +115,6 @@ public:
 	void onProfileBtnClick();
 
 	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
-	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
-	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
-	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 
 protected:
 	/**
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index f754853b82..50b2ed8c51 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -1043,6 +1043,19 @@ void LLFloaterIMSession::processSessionUpdate(const LLSD& session_update)
 	}
 }
 
+// virtual
+void LLFloaterIMSession::draw()
+{
+	// add people who were added via dropPerson()
+	if (!mPendingParticipants.empty())
+	{
+		addSessionParticipants(mPendingParticipants);
+		mPendingParticipants.clear();
+	}
+
+	LLFloaterIMSessionTab::draw();
+}
+
 // virtual
 BOOL LLFloaterIMSession::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 									EDragAndDropType cargo_type,
@@ -1081,7 +1094,9 @@ bool LLFloaterIMSession::dropPerson(LLUUID* person_id, bool drop)
 		res = canAddSelectedToChat(ids);
 		if(res && drop)
 		{
-			addSessionParticipants(ids);
+			// these people will be added during the next draw() call
+			// (so they can be added all at once)
+			mPendingParticipants.push_back(*person_id);
 		}
 	}
 
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index e7fd6f9ff3..381b3cf721 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -69,6 +69,13 @@ public:
 	/*virtual*/ BOOL getVisible();
 	// Check typing timeout timer.
 
+	/*virtual*/ void draw();
+	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+		EDragAndDropType cargo_type,
+		void* cargo_data,
+		EAcceptance* accept,
+		std::string& tooltip_msg);
+
 	static LLFloaterIMSession* findInstance(const LLUUID& session_id);
 	static LLFloaterIMSession* getInstance(const LLUUID& session_id);
 
@@ -117,13 +124,6 @@ public:
 	void processAgentListUpdates(const LLSD& body);
 	void processSessionUpdate(const LLSD& session_update);
 
-	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-									   EDragAndDropType cargo_type,
-									   void* cargo_data,
-									   EAcceptance* accept,
-									   std::string& tooltip_msg);
-
-
 	//used as a callback on receiving new IM message
 	static void sRemoveTypingIndicator(const LLSD& data);
 	static void onIMChicletCreated(const LLUUID& session_id);
@@ -189,6 +189,7 @@ private:
 	LLSD mQueuedMsgsForInit;
 
 	uuid_vec_t mInvitedParticipants;
+	uuid_vec_t mPendingParticipants;
 
 	// connection to voice channel state change signal
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
-- 
cgit v1.2.3


From dde030e6cd8816bb7f99e0358a8c83eaccf1f8b9 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 1 Feb 2013 11:18:23 -0800
Subject: CHUI-689: When DND mode is enabled, making a direct delivery purchase
 results in an IM message from '(Nobody)'. Solution: Fixed a problem in
 process_improved_im that would falsy use system messages while in DND mode as
 an IM from a user. Also made it so that while in DND mode, SystemMessages and
 message with a high or greater priority are shown to the user as toasts
 (before a notification chiclet would just appear without the toast).

---
 indra/newview/llnotificationscripthandler.cpp | 5 +++++
 indra/newview/llviewermessage.cpp             | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index e2d4e9f8ce..19dd6d4ca0 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -27,6 +27,7 @@
 
 #include "llviewerprecompiledheaders.h" // must be first include
 
+#include "llagent.h"
 #include "llnotificationhandler.h"
 #include "lltoastnotifypanel.h"
 #include "llviewercontrol.h"
@@ -95,6 +96,10 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 		p.notification = notification;
 		p.panel = notify_box;
 		p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
+		if(gAgent.isDoNotDisturb())
+		{ 
+			p.force_show = notification->getName() == "SystemMessage" || notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
+		}
 
 		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
 		if(channel)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index caafb10e25..359819ec49 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2391,7 +2391,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			// do nothing -- don't distract newbies in
 			// Prelude with global IMs
 		}
-		else if (offline == IM_ONLINE && is_do_not_disturb && name != SYSTEM_FROM)
+		else if (offline == IM_ONLINE && is_do_not_disturb && from_id.notNull())
 		{
 			// return a standard "do not disturb" message, but only do it to online IM 
 			// (i.e. not other auto responses and not store-and-forward IM)
-- 
cgit v1.2.3


From 1192abd7eb0dff000be69f21d4d7cc7e0ecef561 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 1 Feb 2013 21:55:03 +0000
Subject: CHUI-720 FIX User can open "Add friend" by pressing on a line in
 context menu for user that already is friend Added check for getVisible() and
 getEnabled() before passing along handleMouseDown() and handleMouseUp()
 callbacks to other menu items in LLMenuItemSeparatorGL

---
 indra/llui/llmenugl.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index b7148bb91b..f7bf39c897 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -593,12 +593,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask)
 	{
 		// the menu items are in the child list in bottom up order
 		LLView* prev_menu_item = parent_menu->findNextSibling(this);
-		return prev_menu_item ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
+		return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
 	}
 	else
 	{
 		LLView* next_menu_item = parent_menu->findPrevSibling(this);
-		return next_menu_item ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
+		return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
 	}
 }
 
@@ -608,12 +608,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask)
 	if (y > getRect().getHeight() / 2)
 	{
 		LLView* prev_menu_item = parent_menu->findNextSibling(this);
-		return prev_menu_item ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
+		return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
 	}
 	else
 	{
 		LLView* next_menu_item = parent_menu->findPrevSibling(this);
-		return next_menu_item ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
+		return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
 	}
 }
 
-- 
cgit v1.2.3


From 7705b43889a6cc2c718077906c8dd778b0e877f8 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 1 Feb 2013 18:04:33 -0800
Subject: CHUI-691: Now when an estate message is received while in DND mode, a
 toast notification will appear.

---
 indra/newview/llnotificationscripthandler.cpp | 4 +++-
 indra/newview/llviewermessage.cpp             | 7 +++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 19dd6d4ca0..08c98e4f28 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -98,7 +98,9 @@ bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 		p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
 		if(gAgent.isDoNotDisturb())
 		{ 
-			p.force_show = notification->getName() == "SystemMessage" || notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
+			p.force_show = notification->getName() == "SystemMessage" 
+							||	notification->getName() == "GodMessage" 
+							|| notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
 		}
 
 		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 359819ec49..6bbfd30794 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2371,7 +2371,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	LLNotification::Params params;
 
 	switch(dialog)
-	{
+	{ 
 	case IM_CONSOLE_AND_CHAT_HISTORY:
 		args["MESSAGE"] = message;
 		payload["from_id"] = from_id;
@@ -2391,7 +2391,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			// do nothing -- don't distract newbies in
 			// Prelude with global IMs
 		}
-		else if (offline == IM_ONLINE && is_do_not_disturb && from_id.notNull())
+		else if (offline == IM_ONLINE 
+					&& is_do_not_disturb
+					&& from_id.notNull() //not a system message
+					&& to_id.notNull()) //not global message
 		{
 			// return a standard "do not disturb" message, but only do it to online IM 
 			// (i.e. not other auto responses and not store-and-forward IM)
-- 
cgit v1.2.3


From 2f6ffe2183250f3f71a8d502eed9cf9df9ff8b16 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 4 Feb 2013 14:37:29 +0200
Subject: CHUI-721 FIXED Delete transcripts when performing Clear log action.

---
 indra/newview/llconversationlog.cpp   |  7 +++++++
 indra/newview/llconversationlog.h     |  1 +
 indra/newview/llfloaterpreference.cpp | 16 ++++++----------
 3 files changed, 14 insertions(+), 10 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 7bd6ef8cd7..bfaffdd73b 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -531,7 +531,14 @@ void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD&
 {
 	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
 	{
+		deleteTranscripts();
 		mConversations.clear();
 		notifyObservers();
 	}
 }
+
+void LLConversationLog::deleteTranscripts()
+{
+	gDirUtilp->deleteFilesInDir(gDirUtilp->getPerAccountChatLogsDir(), "*." + LL_TRANSCRIPT_FILE_EXTENSION);
+	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 65a18c02e5..88df17a8f7 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -140,6 +140,7 @@ public:
 
 	void onClearLog();
 	void onClearLogResponse(const LLSD& notification, const LLSD& response);
+	void deleteTranscripts();
 
 private:
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 7742e5b3c3..4f86c26a67 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -460,9 +460,6 @@ BOOL LLFloaterPreference::postBuild()
 	// set 'enable' property for 'Clear log...' button
 	changed();
 
-	// set 'enable' property for 'Delete transcripts...' button
-	updateDeleteTranscriptsButton();
-
 	LLLogChat::setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this));
 
 	return TRUE;
@@ -1587,13 +1584,8 @@ void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification,
 {
 	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
 	{
-		gDirUtilp->deleteFilesInDir(gDirUtilp->getPerAccountChatLogsDir(), "*." + LL_TRANSCRIPT_FILE_EXTENSION);
-
-		std::vector<std::string> list_of_transcriptions_file_names;
-		LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
-		getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
-
-		LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+		LLConversationLog::instance().deleteTranscripts();
+		updateDeleteTranscriptsButton();
 	}
 }
 
@@ -1668,6 +1660,10 @@ void LLFloaterPreference::selectChatPanel()
 void LLFloaterPreference::changed()
 {
 	getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
+
+	// set 'enable' property for 'Delete transcripts...' button
+	updateDeleteTranscriptsButton();
+
 }
 
 //------------------------------Updater---------------------------------------
-- 
cgit v1.2.3


From 85f7f43069ea7ea47b4461fa1d7700339985ab35 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 4 Feb 2013 19:11:17 +0200
Subject: CHUI-695 FIXED Viewer crashes after attempt to accept a friendship in
 IM

---
 indra/newview/lltoastnotifypanel.cpp               | 142 ++-------------------
 indra/newview/lltoastpanel.cpp                     |   4 +-
 .../skins/default/xui/en/panel_notification.xml    |   2 +-
 3 files changed, 14 insertions(+), 134 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 0aab514531..bd6c42d474 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -223,104 +223,6 @@ void LLToastNotifyPanel::adjustPanelForTipNotice()
 	}
 }
 
-//typedef std::set<std::string> button_name_set_t;
-//typedef std::map<std::string, button_name_set_t> disable_button_map_t;
-//
-//disable_button_map_t initUserGiveItemDisableButtonMap()
-//{
-//	// see EXT-5905 for disable rules
-//
-//	disable_button_map_t disable_map;
-//	button_name_set_t buttons;
-//
-//	buttons.insert("Show");
-//	disable_map.insert(std::make_pair("Show", buttons));
-//
-//	buttons.insert("Discard");
-//	disable_map.insert(std::make_pair("Discard", buttons));
-//
-//	buttons.insert("Mute");
-//	disable_map.insert(std::make_pair("Mute", buttons));
-//
-//	return disable_map;
-//}
-//
-//disable_button_map_t initTeleportOfferedDisableButtonMap()
-//{
-//	disable_button_map_t disable_map;
-//	button_name_set_t buttons;
-//
-//	buttons.insert("Teleport");
-//	buttons.insert("Cancel");
-//
-//	disable_map.insert(std::make_pair("Teleport", buttons));
-//	disable_map.insert(std::make_pair("Cancel", buttons));
-//
-//	return disable_map;
-//}
-//
-//disable_button_map_t initFriendshipOfferedDisableButtonMap()
-//{
-//	disable_button_map_t disable_map;
-//	button_name_set_t buttons;
-//
-//	buttons.insert("Accept");
-//	buttons.insert("Decline");
-//
-//	disable_map.insert(std::make_pair("Accept", buttons));
-//	disable_map.insert(std::make_pair("Decline", buttons));
-//
-//	return disable_map;
-//}
-//
-//button_name_set_t getButtonDisableList(const std::string& notification_name, const std::string& button_name)
-//{
-//	static disable_button_map_t user_give_item_disable_map = initUserGiveItemDisableButtonMap();
-//	static disable_button_map_t teleport_offered_disable_map = initTeleportOfferedDisableButtonMap();
-//	static disable_button_map_t friendship_offered_disable_map = initFriendshipOfferedDisableButtonMap();
-//
-//	disable_button_map_t::const_iterator it;
-//	disable_button_map_t::const_iterator it_end;
-//	disable_button_map_t search_map;
-//
-//	if("UserGiveItem" == notification_name)
-//	{
-//		search_map = user_give_item_disable_map;
-//	}
-//	else if("TeleportOffered" == notification_name)
-//	{
-//		search_map = teleport_offered_disable_map;
-//	}
-//	else if("OfferFriendship" == notification_name)
-//	{
-//		search_map = friendship_offered_disable_map;
-//	}
-//
-//	it = search_map.find(button_name);
-//	it_end = search_map.end();
-//
-//	if(it_end != it)
-//	{
-//		return it->second;
-//	}
-//	return button_name_set_t();
-//}
-
-//void LLToastNotifyPanel::disableButtons(const std::string& notification_name, const std::string& selected_button)
-//{
-	//button_name_set_t buttons = getButtonDisableList(notification_name, selected_button);
-
-	//std::vector<index_button_pair_t>::const_iterator it = mButtons.begin();
-	//for ( ; it != mButtons.end(); it++)
-	//{
-	//	LLButton* btn = it->second;
-	//	if(buttons.find(btn->getName()) != buttons.end())
-	//	{
-	//		btn->setEnabled(FALSE);
-	//	}
-	//}
-//}
-
 // static
 void LLToastNotifyPanel::onClickButton(void* data)
 {
@@ -352,7 +254,17 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
     mNumButtons = 0;
     mAddedDefaultBtn = false;
 
-    buildFromFile( "panel_notification.xml");
+	LLRect current_rect = getRect();
+
+	setXMLFilename("");
+	buildFromFile("panel_notification.xml");
+
+	// reshape the panel to its previous size
+	if (current_rect.notEmpty())
+	{
+		reshape(current_rect.getWidth(), current_rect.getHeight());
+	}
+
     if(rect != LLRect::null)
     {
         this->setShape(rect);
@@ -491,37 +403,9 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
         }
     }
 
-    // adjust panel's height to the text size
-    mInfoPanel->setFollowsAll();
     snapToMessageHeight(mTextBox, MAX_LENGTH);
 }
 
-
-
-//void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id, const std::string btn_name)
-//{
-//	if(mNotification->getID() == notification_id)
-//	{
-//		disableButtons(mNotification->getName(), btn_name);
-//	}
-//}
-
-//void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification)
-//{
-//	LLSD response = notification->getResponse();
-//	for (LLSD::map_const_iterator response_it = response.beginMap(); 
-//		response_it != response.endMap(); ++response_it)
-//	{
-//		if (response_it->second.isBoolean() && response_it->second.asBoolean())
-//		{
-//			// that after multiple responses there can be many pressed buttons
-//			// need to process them all
-//			disableButtons(notification->getName(), response_it->first);
-//		}
-//	}
-//}
-
-
 //////////////////////////////////////////////////////////////////////////
 
 LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */,
@@ -538,13 +422,12 @@ LLIMToastNotifyPanel::~LLIMToastNotifyPanel()
 
 void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
 {
+	LLToastPanel::reshape(width, height, called_from_parent);
 	snapToMessageHeight(mTextBox, MAX_LENGTH);
 }
 
 void LLIMToastNotifyPanel::compactButtons()
 {
-	mTextBox->setFollowsAll();
-
 	//we can't set follows in xml since it broke toasts behavior
 	setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP);
 
@@ -590,6 +473,5 @@ void LLIMToastNotifyPanel::init( LLRect rect, bool show_images )
 	compactButtons();
 }
 
-
 // EOF
 
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index 54d3912136..187aee207c 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -81,9 +81,7 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 		S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
 
 		heightDelta = newTextHeight - oldTextHeight;
-		S32 new_panel_height = llmin(
-				llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT),
-				maxTextHeight);
+		S32 new_panel_height = llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT);
 
 		//reshape the panel with new height
 		if (new_panel_height != getRect().getHeight())
diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml
index 94c468e1bb..421ecf10a1 100644
--- a/indra/newview/skins/default/xui/en/panel_notification.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification.xml
@@ -22,7 +22,7 @@
     background_visible="true"
   bg_alpha_color="ToastBackground"
   bg_opaque_color="ToastBackground"
-    follows="left|right|top"
+    follows="all"
     height="100"
     label="info_panel"
     layout="topleft"
-- 
cgit v1.2.3


From 3e73b107d37e293b4e4cde91734e1e8251ba6b72 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 4 Feb 2013 14:41:58 -0800
Subject: CHUI-677 : Added a warning printout in the log to capture context of
 this bug.

---
 indra/newview/llimview.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 5acb0b6374..1cceb68e2a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1591,6 +1591,11 @@ LLUUID LLIMMgr::computeSessionID(
 			session_id = other_participant_id ^ agent_id;
 		}
 	}
+
+	if (gAgent.isInGroup(session_id) && (session_id != other_participant_id))
+	{
+		llwarns << "Group session id different from group id: IM type = " << dialog << ", session id = " << session_id << ", group id = " << other_participant_id << llendl;
+	}
 	return session_id;
 }
 
-- 
cgit v1.2.3


From 6a68f16f2e908838b89216543b36f07e2a71c360 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 4 Feb 2013 19:29:05 -0800
Subject: CHUI-732 : Fixed! Do not iterate through selection while modufying it
 at the same time, use a temp set.

---
 indra/llui/llfolderview.cpp | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 7c1ca017d7..c756ff84e1 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -924,23 +924,27 @@ void LLFolderView::cut()
 {
 	// clear the inventory clipboard
 	LLClipboard::instance().reset();
-	S32 count = mSelectedItems.size();
-	if(getVisible() && getEnabled() && (count > 0))
+	if(getVisible() && getEnabled() && (mSelectedItems.size() > 0))
 	{
+		// Find out which item will be selected once the selection will be cut
 		LLFolderViewItem* item_to_select = getNextUnselectedItem();
+		
+		// Get the selection: removeItem() modified mSelectedItems and makes iterating on it unwise
+		std::set<LLFolderViewItem*> inventory_selected = getSelectionList();
 
-		selected_items_t::iterator item_it;
-		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+		// Move each item to the clipboard and out of their folder
+		for (std::set<LLFolderViewItem*>::iterator item_it = inventory_selected.begin(); item_it != inventory_selected.end(); ++item_it)
 		{
 			LLFolderViewItem* item_to_cut = *item_it;
 			LLFolderViewModelItem* listener = item_to_cut->getViewModelItem();
-			if(listener)
+			if (listener)
 			{
 				listener->cutToClipboard();
 				listener->removeItem();
 			}
 		}
-
+		
+		// Update the selection
 		setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
 	}
 	mSearchString.clear();
-- 
cgit v1.2.3


From 2aee8f6fbe2be3196300dd1ee6e31039de089207 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 5 Feb 2013 21:11:33 -0800
Subject: CHUI-730 : Fixed! Only clear out More sub menus in inventory

---
 indra/newview/llinventorybridge.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 5bfd63f3df..0ee78d57bd 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -571,7 +571,7 @@ void hide_context_entries(LLMenuGL& menu,
 
 		// descend into split menus:
 		LLMenuItemBranchGL* branchp = dynamic_cast<LLMenuItemBranchGL*>(menu_item);
-		if (NULL != branchp)
+		if ((name == "More") && branchp)
 		{
 			hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries);
 		}
-- 
cgit v1.2.3


From 5b143ee2c70dab6a50c51da68d6b4c97196e2aed Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 5 Feb 2013 22:26:58 -0800
Subject: CHUI-677 : Fixed! Use the selected session for doToSelectedGroup(),
 not the selected item.

---
 indra/newview/llfloaterimcontainer.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 54e5085490..5a284cc7b7 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1118,19 +1118,18 @@ void LLFloaterIMContainer::doToSelected(const LLSD& userdata)
 void LLFloaterIMContainer::doToSelectedGroup(const LLSD& userdata)
 {
     std::string action = userdata.asString();
-    LLUUID selected_group = getCurSelectedViewModelItem()->getUUID();
 
     if (action == "group_profile")
     {
-        LLGroupActions::show(selected_group);
+        LLGroupActions::show(mSelectedSession);
     }
     else if (action == "activate_group")
     {
-        LLGroupActions::activate(selected_group);
+        LLGroupActions::activate(mSelectedSession);
     }
     else if (action == "leave_group")
     {
-        LLGroupActions::leave(selected_group);
+        LLGroupActions::leave(mSelectedSession);
     }
 }
 
-- 
cgit v1.2.3


From 3781615afa6db7289f26f404885ac614c7f1cee0 Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Wed, 6 Feb 2013 10:03:42 +0200
Subject: CHUI-597 (Messages shown in Conversation Log are inaccurate) Added
 messages, for now they're displayed in two cases: 1) no log entries, logging
 disabled 2) no log entries, logging enabled Case when there are existing log
 entries and logging is disabled is still under discussion

---
 indra/newview/llconversationlog.cpp                |  5 +++--
 indra/newview/llconversationlog.h                  |  5 +++++
 indra/newview/llconversationloglist.cpp            | 24 +++++++++++++++++++++-
 indra/newview/llfloaterconversationlog.cpp         |  9 --------
 indra/newview/llfloaterconversationlog.h           |  2 --
 .../default/xui/en/floater_conversation_log.xml    |  3 ---
 indra/newview/skins/default/xui/en/strings.xml     | 11 ++++++++++
 7 files changed, 42 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 7bd6ef8cd7..5f037549ab 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -187,7 +187,8 @@ void LLConversationLogFriendObserver::changed(U32 mask)
 /************************************************************************/
 
 LLConversationLog::LLConversationLog() :
-	mAvatarNameCacheConnection()
+	mAvatarNameCacheConnection(),
+	mLoggingEnabled(false)
 {
 	LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
 	S32 log_mode = keep_log_ctrlp->getValue();
@@ -202,6 +203,7 @@ LLConversationLog::LLConversationLog() :
 
 void LLConversationLog::enableLogging(S32 log_mode)
 {
+	mLoggingEnabled = log_mode > 0;
 	if (log_mode > 0)
 	{
 		LLIMMgr::instance().addSessionObserver(this);
@@ -217,7 +219,6 @@ void LLConversationLog::enableLogging(S32 log_mode)
 		LLIMMgr::instance().removeSessionObserver(this);
 		mNewMessageSignalConnection.disconnect();
 		LLAvatarTracker::instance().removeObserver(mFriendObserver);
-		mConversations.clear();
 	}
 
 	notifyObservers();
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 65a18c02e5..d5b6eccb29 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -141,6 +141,9 @@ public:
 	void onClearLog();
 	void onClearLogResponse(const LLSD& notification, const LLSD& response);
 
+	bool getIsLoggingEnabled() { return mLoggingEnabled; }
+	bool isLogEmpty() { return mConversations.empty(); }
+
 private:
 
 	LLConversationLog();
@@ -187,6 +190,8 @@ private:
 
 	boost::signals2::connection mNewMessageSignalConnection;
 	boost::signals2::connection mAvatarNameCacheConnection;
+
+	bool mLoggingEnabled;
 };
 
 class LLConversationLogObserver
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 6dbcb7bef7..96b225b841 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -33,6 +33,7 @@
 #include "llconversationloglist.h"
 #include "llconversationloglistitem.h"
 #include "llviewermenu.h"
+#include "lltrans.h"
 
 static LLDefaultChildRegistry::Register<LLConversationLogList> r("conversation_log_list");
 
@@ -200,8 +201,9 @@ void LLConversationLogList::rebuildList()
 	clear();
 
 	bool have_filter = !mNameFilter.empty();
+	LLConversationLog &log_instance = LLConversationLog::instance();
 
-	const std::vector<LLConversation>& conversations = LLConversationLog::instance().getConversations();
+	const std::vector<LLConversation>& conversations = log_instance.getConversations();
 	std::vector<LLConversation>::const_iterator iter = conversations.begin();
 
 	for (; iter != conversations.end(); ++iter)
@@ -212,6 +214,26 @@ void LLConversationLogList::rebuildList()
 
 		addNewItem(&*iter);
 	}
+	
+
+	bool logging_enabled = log_instance.getIsLoggingEnabled();
+	bool log_empty = log_instance.isLogEmpty();
+	if (!logging_enabled && log_empty)
+	{
+		setNoItemsCommentText(LLTrans::getString("logging_calls_disabled_log_empty"));
+	}
+	else if (!logging_enabled && !log_empty)
+	{
+		setNoItemsCommentText(LLTrans::getString("logging_calls_disabled_log_not_empty"));
+	}
+	else if (logging_enabled && log_empty)
+	{
+		setNoItemsCommentText(LLTrans::getString("logging_calls_enabled_log_empty"));
+	}
+	else if (logging_enabled && !log_empty)
+	{
+		setNoItemsCommentText("");
+	}
 }
 
 void LLConversationLogList::onCustomAction(const LLSD& userdata)
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index 07723ce44d..4c910c5655 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -63,10 +63,6 @@ BOOL LLFloaterConversationLog::postBuild()
 
 	getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
 
-	LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
-	keep_log_ctrlp->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
-	onCallLoggingEnabledDisabled(keep_log_ctrlp->getValue());
-
 	return LLFloater::postBuild();
 }
 
@@ -136,8 +132,3 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
 	return false;
 }
 
-void LLFloaterConversationLog::onCallLoggingEnabledDisabled(S32 log_mode)
-{
-	std::string no_items_msg = log_mode > 0 ? "" : getString("logging_calls_disabled");
-	mConversationLogList->setNoItemsCommentText(no_items_msg);
-}
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
index aa0f480aae..e971330f3d 100644
--- a/indra/newview/llfloaterconversationlog.h
+++ b/indra/newview/llfloaterconversationlog.h
@@ -49,8 +49,6 @@ private:
 	bool isActionEnabled(const LLSD& userdata);
 	bool isActionChecked(const LLSD& userdata);
 
-	void onCallLoggingEnabledDisabled(S32 log_mode);
-
 	LLConversationLogList* mConversationLogList;
 };
 
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index 256e03c4d7..7229292a14 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -13,9 +13,6 @@
  reuse_instance="true"
  title="CONVERSATION LOG"
  width="300">
-  <string name="logging_calls_disabled">
-     Conversations are not being logged. To log conversations in the future, select "Save IM logs on my computer" under Preferences > Privacy.
-  </string>
   <panel
    follows="left|top|right"
    height="32"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index d6a2383e52..5aa743b32d 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3908,4 +3908,15 @@ Try enclosing path to the editor with double quotes.
   <!-- Spell check settings floater -->
   <string name="UserDictionary">[User]</string>
   
+  <!-- Conversation log messages -->
+  <string name="logging_calls_disabled_log_empty">
+    Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
+  </string>
+  <string name="logging_calls_disabled_log_not_empty">
+    No more conversations will be logged. To resume keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
+  </string>
+  <string name="logging_calls_enabled_log_empty">
+    There are no logged conversations. After you contact someone, or someone contacts you, a log entry will be shown here.
+  </string>
+  
   </strings>
-- 
cgit v1.2.3


From 418b0334f2ee92ce8b8958218c8d6db5ccc855f2 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 6 Feb 2013 15:06:27 +0200
Subject: CHUI-716 FIXED Call onClickCloseBtn() to avoid complete disappearing
 of torn off Nearby chat.

---
 indra/newview/llfloaterimnearbychat.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index a2dd93e10d..345418bffc 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -260,6 +260,7 @@ void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
 void LLFloaterIMNearbyChat::onClose(bool app_quitting)
 {
 	// Override LLFloaterIMSessionTab::onClose() so that Nearby Chat is not removed from the conversation floater
+	onClickCloseBtn();
 }
 
 // virtual
-- 
cgit v1.2.3


From 302f57e47fdab9e043a72e6a83f0f2b1992f2a99 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 6 Feb 2013 20:17:35 +0200
Subject: CHUI-744 FIXED KeepConversationLogTranscripts setting is moved to
 settings_per_account.xml

---
 indra/newview/app_settings/settings.xml             | 11 -----------
 indra/newview/app_settings/settings_per_account.xml | 11 +++++++++++
 indra/newview/llconversationlog.cpp                 |  4 ++--
 indra/newview/llfloaterimcontainer.cpp              |  4 ++--
 indra/newview/llfloaterimnearbychat.cpp             |  2 +-
 indra/newview/llimview.cpp                          |  2 +-
 6 files changed, 17 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index fb4cc6de62..79376f7467 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4667,17 +4667,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>KeepConversationLogTranscripts</key>
-    <map>
-      <key>Comment</key>
-      <string>Keep a conversation log and transcripts</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>S32</string>
-      <key>Value</key>
-      <integer>2</integer>
-    </map>
     <key>LandBrushSize</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 6864328339..0b589e2da6 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -281,6 +281,17 @@
         <key>Value</key>
             <integer>0</integer>
         </map>
+    <key>KeepConversationLogTranscripts</key>
+    	<map>
+      	<key>Comment</key>
+      		<string>Keep a conversation log and transcripts</string>
+      	<key>Persist</key>
+      		<integer>1</integer>
+      	<key>Type</key>
+      		<string>S32</string>
+      	<key>Value</key>
+      		<integer>2</integer>
+    	</map>    
     <key>ShowFavoritesOnLogin</key>
         <map>
         <key>Comment</key>
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 04abda1799..c5be2f59be 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -190,7 +190,7 @@ LLConversationLog::LLConversationLog() :
 	mAvatarNameCacheConnection(),
 	mLoggingEnabled(false)
 {
-	LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+	LLControlVariable * keep_log_ctrlp = gSavedPerAccountSettings.getControl("KeepConversationLogTranscripts").get();
 	S32 log_mode = keep_log_ctrlp->getValue();
 
 	if (log_mode > 0)
@@ -369,7 +369,7 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
 
 void LLConversationLog::cache()
 {
-	if (gSavedSettings.getS32("KeepConversationLogTranscripts") > 0)
+	if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0)
 	{
 		saveToFile(getFileName());
 	}
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 5a284cc7b7..2b13ce6377 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1141,7 +1141,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 
 	if ("conversation_log" == item)
 	{
-		return gSavedSettings.getS32("KeepConversationLogTranscripts") > 0;
+		return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
 	}
 
 	//Enable Chat history item for ad-hoc and group conversations
@@ -1792,7 +1792,7 @@ void LLFloaterIMContainer::updateSpeakBtnState()
 
 bool LLFloaterIMContainer::isConversationLoggingAllowed()
 {
-	return gSavedSettings.getS32("KeepConversationLogTranscripts") > 0;
+	return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
 }
 
 void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 345418bffc..430326203f 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -542,7 +542,7 @@ void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLS
 	}
 
 	// logging
-	if (!args["do_not_log"].asBoolean() && gSavedSettings.getS32("KeepConversationLogTranscripts") > 1)
+	if (!args["do_not_log"].asBoolean() && gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1)
 	{
 		std::string from_name = chat.mFromName;
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 1cceb68e2a..d4c8d8c4f4 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -928,7 +928,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 
 bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
-	if (gSavedSettings.getS32("KeepConversationLogTranscripts") > 1)
+	if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1)
 	{	
 		std::string from_name = from;
 
-- 
cgit v1.2.3


From f944608ab93199a5588ec2c969268b094b8be7c8 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 6 Feb 2013 20:00:43 +0200
Subject: CHUI-707: "Chat" toolbar button stop flashing after setting toolbar
 buttons view to "Icons only": save/restore flashing states

---
 indra/llui/lltoolbar.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'indra')

diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 071046fe6d..b9256dd890 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -872,8 +872,15 @@ void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent)
 
 void LLToolBar::createButtons()
 {
+	std::set<LLUUID> set_flashing;
+
 	BOOST_FOREACH(LLToolBarButton* button, mButtons)
 	{
+        if (button->getFlashTimer() && button->getFlashTimer()->isFlashingInProgress())
+        {
+        	set_flashing.insert(button->getCommandId().uuid());
+        }
+
 		if (mButtonRemoveSignal)
 		{
 			(*mButtonRemoveSignal)(button);
@@ -896,6 +903,11 @@ void LLToolBar::createButtons()
 		{
 			(*mButtonAddSignal)(button);
 		}
+
+		if (set_flashing.find(button->getCommandId().uuid()) != set_flashing.end())
+		{
+			button->setFlashing(true);
+		}
 	}
 	mNeedsLayout = true;
 }
-- 
cgit v1.2.3


From ec0ac12eba9d944ade7bd734226a03ea2eb47229 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 6 Feb 2013 20:51:14 +0200
Subject: CHUI-712 FIXED IM log files renamed with ll.txt will create double
 files for users

---
 indra/newview/llconversationlog.cpp   |   8 +-
 indra/newview/llconversationlog.h     |   1 -
 indra/newview/llfloaterpreference.cpp |   2 +-
 indra/newview/lllogchat.cpp           | 147 ++++++++++++++++++----------------
 indra/newview/lllogchat.h             |   9 +--
 5 files changed, 82 insertions(+), 85 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index c5be2f59be..82176b3a06 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -532,14 +532,8 @@ void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD&
 {
 	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
 	{
-		deleteTranscripts();
+		LLLogChat::deleteTranscripts();
 		mConversations.clear();
 		notifyObservers();
 	}
 }
-
-void LLConversationLog::deleteTranscripts()
-{
-	gDirUtilp->deleteFilesInDir(gDirUtilp->getPerAccountChatLogsDir(), "*." + LL_TRANSCRIPT_FILE_EXTENSION);
-	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
-}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 5213c9b3ab..d5b6eccb29 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -140,7 +140,6 @@ public:
 
 	void onClearLog();
 	void onClearLogResponse(const LLSD& notification, const LLSD& response);
-	void deleteTranscripts();
 
 	bool getIsLoggingEnabled() { return mLoggingEnabled; }
 	bool isLogEmpty() { return mConversations.empty(); }
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 4f86c26a67..da24bb3b8f 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1584,7 +1584,7 @@ void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification,
 {
 	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
 	{
-		LLConversationLog::instance().deleteTranscripts();
+		LLLogChat::deleteTranscripts();
 		updateDeleteTranscriptsButton();
 	}
 }
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 545b44ef92..17b72c5023 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -33,6 +33,7 @@
 #include "llviewercontrol.h"
 
 #include "lldiriterator.h"
+#include "llfloaterimsessiontab.h"
 #include "llinstantmessage.h"
 #include "llsingleton.h" // for LLSingleton
 
@@ -40,6 +41,7 @@
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/regex.hpp>
 #include <boost/regex/v4/match_results.hpp>
+#include <boost/foreach.hpp>
 
 #if LL_MSVC
 #pragma warning(push)  
@@ -62,7 +64,7 @@ const std::string LL_IM_TIME("time");
 const std::string LL_IM_TEXT("message");
 const std::string LL_IM_FROM("from");
 const std::string LL_IM_FROM_ID("from_id");
-const std::string LL_TRANSCRIPT_FILE_EXTENSION("ll.txt");
+const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt");
 
 const static std::string IM_SEPARATOR(": ");
 const static std::string NEW_LINE("\n");
@@ -85,6 +87,7 @@ const static std::string MULTI_LINE_PREFIX(" ");
  * Note: "You" was used as an avatar names in viewers of previous versions
  */
 const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]\\s+|\\[\\d{1,2}:\\d{2}\\]\\s+)?(.*)$");
+const static boost::regex TIMESTAMP("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]|\\[\\d{1,2}:\\d{2}\\]).*");
 
 /**
  *  Regular expression suitable to match names like
@@ -328,69 +331,6 @@ void LLLogChat::saveHistory(const std::string& filename,
 	}
 }
 
-void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLineType, const LLSD&, void*), void* userdata)
-{
-	if(!filename.size())
-	{
-		llwarns << "Filename is Empty!" << llendl;
-		return ;
-	}
-		
-	LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "r");		/*Flawfinder: ignore*/
-	if (!fptr)
-	{
-		callback(LOG_EMPTY, LLSD(), userdata);
-		return;			//No previous conversation with this name.
-	}
-	else
-	{
-		char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
-		char *bptr;
-		S32 len;
-		bool firstline=TRUE;
-
-		if ( fseek(fptr, (LOG_RECALL_SIZE - 1) * -1  , SEEK_END) )		
-		{	//File is smaller than recall size.  Get it all.
-			firstline = FALSE;
-			if ( fseek(fptr, 0, SEEK_SET) )
-			{
-				fclose(fptr);
-				return;
-			}
-		}
-
-		while ( fgets(buffer, LOG_RECALL_SIZE, fptr)  && !feof(fptr) ) 
-		{
-			len = strlen(buffer) - 1;		/*Flawfinder: ignore*/
-			for ( bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--)	*bptr='\0';
-			
-			if (!firstline)
-			{
-				LLSD item;
-				std::string line(buffer);
-				std::istringstream iss(line);
-				
-				if (!LLChatLogParser::parse(line, item))
-				{
-					item["message"]	= line;
-					callback(LOG_LINE, item, userdata);
-				}
-				else
-				{
-					callback(LOG_LLSD, item, userdata);
-				}
-			}
-			else
-			{
-				firstline = FALSE;
-			}
-		}
-		callback(LOG_END, LLSD(), userdata);
-		
-		fclose(fptr);
-	}
-}
-
 // static
 void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
 {
@@ -506,19 +446,46 @@ std::string LLLogChat::oldLogFileName(std::string filename)
 void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions)
 {
 	// get Users log directory
-	std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+	std::string dirname = gDirUtilp->getPerAccountChatLogsDir();
 
 	// add final OS dependent delimiter
-	directory += gDirUtilp->getDirDelimiter();
+	dirname += gDirUtilp->getDirDelimiter();
 
 	// create search pattern
 	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
 
-	LLDirIterator iter(directory, pattern);
-	std::string scanResult;
-	while (iter.next(scanResult))
+	LLDirIterator iter(dirname, pattern);
+	std::string filename;
+	while (iter.next(filename))
 	{
-		list_of_transcriptions.push_back(scanResult);
+		std::string fullname = gDirUtilp->add(dirname, filename);
+
+		LLFILE * filep = LLFile::fopen(fullname, "rb");
+		if (NULL != filep)
+		{
+			char buffer[LOG_RECALL_SIZE];
+
+			fseek(filep, 0, SEEK_END);			// seek to end of file
+			S32 bytes_to_read = ftell(filep);	// get current file pointer
+			fseek(filep, 0, SEEK_SET);			// seek back to beginning of file
+
+			// limit the number characters to read from file
+			if (bytes_to_read >= LOG_RECALL_SIZE)
+			{
+				bytes_to_read = LOG_RECALL_SIZE - 1;
+			}
+
+			if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep))
+			{
+				//matching a timestamp
+				boost::match_results<std::string::const_iterator> matches;
+				if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
+				{
+					list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename));
+				}
+			}
+			LLFile::close(filep);
+		}
 	}
 }
 
@@ -533,6 +500,46 @@ boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_s
 	return sSaveHistorySignal->connect(cb);
 }
 
+//static
+void LLLogChat::deleteTranscripts()
+{
+	std::vector<std::string> list_of_transcriptions;
+	getListOfTranscriptFiles(list_of_transcriptions);
+
+	BOOST_FOREACH(const std::string& fullpath, list_of_transcriptions)
+	{
+		S32 retry_count = 0;
+		while (retry_count < 5)
+		{
+			if (0 != LLFile::remove(fullpath))
+			{
+				retry_count++;
+				S32 result = errno;
+				LL_WARNS("LLLogChat::deleteTranscripts") << "Problem removing " << fullpath << " - errorcode: "
+					<< result << " attempt " << retry_count << LL_ENDL;
+
+				if(retry_count >= 5)
+				{
+					LL_WARNS("LLLogChat::deleteTranscripts") << "Failed to remove " << fullpath << LL_ENDL;
+					return;
+				}
+
+				ms_sleep(100);
+			}
+			else
+			{
+				if (retry_count)
+				{
+					LL_WARNS("LLLogChat::deleteTranscripts") << "Successfully removed " << fullpath << LL_ENDL;
+				}
+				break;
+			}			
+		}
+	}
+
+	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+}
+
 //*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
 //which are more strict by its nature (only firstname and secondname)
 //Example, an object's name can be written like "Object <actual_object's_name>"
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index b35a94b4b3..5fbb4ade96 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -51,16 +51,13 @@ public:
 				const std::string& line);
 	static void getListOfTranscriptFiles(std::vector<std::string>& list);
 
-	/** @deprecated @see loadChatHistory() */
-	static void loadHistory(const std::string& filename, 
-		                    void (*callback)(ELogLineType, const LLSD&, void*), 
-							void* userdata);
-
 	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
 
 	typedef boost::signals2::signal<void ()> save_history_signal_t;
 	static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
 
+	static void deleteTranscripts();
+
 private:
 	static std::string cleanFileName(std::string filename);
 	static save_history_signal_t * sSaveHistorySignal;
@@ -123,6 +120,6 @@ extern const std::string LL_IM_TIME; //("time");
 extern const std::string LL_IM_TEXT; //("message");
 extern const std::string LL_IM_FROM; //("from");
 extern const std::string LL_IM_FROM_ID; //("from_id");
-extern const std::string LL_TRANSCRIPT_FILE_EXTENSION; //("ll.txt");
+extern const std::string LL_TRANSCRIPT_FILE_EXTENSION; //("txt");
 
 #endif
-- 
cgit v1.2.3


From 7ed270ff9dfdbc905dbee70907d3057a5ae490e7 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 6 Feb 2013 18:11:52 -0800
Subject: CHUI-735 : Fixed! Move the delete key handling from the llfolderview
 to the llinventorypanel level.

---
 indra/llui/llfolderview.cpp        | 23 -----------------------
 indra/llui/llfolderview.h          |  3 ---
 indra/newview/llinventorypanel.cpp |  8 ++++++++
 3 files changed, 8 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index c756ff84e1..dca14cc48f 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1336,29 +1336,6 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
 }
 
 
-BOOL LLFolderView::canDoDelete() const
-{
-	if (mSelectedItems.size() == 0) return FALSE;
-
-	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-	{
-		if (!(*item_it)->getViewModelItem()->isItemRemovable())
-		{
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-
-void LLFolderView::doDelete()
-{
-	if(mSelectedItems.size() > 0)
-	{				
-		removeSelectedItems();
-	}
-}
-
-
 BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
 {
 	mKeyboardSelection = FALSE;
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 05b2abb9d3..11fccdace4 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -180,9 +180,6 @@ public:
 	virtual BOOL	canPaste() const;
 	virtual void	paste();
 
-	virtual BOOL	canDoDelete() const;
-	virtual void	doDelete();
-
 	LLFolderViewItem* getNextUnselectedItem();
 
 	// Public rename functionality - can only start the process
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 019ba8f5b2..0653a097f5 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1365,6 +1365,14 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
 			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open");
 			handled = TRUE;
 		}
+		break;
+	case KEY_DELETE:
+		if (mask == MASK_NONE)
+		{
+			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete");
+			handled = TRUE;
+		}
+		break;
 	}
 	return handled;
 }
-- 
cgit v1.2.3


From b356bbb6a5930e8900250c6654688ae2e6d25ecf Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Thu, 7 Feb 2013 10:48:49 +0200
Subject: CHUI-713 "Conversations" floater size doesn't persist between
 sessions

---
 indra/newview/llfloaterimcontainer.cpp  | 9 +++++++--
 indra/newview/llfloaterimsessiontab.cpp | 5 ++++-
 2 files changed, 11 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 5a284cc7b7..27e579a68c 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -273,14 +273,19 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
 		openFloater(floaterp->getKey());
 		return;
 	}
+
+	LLUUID session_id = floaterp->getKey();
 	
 	// Make sure the message panel is open when adding a floater or it stays mysteriously hidden
-	collapseMessagesPane(false);
+	if (session_id != LLUUID())
+	{
+		collapseMessagesPane(false);
+	}
 
 	// Add the floater
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
-	LLUUID session_id = floaterp->getKey();
+
 	
 	LLIconCtrl* icon = 0;
 
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 6dbcdb4474..526eeef869 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -769,7 +769,10 @@ void LLFloaterIMSessionTab::onOpen(const LLSD& key)
 	{
 		LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(getHost());
 		// Show the messages pane when opening a floater hosted in the Conversations
-		host_floater->collapseMessagesPane(false);
+		if (!isNearbyChat())
+		{
+			host_floater->collapseMessagesPane(false);
+		}
 	}
 }
 
-- 
cgit v1.2.3


From 68a4a8402ccd614f5cdb40cb53efa85166c12598 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 7 Feb 2013 19:39:46 +0200
Subject: CHUI-722 Fixed! Add ? button to titlebar on floaters: Conversation
 Log, Nearby Chat History, and IM History

---
 indra/newview/skins/default/xui/en/floater_conversation_log.xml     | 1 +
 indra/newview/skins/default/xui/en/floater_conversation_preview.xml | 1 +
 2 files changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index 7229292a14..19a4cbc119 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -3,6 +3,7 @@
 <floater
  can_resize="true"
  positioning="cascading"
+ help_topic="conversation_log"
  height="200"
  min_height="100"
  min_width="230"
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 6f1ddaaf4f..764b9d8385 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -3,6 +3,7 @@
  legacy_header_height="18"
  can_resize="true"
  default_tab_group="1"
+ help_topic="conversation_preview"
  height="391"
  layout="topleft"
  min_height="243"
-- 
cgit v1.2.3


From dac026a7d6ad932ef185b4e5c5b5efd7b059e911 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 7 Feb 2013 13:27:32 -0800
Subject: CHUI-735 : Fixed! Handle the backspace case, suppress the search
 string handling from LLFolderView (it's in the search edit field now).

---
 indra/llui/llfolderview.cpp        | 14 --------------
 indra/newview/llinventorypanel.cpp |  3 +++
 2 files changed, 3 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index dca14cc48f..8feaf654f0 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1275,20 +1275,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 		break;
 	}
 
-	if (!handled && mParentPanel->hasFocus())
-	{
-		if (key == KEY_BACKSPACE)
-		{
-			mSearchTimer.reset();
-			if (mSearchString.size())
-			{
-				mSearchString.erase(mSearchString.size() - 1, 1);
-			}
-			search(getCurSelectedItem(), mSearchString, FALSE);
-			handled = TRUE;
-		}
-	}
-
 	return handled;
 }
 
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 0653a097f5..578b83fd28 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1367,6 +1367,9 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
 		}
 		break;
 	case KEY_DELETE:
+	case KEY_BACKSPACE:
+		// Delete selected items if delete or backspace key hit on the inventory panel
+		// Note: on Mac laptop keyboards, backspace and delete are one and the same
 		if (mask == MASK_NONE)
 		{
 			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete");
-- 
cgit v1.2.3


From 29a57c16c976eb39b3a0e82872435e0228044ba9 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 7 Feb 2013 14:41:38 -0800
Subject: CHUI-736: When auto-exit DND mode upon startup, stored conversations
 are not highlighted. When the dnd im is processed, now flash the conversation
 line item.

---
 indra/newview/llimview.cpp | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d4c8d8c4f4..2eaef48049 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -107,6 +107,7 @@ void process_dnd_im(const LLSD& notification)
 {
     LLSD data = notification["substitutions"];
     LLUUID sessionID = data["SESSION_ID"].asUUID();
+	LLUUID fromID = data["FROM_ID"].asUUID();
 
     //re-create the IM session if needed 
     //(when coming out of DND mode upon app restart)
@@ -119,14 +120,22 @@ void process_dnd_im(const LLSD& notification)
         {
             name = av_name.getDisplayName();
         }
-
+		
         
         LLIMModel::getInstance()->newSession(sessionID, 
             name, 
             IM_NOTHING_SPECIAL, 
-            data["FROM_ID"], 
+            fromID, 
             false, 
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
+
+		LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+		
+		if (im_box)
+		{
+			im_box->flashConversationItemWidget(sessionID, true);
+		}
+
     }
 }
 
-- 
cgit v1.2.3


From c55e4a61242cd3cf94e0a28398fd33a4eb8ea683 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 8 Feb 2013 02:03:28 +0000
Subject: CHUI-703 FIX Notification buttons: "Join","Decline","Info" are
 duplicated after relogin while group invitation Changed
 LLPersistentNotificationStorage::saveNotification() to use
 notification->asLLSD(true) to skip duplicates Changed
 LLDockControl::mDockWidget to be a LLHandle<LLView> instead of a LLView* to
 fix crash (from accessing deleted LLView)

---
 indra/llui/lldockcontrol.cpp                      | 31 +++++++++++++----------
 indra/llui/lldockcontrol.h                        |  4 +--
 indra/newview/llpersistentnotificationstorage.cpp |  2 +-
 3 files changed, 21 insertions(+), 16 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index af39e41fa6..602113432e 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -31,7 +31,6 @@
 
 LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 		const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
-		mDockWidget(dockWidget),
 		mDockableFloater(dockableFloater),
 		mDockTongue(dockTongue),
 		mDockTongueX(0),
@@ -39,6 +38,11 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 {
 	mDockAt = dockAt;
 
+	if (dockWidget != NULL)
+	{
+		mDockWidget = dockWidget->getHandle();
+	}
+
 	if (dockableFloater->isDocked())
 	{
 		on();
@@ -62,7 +66,7 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 		repositionDockable();
 	}
 
-	if (mDockWidget != NULL)
+	if (getDock() != NULL)
 	{
 		mDockWidgetVisible = isDockVisible();
 	}
@@ -78,14 +82,15 @@ LLDockControl::~LLDockControl()
 
 void LLDockControl::setDock(LLView* dockWidget)
 {
-	mDockWidget = dockWidget;
-	if (mDockWidget != NULL)
+	if (dockWidget != NULL)
 	{
+		mDockWidget = dockWidget->getHandle();
 		repositionDockable();
 		mDockWidgetVisible = isDockVisible();
 	}
 	else
 	{
+		mDockWidget = LLHandle<LLView>();
 		mDockWidgetVisible = false;
 	}
 }
@@ -97,8 +102,8 @@ void LLDockControl::getAllowedRect(LLRect& rect)
 
 void LLDockControl::repositionDockable()
 {
-	if (!mDockWidget) return;
-	LLRect dockRect = mDockWidget->calcScreenRect();
+	if (!getDock()) return;
+	LLRect dockRect = getDock()->calcScreenRect();
 	LLRect rootRect;
 	LLRect floater_rect = mDockableFloater->calcScreenRect();
 	mGetAllowedRectCallback(rootRect);
@@ -150,13 +155,13 @@ bool LLDockControl::isDockVisible()
 {
 	bool res = true;
 
-	if (mDockWidget != NULL)
+	if (getDock() != NULL)
 	{
 		//we should check all hierarchy
-		res = mDockWidget->isInVisibleChain();
+		res = getDock()->isInVisibleChain();
 		if (res)
 		{
-			LLRect dockRect = mDockWidget->calcScreenRect();
+			LLRect dockRect = getDock()->calcScreenRect();
 
 			switch (mDockAt)
 			{
@@ -169,7 +174,7 @@ bool LLDockControl::isDockVisible()
 				// assume that parent for all dockable floaters
 				// is the root view
 				LLRect dockParentRect =
-						mDockWidget->getRootView()->calcScreenRect();
+						getDock()->getRootView()->calcScreenRect();
 				if (dockRect.mRight <= dockParentRect.mLeft
 						|| dockRect.mLeft >= dockParentRect.mRight)
 				{
@@ -189,7 +194,7 @@ bool LLDockControl::isDockVisible()
 void LLDockControl::moveDockable()
 {
 	// calculate new dockable position
-	LLRect dockRect = mDockWidget->calcScreenRect();
+	LLRect dockRect = getDock()->calcScreenRect();
 	LLRect rootRect;
 	mGetAllowedRectCallback(rootRect);
 
@@ -263,7 +268,7 @@ void LLDockControl::moveDockable()
 
 
 		// calculate dock tongue position
-		dockParentRect = mDockWidget->getParent()->calcScreenRect();
+		dockParentRect = getDock()->getParent()->calcScreenRect();
 		if (dockRect.getCenterX() < dockParentRect.mLeft)
 		{
 			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
@@ -299,7 +304,7 @@ void LLDockControl::moveDockable()
 		}
 
 		// calculate dock tongue position
-		dockParentRect = mDockWidget->getParent()->calcScreenRect();
+		dockParentRect = getDock()->getParent()->calcScreenRect();
 		if (dockRect.getCenterX() < dockParentRect.mLeft)
 		{
 			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index c9602011f6..a1cfa0072c 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -63,7 +63,7 @@ public:
 	void setDock(LLView* dockWidget);
 	LLView* getDock()
 	{
-		return mDockWidget;
+		return mDockWidget.get();
 	}
 	void repositionDockable();
 	void drawToungue();
@@ -83,7 +83,7 @@ private:
 	bool mRecalculateDockablePosition;
 	bool mDockWidgetVisible;
 	DocAt mDockAt;
-	LLView* mDockWidget;
+	LLHandle<LLView> mDockWidget;
 	LLRect mPrevDockRect;
 	LLRect mRootRect;
 	LLRect mFloaterRect;
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 224aaa2146..11c12e6c10 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -75,7 +75,7 @@ void LLPersistentNotificationStorage::saveNotifications()
 			continue;
 		}
 
-		data.append(notification->asLLSD());
+		data.append(notification->asLLSD(true));
 	}
 
 	writeNotifications(output);
-- 
cgit v1.2.3


From 64fe330620459be18ee4dd54866386a8f6a76ab8 Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Sat, 9 Feb 2013 00:10:09 +0200
Subject: CHUI-713 "Conversations" floater size doesn't persist between
 sessions additional fix

---
 indra/newview/llfloaterimcontainer.cpp  | 12 ++++++++++--
 indra/newview/llfloaterimcontainer.h    |  1 +
 indra/newview/llfloaterimsessiontab.cpp |  5 +----
 3 files changed, 12 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 27e579a68c..312f70fe30 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -62,7 +62,8 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param
 	mExpandCollapseBtn(NULL),
 	mConversationsRoot(NULL),
 	mConversationsEventStream("ConversationsEvents"),
-	mInitialized(false)
+	mInitialized(false),
+	mIsFirstLaunch(false)
 {
     mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction,  this, _2));
@@ -243,6 +244,7 @@ BOOL LLFloaterIMContainer::postBuild()
 	mGeneralTitle = getTitle();
 	
 	mInitialized = true;
+	mIsFirstLaunch = true;
 
 	// Add callbacks:
 	// We'll take care of view updates on idle
@@ -277,7 +279,7 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
 	LLUUID session_id = floaterp->getKey();
 	
 	// Make sure the message panel is open when adding a floater or it stays mysteriously hidden
-	if (session_id != LLUUID())
+	if (!mIsFirstLaunch)
 	{
 		collapseMessagesPane(false);
 	}
@@ -635,6 +637,12 @@ void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 		return;
 	}
 
+	if (mIsFirstLaunch)
+	{
+		mIsFirstLaunch = false;
+		return;
+	}
+
 	// Save current width of panels before collapsing/expanding right pane.
 	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
     S32 msg_pane_width = mMessagesPane->getRect().getWidth();
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 06af6c7b51..a28dba3b98 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -167,6 +167,7 @@ private:
 	LLLayoutStack* mConversationsStack;
 	
 	bool mInitialized;
+	bool mIsFirstLaunch;
 
 	LLUUID mSelectedSession;
 	std::string mGeneralTitle;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 526eeef869..6dbcdb4474 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -769,10 +769,7 @@ void LLFloaterIMSessionTab::onOpen(const LLSD& key)
 	{
 		LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(getHost());
 		// Show the messages pane when opening a floater hosted in the Conversations
-		if (!isNearbyChat())
-		{
-			host_floater->collapseMessagesPane(false);
-		}
+		host_floater->collapseMessagesPane(false);
 	}
 }
 
-- 
cgit v1.2.3


From 46294bdcaca5ea259dee95256179653779697e21 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Fri, 8 Feb 2013 19:54:34 +0200
Subject: CHUI-731 FIXED Viewer crashed while deleting text from IM message

---
 indra/llui/lltextbase.cpp | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 8839afb60d..4c9c2781f2 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -605,7 +605,8 @@ void LLTextBase::drawText()
 
 				// Find the start of the first word
 				U32 word_start = seg_start, word_end = -1;
-				while ( (word_start < wstrText.length()) && (!LLStringOps::isAlpha(wstrText[word_start])) )
+				U32 text_length = wstrText.length();
+				while ( (word_start < text_length) && (!LLStringOps::isAlpha(wstrText[word_start])) )
 				{
 					word_start++;
 				}
@@ -627,11 +628,15 @@ void LLTextBase::drawText()
 						break;
 					}
 
-					// Don't process words shorter than 3 characters
-					std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
-					if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
+					if (word_start < text_length && word_end <= text_length && word_end > word_start)
 					{
-						mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
+						std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
+
+						// Don't process words shorter than 3 characters
+						if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
+						{
+							mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
+						}
 					}
 
 					// Find the start of the next word
-- 
cgit v1.2.3


From 4a0dd9ec76bfc9a3207b0e75608343f29fb26358 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 8 Feb 2013 19:16:38 +0000
Subject: CHUI-703 FIX Notification buttons: "Join","Decline","Info" are
 duplicated after relogin while group invitation Renamed
 LLDockControl::mDockWidget to mDockWidgetHandle for clarity

---
 indra/llui/lldockcontrol.cpp | 6 +++---
 indra/llui/lldockcontrol.h   | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 602113432e..bd42497cb6 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -40,7 +40,7 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 
 	if (dockWidget != NULL)
 	{
-		mDockWidget = dockWidget->getHandle();
+		mDockWidgetHandle = dockWidget->getHandle();
 	}
 
 	if (dockableFloater->isDocked())
@@ -84,13 +84,13 @@ void LLDockControl::setDock(LLView* dockWidget)
 {
 	if (dockWidget != NULL)
 	{
-		mDockWidget = dockWidget->getHandle();
+		mDockWidgetHandle = dockWidget->getHandle();
 		repositionDockable();
 		mDockWidgetVisible = isDockVisible();
 	}
 	else
 	{
-		mDockWidget = LLHandle<LLView>();
+		mDockWidgetHandle = LLHandle<LLView>();
 		mDockWidgetVisible = false;
 	}
 }
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index a1cfa0072c..98a9c7236d 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -63,7 +63,7 @@ public:
 	void setDock(LLView* dockWidget);
 	LLView* getDock()
 	{
-		return mDockWidget.get();
+		return mDockWidgetHandle.get();
 	}
 	void repositionDockable();
 	void drawToungue();
@@ -83,7 +83,7 @@ private:
 	bool mRecalculateDockablePosition;
 	bool mDockWidgetVisible;
 	DocAt mDockAt;
-	LLHandle<LLView> mDockWidget;
+	LLHandle<LLView> mDockWidgetHandle;
 	LLRect mPrevDockRect;
 	LLRect mRootRect;
 	LLRect mFloaterRect;
-- 
cgit v1.2.3


From a034c272c3d8d526a70998aae7ee816070481c39 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 8 Feb 2013 18:12:26 -0800
Subject: CHUI-747: Script buttons in a toast overlap message text. Problem was
 due to the message container not being shifted upward when buttons were added
 to the control buttons container (which is beneath the message container). A
 small change in CHUI-695 caused this.

---
 indra/newview/lltoastnotifypanel.cpp                      | 3 +++
 indra/newview/skins/default/xui/en/panel_notification.xml | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index bd6c42d474..3fd056ea31 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -403,6 +403,9 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
         }
     }
 
+	//.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel 
+	//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
+	mInfoPanel->setFollowsAll();
     snapToMessageHeight(mTextBox, MAX_LENGTH);
 }
 
diff --git a/indra/newview/skins/default/xui/en/panel_notification.xml b/indra/newview/skins/default/xui/en/panel_notification.xml
index 421ecf10a1..94c468e1bb 100644
--- a/indra/newview/skins/default/xui/en/panel_notification.xml
+++ b/indra/newview/skins/default/xui/en/panel_notification.xml
@@ -22,7 +22,7 @@
     background_visible="true"
   bg_alpha_color="ToastBackground"
   bg_opaque_color="ToastBackground"
-    follows="all"
+    follows="left|right|top"
     height="100"
     label="info_panel"
     layout="topleft"
-- 
cgit v1.2.3


From 2e2026a4f8359aba26e330fc8ec9ce4a3d40e666 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 8 Feb 2013 20:51:02 -0800
Subject: CHUI-746 : Fixed! Undid the MAINT-2276 hack now that submenus do work
 thanks to CHUI-682

---
 indra/newview/llpaneloutfitedit.cpp                  | 13 +++----------
 indra/newview/skins/default/xui/en/menu_cof_gear.xml |  2 +-
 2 files changed, 4 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 30f137bdba..c09d4393c8 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -186,11 +186,8 @@ private:
 	// Populate the menu with items like "New Skin", "New Pants", etc.
 	static void populateCreateWearableSubmenus(LLMenuGL* menu)
 	{
-        // MAINT-2276...these menus are created as dummies because they are not available
-        // when this function is called. This prevents their parent from popping up later.
-        //
-		//LLView* menu_clothes	= gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);
-		//LLView* menu_bp			= gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE);
+		LLView* menu_clothes	= gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);
+		LLView* menu_bp			= gMenuHolder->getChildView("COF.Gear.New_Body_Parts", FALSE);
 
 		for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i)
 		{
@@ -203,11 +200,7 @@ private:
 			p.on_click.function_name = "Wearable.Create";
 			p.on_click.parameter = LLSD(type_name);
 
-            //LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp;
-            // This is a work-around for MAINT-2276 wherein the parent toggleable menu does not appear
-            // It puts everything under one menu, but that menu appears, which is better than not.
-            // 
-			LLView* parent =  menu;
+            LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp;
 			LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
 		}
 	}
diff --git a/indra/newview/skins/default/xui/en/menu_cof_gear.xml b/indra/newview/skins/default/xui/en/menu_cof_gear.xml
index a6e9a40e31..45cf780557 100644
--- a/indra/newview/skins/default/xui/en/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_gear.xml
@@ -9,5 +9,5 @@
     <menu
      label="New Body Parts"
      layout="topleft"
-     name="COF.Geear.New_Body_Parts" />
+     name="COF.Gear.New_Body_Parts" />
 </toggleable_menu>
-- 
cgit v1.2.3


From 5ecac2e900054526c5e9e2fe5610f470ad06df32 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 8 Feb 2013 22:38:54 -0800
Subject: CHUI-735 : Fixed! Refactor the code to move isSelectionRemovable() to
 the LLInventoryPanel level. Use it when using the delete key.

---
 indra/newview/llinventorypanel.cpp     | 32 +++++++++++++++++++++++++++++++-
 indra/newview/llinventorypanel.h       |  1 +
 indra/newview/llpanelmaininventory.cpp | 22 +---------------------
 3 files changed, 33 insertions(+), 22 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 578b83fd28..1357b613bb 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1370,7 +1370,7 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
 	case KEY_BACKSPACE:
 		// Delete selected items if delete or backspace key hit on the inventory panel
 		// Note: on Mac laptop keyboards, backspace and delete are one and the same
-		if (mask == MASK_NONE)
+		if (isSelectionRemovable() && (mask == MASK_NONE))
 		{
 			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete");
 			handled = TRUE;
@@ -1380,6 +1380,36 @@ BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
 	return handled;
 }
 
+bool LLInventoryPanel::isSelectionRemovable()
+{
+	bool can_delete = false;
+	if (mFolderRoot)
+	{
+		std::set<LLFolderViewItem*> selection_set = mFolderRoot->getSelectionList();
+		if (!selection_set.empty()) 
+		{
+			can_delete = true;
+			for (std::set<LLFolderViewItem*>::iterator iter = selection_set.begin();
+				 iter != selection_set.end();
+				 ++iter)
+			{
+				LLFolderViewItem *item = *iter;
+				const LLFolderViewModelItemInventory *listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
+				if (!listener)
+				{
+					can_delete = false;
+				}
+				else
+				{
+					can_delete &= listener->isItemRemovable();
+					can_delete &= !listener->isItemInTrash();
+				}
+			}
+		}
+	}
+	return can_delete;
+}
+
 /************************************************************************/
 /* Recent Inventory Panel related class                                 */
 /************************************************************************/
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 6eb85fbad2..00a90325ad 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -162,6 +162,7 @@ public:
 	void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
 	void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
 	void clearSelection();
+	bool isSelectionRemovable();
 	LLInventoryFilter& getFilter();
 	const LLInventoryFilter& getFilter() const;
 	void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 82b79db60a..d6535c88e9 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -1112,27 +1112,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	const std::string command_name = userdata.asString();
 	if (command_name == "delete")
 	{
-		BOOL can_delete = FALSE;
-		LLFolderView* root = getActivePanel()->getRootFolder();
-		if (root)
-		{
-			can_delete = TRUE;
-			std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
-			if (selection_set.empty()) return FALSE;
-			for (std::set<LLFolderViewItem*>::iterator iter =    selection_set.begin();
-				 iter != selection_set.end();
-				 ++iter)
-			{
-				LLFolderViewItem *item = *iter;
-				const LLFolderViewModelItemInventory *listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
-				llassert(listener);
-				if (!listener) return FALSE;
-				can_delete &= listener->isItemRemovable();
-				can_delete &= !listener->isItemInTrash();
-			}
-			return can_delete;
-		}
-		return FALSE;
+		return getActivePanel()->isSelectionRemovable();
 	}
 	if (command_name == "save_texture")
 	{
-- 
cgit v1.2.3


From 9a75eeb67e9d768ad925c5d1f0e7ab180be8ee71 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 11 Feb 2013 14:39:05 +0200
Subject: Fix for build issue under windows

---
 indra/newview/llinventorypanel.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 1357b613bb..fabcd50c7d 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1401,8 +1401,7 @@ bool LLInventoryPanel::isSelectionRemovable()
 				}
 				else
 				{
-					can_delete &= listener->isItemRemovable();
-					can_delete &= !listener->isItemInTrash();
+					can_delete &= listener->isItemRemovable() && !listener->isItemInTrash();
 				}
 			}
 		}
-- 
cgit v1.2.3


From 4b4367269058c8ba10d284b48ffae9e24fd086ce Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 11 Feb 2013 15:22:24 +0200
Subject: CHUI-751 FIXED Triple click is now handled.

---
 indra/llui/lltextbase.cpp | 9 +++++++++
 indra/llui/lltextbase.h   | 3 ++-
 2 files changed, 11 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 4c9c2781f2..7cee9f5b46 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -46,6 +46,7 @@
 
 const F32	CURSOR_FLASH_DELAY = 1.0f;  // in seconds
 const S32	CURSOR_THICKNESS = 2;
+const F32	TRIPLE_CLICK_INTERVAL = 0.3f;	// delay between double and triple click.
 
 LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num) 
 :	mDocIndexStart(index_start), 
@@ -1004,6 +1005,13 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
 
 BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
 {
+	// handle triple click
+	if (!mTripleClickTimer.hasExpired())
+	{
+		selectAll();
+		return TRUE;
+	}
+
 	LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
 	if (cur_segment && cur_segment->handleMouseDown(x, y, mask))
 	{
@@ -1078,6 +1086,7 @@ BOOL LLTextBase::handleRightMouseUp(S32 x, S32 y, MASK mask)
 
 BOOL LLTextBase::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
+	mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
 	LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
 	if (cur_segment && cur_segment->handleDoubleClick(x, y, mask))
 	{
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 629b304b25..ad566a36d3 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -598,7 +598,8 @@ protected:
 	// selection
 	S32							mSelectionStart;
 	S32							mSelectionEnd;
-	
+	LLTimer		                mTripleClickTimer;
+
 	BOOL						mIsSelecting;		// Are we in the middle of a drag-select? 
 
 	// spell checking
-- 
cgit v1.2.3


From 5066e850df6e44e65bf7760ac990fdd5ed1c7b8e Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 11 Feb 2013 15:26:17 +0200
Subject: CHUI-728 FIXED Don't display Nearby chat participants if Conversation
 pane is collapsed.

---
 indra/newview/llfloaterimcontainer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 05db0e93e6..cef45a5b56 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1769,7 +1769,7 @@ void LLFloaterIMContainer::openNearbyChat()
 {
 	// If there's only one conversation in the container and that conversation is the nearby chat
 	//(which it should be...), open it so to make the list of participants visible. This happens to be the most common case when opening the Chat floater.
-	if(mConversationsItems.size() == 1)
+	if((mConversationsItems.size() == 1)&&(!mConversationsPane->isCollapsed()))
 	{
 		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,LLUUID()));
 		if (nearby_chat)
-- 
cgit v1.2.3


From 33d49d15693de15527960476b816845f8b3d6d54 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Mon, 11 Feb 2013 20:02:19 +0000
Subject: CHUI-755 FIX Conversation log changes in a session are lost if viewer
 crashes Added call to LLConversationLog::instance().cache() after
 LLLogChat::SaveHistory() in LLIMView::logToFile()

---
 indra/newview/llconversationlog.cpp | 2 +-
 indra/newview/llconversationlog.h   | 2 +-
 indra/newview/llimview.cpp          | 2 ++
 3 files changed, 4 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 82176b3a06..4e707ac76e 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -276,7 +276,7 @@ void LLConversationLog::updateConversationName(const LLIMModel::LLIMSession* ses
 	LLConversation* conversation = findConversation(session);
 	if (conversation)
 	{
-		conversation->setConverstionName(name);
+		conversation->setConversationName(name);
 		notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME);
 	}
 }
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index d5b6eccb29..fd38556131 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -58,7 +58,7 @@ public:
 	const time_t&		getTime()				const	{ return mTime; }
 	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }
 
-	void setConverstionName(std::string conv_name) { mConversationName = conv_name; }
+	void setConversationName(std::string conv_name) { mConversationName = conv_name; }
 	void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
 	bool isOlderThan(U32 days) const;
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 2eaef48049..cdf6cb6252 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -66,6 +66,7 @@
 #include "lltoolbarview.h"
 #include "llviewercontrol.h"
 #include "llviewerparcelmgr.h"
+#include "llconversationlog.h"
 #include "message.h"
 
 
@@ -950,6 +951,7 @@ bool LLIMModel::logToFile(const std::string& file_name, const std::string& from,
 		}
 
 		LLLogChat::saveHistory(file_name, from_name, from_id, utf8_text);
+		LLConversationLog::instance().cache(); // update the conversation log too
 		return true;
 	}
 	else
-- 
cgit v1.2.3


From f6b9d2bce45818f15e2882a7cb34ce9ea7a2e4ba Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Mon, 11 Feb 2013 20:39:03 +0000
Subject: CHUI-760 FIX Conversation.log file not saved in user specified
 location Changed LLConversationLog::getFileName() to use
 LL_PATH_PER_ACCOUNT_CHAT_LOGS instead of LL_PATH_PER_SL_ACCOUNT

---
 indra/newview/llconversationlog.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 4e707ac76e..15d61e978d 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -378,7 +378,7 @@ void LLConversationLog::cache()
 std::string LLConversationLog::getFileName()
 {
 	std::string filename = "conversation";
-	return gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, filename) + ".log";
+	return gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename) + ".log";
 }
 
 bool LLConversationLog::saveToFile(const std::string& filename)
-- 
cgit v1.2.3


From 279d4a95ea84ddeb32efc54deb6923202fe638a7 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Mon, 11 Feb 2013 16:08:45 -0800
Subject: CHUI-690 : Fixed! Prevent xml parsing error when building Places
 panel providing an option menu to the LLFolderView constructor

---
 indra/newview/llplacesinventorypanel.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index 01586a4d91..4c2213c198 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -82,6 +82,7 @@ LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )
     p.show_item_link_overlays = mShowItemLinkOverlays;
     p.root = NULL;
     p.use_ellipses = mParams.folder_view.use_ellipses;
+    p.options_menu = "menu_inventory.xml";
 
     return LLUICtrlFactory::create<LLPlacesFolderView>(p);
 }
-- 
cgit v1.2.3


From 5a92a7700666f40883b72deed8429e7e06164623 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Tue, 12 Feb 2013 01:12:47 +0000
Subject: CHUI-740 FIX Incorrect option shown in group Moderator tools "Toggle
 mute this participant" Reverted changes in menu_conversation.xml,
 llconversationmodel.cpp, and llfloaterimcontainer.cpp

---
 indra/newview/llconversationmodel.cpp                    |  3 ++-
 indra/newview/llfloaterimcontainer.cpp                   | 12 ++++++++++--
 indra/newview/skins/default/xui/en/menu_conversation.xml | 13 ++++++++++---
 3 files changed, 22 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index bfc564f407..0977056b2a 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -151,7 +151,8 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
 			items.push_back(std::string("Moderator Options"));
 			items.push_back(std::string("AllowTextChat"));
 			items.push_back(std::string("moderate_voice_separator"));
-			items.push_back(std::string("ModerateVoiceToggleMuteSelected"));
+			items.push_back(std::string("ModerateVoiceMuteSelected"));
+			items.push_back(std::string("ModerateVoiceUnMuteSelected"));
 			items.push_back(std::string("ModerateVoiceMute"));
 			items.push_back(std::string("ModerateVoiceUnmute"));
 		}
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index cef45a5b56..30ea9f10c0 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1245,7 +1245,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
     {
 		return LLAvatarActions::canOfferTeleport(uuids);
     }
-	else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute_unmute" == item))
+	else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item))
 	{
 		// *TODO : get that out of here...
 		return enableModerateContextMenuItem(item);
@@ -1589,10 +1589,18 @@ bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& user
 
 	bool voice_channel = speakerp->isInVoiceChannel();
 
-	if ("can_moderate_voice" == userdata || "can_mute_unmute" == userdata)
+	if ("can_moderate_voice" == userdata)
 	{
 		return voice_channel;
 	}
+	else if ("can_mute" == userdata)
+	{
+		return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+	else if ("can_unmute" == userdata)
+	{
+		return voice_channel && isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
 
 	// The last invoke is used to check whether the "can_allow_text_chat" will enabled
 	return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 46c6e19fa5..8583747da0 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -163,11 +163,18 @@
 		</menu_item_check>
 		<menu_item_separator layout="topleft" name="moderate_voice_separator" />
 		<menu_item_call
-		 label="Toggle mute this participant"
+		 label="Mute this participant"
 		 layout="topleft"
-		 name="ModerateVoiceToggleMuteSelected">
+		 name="ModerateVoiceMuteSelected">
 			<on_click function="Avatar.DoToSelected" parameter="selected" />
-			<on_enable function="Avatar.EnableItem" parameter="can_mute_unmute" />
+      <on_enable function="Avatar.EnableItem" parameter="can_mute" />
+    </menu_item_call>
+    <menu_item_call
+		 label="Unmute this participant"
+		 layout="topleft"
+		 name="ModerateVoiceUnMuteSelected">
+      <on_click function="Avatar.DoToSelected" parameter="selected" />
+      <on_enable function="Avatar.EnableItem" parameter="can_unmute" />
 		</menu_item_call>
 		<menu_item_call
 		 label="Mute everyone"
-- 
cgit v1.2.3


From 8aaedd0a5fc73f45684c029ca9f349d793e61e93 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 12 Feb 2013 14:27:52 +0200
Subject: CHUI-742 FIXED Update log location when closing Preference floater.

---
 indra/newview/llfloaterpreference.cpp | 13 ++++++++++---
 indra/newview/llfloaterpreference.h   |  3 ++-
 2 files changed, 12 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index da24bb3b8f..662d2df5d2 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -646,6 +646,9 @@ void LLFloaterPreference::cancel()
 		LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
 		pPathfindingConsole->onRegionBoundaryCross();
 	}
+
+	std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+	updateLogLocation(dir_name);
 }
 
 void LLFloaterPreference::onOpen(const LLSD& key)
@@ -1443,16 +1446,20 @@ void LLFloaterPreference::onClickLogPath()
 
 	std::string dir_name = picker.getDirName();
 	gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+	updateLogLocation(dir_name);
 	
+	// enable/disable 'Delete transcripts button
+	updateDeleteTranscriptsButton();
+}
+
+void LLFloaterPreference::updateLogLocation(const std::string& dir_name)
+{
 	gDirUtilp->setChatLogsDir(dir_name);
 	gDirUtilp->updatePerAccountChatLogsDir();
 	LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
 
 	// refresh IM floaters with new logs from files from new selected directory
 	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
-
-	// enable/disable 'Delete transcripts button
-	updateDeleteTranscriptsButton();
 }
 
 void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index f9f1d52244..dbd87f74a1 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -142,7 +142,8 @@ public:
 	void onClickDisablePopup();	
 	void resetAllIgnored();
 	void setAllIgnored();
-	void onClickLogPath();	
+	void onClickLogPath();
+	void updateLogLocation(const std::string& dir_name);
 	void enableHistory();
 	void setPersonalInfo(const std::string& visibility, bool im_via_email);
 	void refreshEnabledState();
-- 
cgit v1.2.3


From b1d03f940d4682db3e9866888d6f00f9300a55ed Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 12 Feb 2013 12:31:59 -0800
Subject: CHUI-758: Group notice received in DND mode causes crash on startup
 when auto-exiting DND mode. Crash occurred because two instances of the Group
 Notice notification were trying to be added from the persistent storage and
 then the DND storage.

---
 .../newview/lldonotdisturbnotificationstorage.cpp  | 32 ++++++++++++++--------
 indra/newview/llviewermessage.cpp                  |  5 +++-
 2 files changed, 25 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index f7af447a57..22f35752bd 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -164,22 +164,32 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
         {
             offerExists = true;
         }
-
-        //New notification needs to be added
-        notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
-		LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
-		if (responder == NULL)
+		
+		//Notification already exists due to persistent storage adding it first into the notification system
+		if(notification)
 		{
-			LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
-				<< notification->getType() << "'" << LL_ENDL;
+			notification->setDND(true);
+			instance.update(instance.find(notificationID));
 		}
+		//New notification needs to be added
 		else
 		{
-			LLNotificationResponderPtr responderPtr(responder);
-			notification->setResponseFunctor(responderPtr);
+			notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
+			LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
+			if (responder == NULL)
+			{
+				LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
+					<< notification->getType() << "'" << LL_ENDL;
+			}
+			else
+			{
+				LLNotificationResponderPtr responderPtr(responder);
+				notification->setResponseFunctor(responderPtr);
+			}
+
+			instance.add(notification);
 		}
-			
-		instance.add(notification);
+
 	}
 
     if(imToastExists)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 6bbfd30794..2340436a01 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2615,7 +2615,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				payload["sender_name"] = name;
 				payload["group_id"] = group_id;
 				payload["inventory_name"] = item_name;
-				payload["inventory_offer"] = info ? info->asLLSD() : LLSD();
+				if(info && info->asLLSD())
+				{
+					payload["inventory_offer"] = info->asLLSD();
+				}
 
 				LLSD args;
 				args["SUBJECT"] = subj;
-- 
cgit v1.2.3


From 649a191c4fd7880e41aff5aae07b31b2a6fa840a Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Wed, 13 Feb 2013 00:12:04 +0000
Subject: CHUI-740 FIX Incorrect option shown in group Moderator tools "Toggle
 mute this participant" Made mute and unmute invisible instead of disabled
 when not available

---
 indra/newview/skins/default/xui/en/menu_conversation.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index 8583747da0..cbd2343a3c 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -167,14 +167,14 @@
 		 layout="topleft"
 		 name="ModerateVoiceMuteSelected">
 			<on_click function="Avatar.DoToSelected" parameter="selected" />
-      <on_enable function="Avatar.EnableItem" parameter="can_mute" />
+      <on_visible function="Avatar.EnableItem" parameter="can_mute" />
     </menu_item_call>
     <menu_item_call
 		 label="Unmute this participant"
 		 layout="topleft"
 		 name="ModerateVoiceUnMuteSelected">
       <on_click function="Avatar.DoToSelected" parameter="selected" />
-      <on_enable function="Avatar.EnableItem" parameter="can_unmute" />
+      <on_visible function="Avatar.EnableItem" parameter="can_unmute" />
 		</menu_item_call>
 		<menu_item_call
 		 label="Mute everyone"
-- 
cgit v1.2.3


From d818252528aa68a387dc237d1c5a74d366c5a120 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Wed, 13 Feb 2013 01:38:24 +0000
Subject: CHUI-740 FIX Incorrect option shown in group Moderator tools "Toggle
 mute this participant" Added new
 LLFloaterIMContainer::visibleContextMenuItem() connected to
 "Avatar.VisibleItem"

---
 indra/newview/llfloaterimcontainer.cpp              | 21 +++++++++++++++++++--
 indra/newview/llfloaterimcontainer.h                |  5 +++--
 .../skins/default/xui/en/menu_conversation.xml      |  6 ++++--
 3 files changed, 26 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 30ea9f10c0..52e153a15e 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -68,8 +68,9 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param
     mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction,  this, _2));
 	
-    mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMContainer::checkContextMenuItem,	this, _2));
-    mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem,	this, _2));
+	mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMContainer::checkContextMenuItem,	this, _2));
+	mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem,	this, _2));
+	mEnableCallbackRegistrar.add("Avatar.VisibleItem", boost::bind(&LLFloaterIMContainer::visibleContextMenuItem,	this, _2));
     mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelected, this, _2));
     
     mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelectedGroup, this, _2));
@@ -1290,6 +1291,22 @@ bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_ve
     return false;
 }
 
+bool LLFloaterIMContainer::visibleContextMenuItem(const LLSD& userdata)
+{
+	const std::string& item = userdata.asString();
+
+	if ("show_mute" == item)
+	{
+		return !isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+	else if ("show_unmute" == item)
+	{
+		return isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+
+	return true;
+}
+
 void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
 {
     setVisibleAndFrontmost(false);
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index a28dba3b98..265ae8df4c 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -140,8 +140,9 @@ private:
     const LLConversationItem * getCurSelectedViewModelItem();
     void getParticipantUUIDs(uuid_vec_t& selected_uuids);
     void doToSelected(const LLSD& userdata);
-    bool checkContextMenuItem(const LLSD& userdata);
-    bool enableContextMenuItem(const LLSD& userdata);
+	bool checkContextMenuItem(const LLSD& userdata);
+	bool enableContextMenuItem(const LLSD& userdata);
+	bool visibleContextMenuItem(const LLSD& userdata);
     void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS);
     void doToSelectedGroup(const LLSD& userdata);
 
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index cbd2343a3c..fd5c86b3ca 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -167,14 +167,16 @@
 		 layout="topleft"
 		 name="ModerateVoiceMuteSelected">
 			<on_click function="Avatar.DoToSelected" parameter="selected" />
-      <on_visible function="Avatar.EnableItem" parameter="can_mute" />
+      <on_enable function="Avatar.EnableItem" parameter="can_mute" />
+      <on_visible function="Avatar.VisibleItem" parameter="show_mute" />
     </menu_item_call>
     <menu_item_call
 		 label="Unmute this participant"
 		 layout="topleft"
 		 name="ModerateVoiceUnMuteSelected">
       <on_click function="Avatar.DoToSelected" parameter="selected" />
-      <on_visible function="Avatar.EnableItem" parameter="can_unmute" />
+      <on_enable function="Avatar.EnableItem" parameter="can_unmute" />
+      <on_visible function="Avatar.VisibleItem" parameter="show_unmute" />
 		</menu_item_call>
 		<menu_item_call
 		 label="Mute everyone"
-- 
cgit v1.2.3


From a33104ec5522352e23cdb788c003f830cd03cc1a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 12 Feb 2013 19:26:24 -0800
Subject: CHUI-695: Viewer crash when accepting friend offer in conversations
 window. Problem was that LLIMToastNotifyPanel::snapToMessageHeight was
 calling LLToastPanel::reshape, which would then call
 LLIMToastNotifyPanel::reshape again. Resolution: Modified
 LLIMToastNotifyPanel::snapToMessageHeight to cleanly replicate what
 LLToastPanel::reshape was doing.

---
 indra/newview/lltoastnotifypanel.cpp | 22 +++++++++++++++++++++-
 indra/newview/lltoastnotifypanel.h   |  3 +++
 indra/newview/lltoastpanel.cpp       | 33 ++++++++++++++++++++-------------
 indra/newview/lltoastpanel.h         |  1 +
 4 files changed, 45 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 3fd056ea31..c5a8d85392 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -426,7 +426,27 @@ LLIMToastNotifyPanel::~LLIMToastNotifyPanel()
 void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
 {
 	LLToastPanel::reshape(width, height, called_from_parent);
-	snapToMessageHeight(mTextBox, MAX_LENGTH);
+	snapToMessageHeight();
+}
+
+void LLIMToastNotifyPanel::snapToMessageHeight()
+{
+	if(!mTextBox)
+	{
+		return;
+	}
+
+	//Add message height if it is visible
+	if (mTextBox->getVisible())
+	{
+		S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, MAX_LENGTH);
+
+		//reshape the panel with new height
+		if (new_panel_height != getRect().getHeight())
+		{
+			LLToastNotifyPanel::reshape( getRect().getWidth(), new_panel_height);
+		}
+	}
 }
 
 void LLIMToastNotifyPanel::compactButtons()
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index f93c7745af..d02171b512 100644
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -157,6 +157,9 @@ public:
 protected:
 	LLTextBase* mParentText;
 	LLUUID	mSessionID;
+
+private:
+	void snapToMessageHeight();
 };
 
 #endif /* LLTOASTNOTIFYPANEL_H_ */
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index 187aee207c..a30f841980 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -58,6 +58,25 @@ const LLUUID& LLToastPanel::getID()
 	return mNotification->id();
 }
 
+S32 LLToastPanel::computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount)
+{
+	S32 heightDelta = 0;
+	S32 maxTextHeight = message->getFont()->getLineHeight() * maxLineCount;
+
+	LLRect messageRect = message->getRect();
+	S32 oldTextHeight = messageRect.getHeight();
+
+	//Knowing the height is set to max allowed, getTextPixelHeight returns needed text height
+	//Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape.
+	S32 requiredTextHeight = message->getTextBoundingRect().getHeight();
+	S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
+
+	heightDelta = newTextHeight - oldTextHeight;
+	S32 new_panel_height = llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT);
+
+	return new_panel_height;
+}
+
 //snap to the message height if it is visible
 void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 {
@@ -69,19 +88,7 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 	//Add message height if it is visible
 	if (message->getVisible())
 	{
-		S32 heightDelta = 0;
-		S32 maxTextHeight = message->getFont()->getLineHeight() * maxLineCount;
-
-		LLRect messageRect = message->getRect();
-		S32 oldTextHeight = messageRect.getHeight();
-
-		//Knowing the height is set to max allowed, getTextPixelHeight returns needed text height
-		//Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape.
-		S32 requiredTextHeight = message->getTextBoundingRect().getHeight();
-		S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
-
-		heightDelta = newTextHeight - oldTextHeight;
-		S32 new_panel_height = llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT);
+		S32 new_panel_height = computeSnappedToMessageHeight(message, maxLineCount);
 
 		//reshape the panel with new height
 		if (new_panel_height != getRect().getHeight())
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index c22557206b..e4ab95007e 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -59,6 +59,7 @@ public:
 protected:
 	LLNotificationPtr mNotification;
 	void snapToMessageHeight(LLTextBase* message, S32 maxLineCount);
+	S32 computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount);
 };
 
 #endif /* LL_TOASTPANEL_H */
-- 
cgit v1.2.3


From 5f08b0553328c3811eb7de3390d2b92a193294c8 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 13 Feb 2013 12:10:21 +0200
Subject: CHUI-743 FIXED CHUI viewer ignores pre chui users Privacy settings to
 not keep IM logs and nearby chat logs

---
 indra/newview/app_settings/settings_per_account.xml | 11 -----------
 indra/newview/llstartup.cpp                         |  7 +++++++
 2 files changed, 7 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 0b589e2da6..363713f2f4 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -176,17 +176,6 @@
         <key>Value</key>
             <integer>1</integer>
         </map>
-    <key>LogInstantMessages</key>
-        <map>
-        <key>Comment</key>
-            <string>Log Instant Messages</string>
-        <key>Persist</key>
-            <integer>1</integer>
-        <key>Type</key>
-            <string>Boolean</string>
-        <key>Value</key>
-            <integer>1</integer>
-        </map>
     <key>LogShowHistory</key>
         <map>
         <key>Comment</key>
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ab86f752c1..37e6ded986 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -917,6 +917,13 @@ bool idle_startup()
 		// Overwrite default user settings with user settings								 
 		LLAppViewer::instance()->loadSettingsFromDirectory("Account");
 
+		// Convert 'LogInstantMessages' into 'KeepConversationLogTranscripts' for backward compatibility (CHUI-743).
+		LLControlVariablePtr logInstantMessagesControl = gSavedPerAccountSettings.getControl("LogInstantMessages");
+		if (logInstantMessagesControl.notNull())
+		{
+			gSavedPerAccountSettings.setS32("KeepConversationLogTranscripts", logInstantMessagesControl->getValue() ? 2 : 1);
+		}
+
 		// Need to set the LastLogoff time here if we don't have one.  LastLogoff is used for "Recent Items" calculation
 		// and startup time is close enough if we don't have a real value.
 		if (gSavedPerAccountSettings.getU32("LastLogoff") == 0)
-- 
cgit v1.2.3


From f8e43b6f6682eb613b0dc1f257b47008c09cd7f1 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 13 Feb 2013 15:08:49 +0200
Subject: CHUI-765 FIXED User's name is added to the list in Nearby tab.

---
 indra/newview/llpanelpeople.cpp                           |  4 ++++
 indra/newview/llpanelpeoplemenus.cpp                      |  9 +++++++++
 indra/newview/llworld.cpp                                 |  2 +-
 indra/newview/skins/default/xui/en/menu_people_nearby.xml | 15 +++++++++++++++
 4 files changed, 29 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 90e857265d..6667706333 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -1032,6 +1032,10 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)
 	}
 
 	LLUUID clicked_id = item->getAvatarId();
+	if(gAgent.getID() == clicked_id)
+	{
+		return;
+	}
 	
 #if 0 // SJB: Useful for testing, but not currently functional or to spec
 	LLAvatarActions::showProfile(clicked_id);
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 899771f3b9..61e9468ce5 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -99,6 +99,10 @@ LLContextMenu* NearbyMenu::createMenu()
 
 bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
 {
+	if(gAgent.getID() == mUUIDs.front())
+	{
+		return false;
+	}
 	std::string item = userdata.asString();
 
 	// Note: can_block and can_delete is used only for one person selected menu
@@ -176,6 +180,11 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
 	{
 		return LLAvatarActions::canOfferTeleport(mUUIDs);
 	}
+	else if (item == std::string("can_im") || item == std::string("can_callog") || item == std::string("can_invite") ||
+	         item == std::string("can_share") || item == std::string("can_pay"))
+	{
+		return true;
+	}
 	return false;
 }
 
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 09d17b3701..793becf0c8 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -1192,7 +1192,7 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
 	{
 		LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter;
 
-		if (!pVOAvatar->isDead() && !pVOAvatar->isSelf() && !pVOAvatar->mIsDummy)
+		if (!pVOAvatar->isDead() && !pVOAvatar->mIsDummy)
 		{
 			LLVector3d pos_global = pVOAvatar->getPositionGlobal();
 			LLUUID uuid = pVOAvatar->getID();
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
index 8014e81469..60a6c98514 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -15,6 +15,9 @@
      name="IM">
         <menu_item_call.on_click
          function="Avatar.IM" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_im"/> 
     </menu_item_call>
     <menu_item_call
     label="Offer Teleport"
@@ -42,6 +45,9 @@
      name="Chat history">
         <menu_item_call.on_click
          function="Avatar.Calllog" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_callog"/>
     </menu_item_call>
     <menu_item_separator />
     <menu_item_call
@@ -70,6 +76,9 @@
      name="Invite">
         <menu_item_call.on_click
          function="Avatar.InviteToGroup" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_invite"/>
     </menu_item_call>
     <menu_item_separator />
     <menu_item_call
@@ -88,6 +97,9 @@
      name="Share">
         <menu_item_call.on_click
          function="Avatar.Share" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_share"/>
     </menu_item_call>
     <menu_item_call
      label="Pay"
@@ -95,6 +107,9 @@
      name="Pay">
         <menu_item_call.on_click
          function="Avatar.Pay" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_pay"/> 
     </menu_item_call>
     <menu_item_check
      label="Block/Unblock"
-- 
cgit v1.2.3


From ab6eca089e2d2a0dceba284ba68eba16fcf2a875 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 13 Feb 2013 15:14:15 +0200
Subject: CHUI-737 FIXED  Reselect current conversation when floater is opened.

---
 indra/newview/llfloaterimcontainer.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index cef45a5b56..869e5992ca 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -259,6 +259,7 @@ void LLFloaterIMContainer::onOpen(const LLSD& key)
 {
 	LLMultiFloater::onOpen(key);
 	openNearbyChat();
+	reSelectConversation();
 	assignResizeLimits();
 }
 
-- 
cgit v1.2.3


From ca676a7175405495aa10a55586fab4dc5dcc6476 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 13 Feb 2013 19:05:40 +0200
Subject: CHUI-761 FIXED Clear log button will not clear transcripts.

---
 indra/newview/llconversationlog.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 15d61e978d..22277e6421 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -532,7 +532,6 @@ void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD&
 {
 	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
 	{
-		LLLogChat::deleteTranscripts();
 		mConversations.clear();
 		notifyObservers();
 	}
-- 
cgit v1.2.3


From a9f7c0089fe0a94879e5a9ad31cd6f8b5fb51c36 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 13 Feb 2013 19:12:25 +0200
Subject: CHUI-769 FIXED The text of the dialog is changed.

---
 indra/newview/skins/default/xui/en/notifications.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f8a35337ed..3ae9b206a4 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -10006,7 +10006,7 @@ Cannot create large prims that intersect other players.  Please re-try when othe
    icon="alertmodal.tga"
    name="PreferenceChatClearLog"
    type="alertmodal">
-    This will delete the log of previous conversations, and all transcripts of those conversations. Proceed?
+    This will delete the log of previous conversations. Proceed?
     <tag>confirm</tag>
     <usetemplate
      ignoretext="Confirm before I delete the log of previous conversations."
@@ -10019,7 +10019,7 @@ Cannot create large prims that intersect other players.  Please re-try when othe
    icon="alertmodal.tga"
    name="PreferenceChatDeleteTranscripts"
    type="alertmodal">
-    This will delete transcripts for all previous conversations. The list of conversations will not be affected. Proceed?
+    This will delete transcripts for all previous conversations. The list of conversations will not be affected. If you run scripts on your chat transcript files, you may want to proceed with caution. Proceed?
     <tag>confirm</tag>
     <usetemplate
      ignoretext="Confirm before I delete transcripts."
-- 
cgit v1.2.3


From a536cf5f4b3a850ebcab566b814c39ed9da03ceb Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 14 Feb 2013 17:44:43 +0200
Subject: CHUI-771 Fixed! Conversation not scrolled to in conversation list
 when clicking on toast: add scrolling to selected widget

---
 indra/newview/llfloaterimcontainer.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 21bd8ab1d2..4a19440caa 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1345,6 +1345,7 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     	if (widget && widget->getParentFolder())
     	{
     		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
+    		mConversationsRoot->scrollToShowSelection();
     	}
 
         //When in DND mode, remove stored IM notifications
-- 
cgit v1.2.3


From c7cac7896ee4ccdd71dad432f1314b85987e78cf Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 13 Feb 2013 20:44:38 +0200
Subject: CHUI-739 Fixed! FUI toolbars not displayed when switching between
 CHUI and release viewer : parsing declare values of Enums

---
 indra/llcommon/llinitparam.h    | 26 +++++++++++++++++++++-----
 indra/newview/lltoolbarview.cpp |  8 +++++---
 2 files changed, 26 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 75c87c4bdb..695403e3f4 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -439,7 +439,7 @@ namespace LLInitParam
 		{}
 
 		void operator ()(const std::string& name)
-	{
+	    {
 			*this = name;
 		}
 
@@ -516,14 +516,30 @@ namespace LLInitParam
 		{
 			static bool read(T& param, Parser* parser)
 			{
-				// read all enums as ints
+				std::string value_string;
+				//TypeValues<T>::value_t v;
+
+				// trying to get the declare value
+				parser_read_func_map_t::iterator string_func = parser->mParserReadFuncs->find(&typeid(std::string));
+				if (string_func != parser->mParserReadFuncs->end())
+				{
+					if (string_func->second(*parser, (void*)&value_string))
+					{
+						if (TypeValues<T>::getValueFromName(value_string, param))
+						{
+							return true;
+						}
+					}
+				}
+
+				// read enums as ints if it not declared as string
 				parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32));
 				if (found_it != parser->mParserReadFuncs->end())
 				{
-					S32 value;
-					if (found_it->second(*parser, (void*)&value))
+					S32 value_S32;
+					if (found_it->second(*parser, (void*)&value_S32))
 					{
-						param = (T)value;
+						param = (T)value_S32;
 						return true;
 					}
 				}
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index de07ad510b..b2318f9158 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -241,8 +241,9 @@ bool LLToolBarView::loadToolbars(bool force_default)
 	LLXUIParser parser;
 	if (!err)
 	{
-	parser.readXUI(root, toolbar_set, toolbar_file);
+	    parser.readXUI(root, toolbar_set, toolbar_file);
 	}
+
 	if (!err && !toolbar_set.validateBlock())
 	{
 		llwarns << "Unable to validate toolbars from file: " << toolbar_file << llendl;
@@ -254,8 +255,9 @@ bool LLToolBarView::loadToolbars(bool force_default)
 		if (force_default)
 		{
 			llerrs << "Unable to load toolbars from default file : " << toolbar_file << llendl;
-		return false;
-	}
+		    return false;
+	    }
+
 		// Try to load the default toolbars
 		return loadToolbars(true);
 	}
-- 
cgit v1.2.3


From 2f49f5ed0e03375df97c877f139f2283f1a1376d Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 13 Feb 2013 15:35:23 -0800
Subject: CHUI-770 : Fixed! Need to use the User Name and not the Account Name
 to save the favorites.

---
 indra/newview/llfavoritesbar.cpp | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index ba3d4036c9..e30dd51acb 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -1520,8 +1520,10 @@ void LLFavoritesOrderStorage::saveFavoritesSLURLs()
 
 	LLAvatarName av_name;
 	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Saved favorites for " << av_name.getAccountName() << llendl;
-	fav_llsd[av_name.getAccountName()] = user_llsd;
+	// Note : use the "John Doe" and not the "john.doe" version of the name 
+	// as we'll compare it with the stored credentials in the login panel.
+	lldebugs << "Saved favorites for " << av_name.getUserName() << llendl;
+	fav_llsd[av_name.getUserName()] = user_llsd;
 
 	llofstream file;
 	file.open(filename);
@@ -1539,10 +1541,12 @@ void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
 
 	LLAvatarName av_name;
 	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Removed favorites for " << av_name.getAccountName() << llendl;
-	if (fav_llsd.has(av_name.getAccountName()))
+	// Note : use the "John Doe" and not the "john.doe" version of the name.
+	// See saveFavoritesSLURLs() here above for the reason why.
+	lldebugs << "Removed favorites for " << av_name.getUserName() << llendl;
+	if (fav_llsd.has(av_name.getUserName()))
 	{
-		fav_llsd.erase(av_name.getAccountName());
+		fav_llsd.erase(av_name.getUserName());
 	}
 
 	llofstream out_file;
-- 
cgit v1.2.3


From 30248c2049f6e20fa20e5b9f61cbd1402905d9b8 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 13 Feb 2013 17:01:26 -0800
Subject: CHUI-695: When the 'Accept' button is pressed the toast panel will be
 resized to the conversation floater dimensions after all buttons and text has
 been added to the toast panel

---
 indra/newview/lltoastnotifypanel.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index c5a8d85392..4ef5ad845c 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -259,12 +259,6 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
 	setXMLFilename("");
 	buildFromFile("panel_notification.xml");
 
-	// reshape the panel to its previous size
-	if (current_rect.notEmpty())
-	{
-		reshape(current_rect.getWidth(), current_rect.getHeight());
-	}
-
     if(rect != LLRect::null)
     {
         this->setShape(rect);
@@ -407,6 +401,12 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
 	//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
 	mInfoPanel->setFollowsAll();
     snapToMessageHeight(mTextBox, MAX_LENGTH);
+
+	// reshape the panel to its previous size
+	if (current_rect.notEmpty())
+	{
+		reshape(current_rect.getWidth(), current_rect.getHeight());
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////
-- 
cgit v1.2.3


From 638d94eef75799d47f8b913e0909b4079e55c03b Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 14 Feb 2013 18:51:13 +0200
Subject: CHUI-739 : Clean up : FUI toolbars not displayed when switching
 between CHUI and release viewer

---
 indra/llcommon/llinitparam.h | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 695403e3f4..eb4d84d835 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -517,7 +517,6 @@ namespace LLInitParam
 			static bool read(T& param, Parser* parser)
 			{
 				std::string value_string;
-				//TypeValues<T>::value_t v;
 
 				// trying to get the declare value
 				parser_read_func_map_t::iterator string_func = parser->mParserReadFuncs->find(&typeid(std::string));
-- 
cgit v1.2.3


From 96bc3d206d890255300d367a70493f93cd0dc5f8 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 14 Feb 2013 17:27:05 -0800
Subject: CHUI-753 : Fixed (temptative) : Added some defensive coding in
 bringToFront() to make safer or avoid pointer casting.

---
 indra/llui/llfloater.cpp | 31 ++++++++++++-------------------
 1 file changed, 12 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 05b2a1b7c6..734e2cfda7 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -2357,7 +2357,6 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 {
 	if (mFrontChild == child)
 	{
-
 		if (give_focus && !gFocusMgr.childHasKeyboardFocus(child))
 		{
 			child->setFocus(TRUE);
@@ -2374,15 +2373,14 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 		// this floater is hosted elsewhere and hence not one of our children, abort
 		return;
 	}
-	std::vector<LLView*> floaters_to_move;
+	std::vector<LLFloater*> floaters_to_move;
 	// Look at all floaters...tab
-	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
+	for (child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it)
 	{
-		LLView* viewp = *child_it;
-		LLFloater *floater = (LLFloater *)viewp;
+		LLFloater* floater = dynamic_cast<LLFloater*>(*child_it);
 
 		// ...but if I'm a dependent floater...
-		if (child->isDependent())
+		if (floater && child->isDependent())
 		{
 			// ...look for floaters that have me as a dependent...
 			LLFloater::handle_set_iter_t found_dependent = floater->mDependents.find(child->getHandle());
@@ -2390,15 +2388,14 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 			if (found_dependent != floater->mDependents.end())
 			{
 				// ...and make sure all children of that floater (including me) are brought to front...
-				for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin();
-					dependent_it != floater->mDependents.end(); )
+				for (LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin();
+					dependent_it != floater->mDependents.end(); ++dependent_it)
 				{
 					LLFloater* sibling = dependent_it->get();
 					if (sibling)
 					{
 						floaters_to_move.push_back(sibling);
 					}
-					++dependent_it;
 				}
 				//...before bringing my parent to the front...
 				floaters_to_move.push_back(floater);
@@ -2406,10 +2403,10 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 		}
 	}
 
-	std::vector<LLView*>::iterator view_it;
-	for(view_it = floaters_to_move.begin(); view_it != floaters_to_move.end(); ++view_it)
+	std::vector<LLFloater*>::iterator floater_it;
+	for(floater_it = floaters_to_move.begin(); floater_it != floaters_to_move.end(); ++floater_it)
 	{
-		LLFloater* floaterp = (LLFloater*)(*view_it);
+		LLFloater* floaterp = *floater_it;
 		sendChildToFront(floaterp);
 
 		// always unminimize dependee, but allow dependents to stay minimized
@@ -2421,23 +2418,19 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 	floaters_to_move.clear();
 
 	// ...then bringing my own dependents to the front...
-	for(LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin();
-		dependent_it != child->mDependents.end(); )
+	for (LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin();
+		dependent_it != child->mDependents.end(); ++dependent_it)
 	{
 		LLFloater* dependent = dependent_it->get();
 		if (dependent)
 		{
 			sendChildToFront(dependent);
-			//don't un-minimize dependent windows automatically
-			// respect user's wishes
-			//dependent->setMinimized(FALSE);
 		}
-		++dependent_it;
 	}
 
 	// ...and finally bringing myself to front 
 	// (do this last, so that I'm left in front at end of this call)
-	if( *getChildList()->begin() != child ) 
+	if (*beginChild() != child)
 	{
 		sendChildToFront(child);
 	}
-- 
cgit v1.2.3


From c0433f1460b5cd96c093e3955ecf4ddcb6376f92 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 15 Feb 2013 13:15:14 +0200
Subject: CHUI-774 Fixed condition of the checking. Also the sound for Teleport
 offer will be played correctly now.

---
 indra/newview/llnotificationofferhandler.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index cde7bb18ce..a2bd96f35a 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -120,11 +120,11 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 				channel->addToast(p);
 
             //Will not play a notification sound for inventory and teleport offer based upon chat preference
-            bool playSound = !((notification->isDND())
-                               && (notification->getName() == "UserGiveItem"
-                                    && gSavedSettings.getBOOL("PlaySoundInventoryOffer") == FALSE)
-                                ||  notification->getName() == "TeleportOffered"
-                                    && gSavedSettings.getBOOL("PlaySoundTeleportOffer") == FALSE);
+            bool playSound = (!notification->isDND()
+                               && ((notification->getName() == "UserGiveItem"
+                                    && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
+                               || (notification->getName() == "TeleportOffered"
+                                    && gSavedSettings.getBOOL("PlaySoundTeleportOffer"))));
 
             if(playSound)
             {
-- 
cgit v1.2.3


From eb8611de12abebb30c4d4f1d418165486cd59faa Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 15 Feb 2013 13:27:37 +0200
Subject: CHUI-755 FIXED cache() is called to update conversation.log file
 after deleting conversations.

---
 indra/newview/llconversationlog.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 22277e6421..23a98fa136 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -333,6 +333,7 @@ void LLConversationLog::removeConversation(const LLConversation& conversation)
 		{
 			mConversations.erase(conv_it);
 			notifyObservers();
+			cache();
 			return;
 		}
 	}
@@ -534,5 +535,6 @@ void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD&
 	{
 		mConversations.clear();
 		notifyObservers();
+		cache();
 	}
 }
-- 
cgit v1.2.3


From 8c20b1e002e2056b27b3bc4613cf077a4a6d3774 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 14 Feb 2013 18:33:07 +0200
Subject: CHUI-773 Conversation line item does not flash for unselected
 conversation when Flash Toolbar Button preference is selected: add flashing
 in "toast" case when session floater is open but not selected

---
 indra/newview/llimview.cpp | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cdf6cb6252..cf6a215970 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -213,16 +213,14 @@ void on_new_message(const LLSD& msg)
     //conversation floater not focused (visible or not)
     bool conversation_floater_not_focused =
     		conversation_floater_is_closed || !im_box->hasFocus();
-
-    // Skip toasting and flashing if we have open window of IM with this session id
-    if (session_floater
-    && session_floater->isInVisibleChain()
-    && !session_floater->isMinimized()
-    && !(session_floater->getHost() && session_floater->getHost()->isMinimized()))
-    {
-       return;
-    }
-    if ("toast" == action)
+    // sess. floater is open
+    bool session_floater_is_open =
+            session_floater
+            && session_floater->isInVisibleChain()
+            && !session_floater->isMinimized()
+            && !(session_floater->getHost() && session_floater->getHost()->isMinimized());
+
+    if ("toast" == action && !session_floater_is_open)
     {
         //User is not focused on conversation containing the message
         if(session_floater_not_focused)
@@ -254,7 +252,7 @@ void on_new_message(const LLSD& msg)
     {
     	if (conversation_floater_not_focused)
     	{
-            if(session_floater_not_focused && !gAgent.isDoNotDisturb())
+            if(!session_floater_is_open && !gAgent.isDoNotDisturb())
             {
             	//User is not focused on conversation containing the message
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
@@ -273,7 +271,7 @@ void on_new_message(const LLSD& msg)
         }
     }
 
-    else if("openconversations" == action)
+    else if("openconversations" == action && !session_floater_is_open)
     {
         //User is not focused on conversation containing the message
         if(session_floater_not_focused)
-- 
cgit v1.2.3


From fdd55c279e303ffe86d715c697db595c89071703 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 18 Feb 2013 14:59:03 +0200
Subject: CHUI-742 FIXED Do not update Log locations immediately after
 selecting a new location.

---
 indra/newview/llfloaterpreference.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 662d2df5d2..b1b22efc56 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1446,7 +1446,6 @@ void LLFloaterPreference::onClickLogPath()
 
 	std::string dir_name = picker.getDirName();
 	gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
-	updateLogLocation(dir_name);
 	
 	// enable/disable 'Delete transcripts button
 	updateDeleteTranscriptsButton();
-- 
cgit v1.2.3


From 7f63b36977107f5bbfc1a1682cb91fea3985fef4 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 18 Feb 2013 15:01:36 +0200
Subject: CHUI-775 FIXED We should always handle changing of preferences.

---
 indra/newview/llconversationlog.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 23a98fa136..fc3bc8551c 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -192,11 +192,11 @@ LLConversationLog::LLConversationLog() :
 {
 	LLControlVariable * keep_log_ctrlp = gSavedPerAccountSettings.getControl("KeepConversationLogTranscripts").get();
 	S32 log_mode = keep_log_ctrlp->getValue();
-
+	keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
 	if (log_mode > 0)
 	{
 		loadFromFile(getFileName());
-		keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+
 		enableLogging(log_mode);
 	}
 }
-- 
cgit v1.2.3


From 2928789484c9eb88e9970af1ce5d5e42320c97bd Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 15 Feb 2013 22:35:25 +0200
Subject: CHUI-767 First click on << icon in a session to collapse message
 panel has no action : delete an obsolete (after the changeset 1cbf27ea0b4e)
 code

---
 indra/newview/llfloaterimcontainer.cpp | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 4a19440caa..2f2b09b589 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -639,11 +639,7 @@ void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 		return;
 	}
 
-	if (mIsFirstLaunch)
-	{
-		mIsFirstLaunch = false;
-		return;
-	}
+	mIsFirstLaunch = false;
 
 	// Save current width of panels before collapsing/expanding right pane.
 	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
-- 
cgit v1.2.3


From e4ea94b62226aebb4408360a033b2c1c71aa4ef6 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 18 Feb 2013 18:56:22 +0200
Subject: CHUI-779 FIXED Chat log preferences are disabled before login.

---
 indra/newview/llfloaterpreference.cpp                         | 1 +
 indra/newview/skins/default/xui/en/panel_preferences_chat.xml | 2 ++
 2 files changed, 3 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index b1b22efc56..3d8d0e15ec 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1491,6 +1491,7 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	getChildView("favorites_on_login_check")->setEnabled(TRUE);
 	getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
 	getChildView("log_path_button")->setEnabled(TRUE);
+	getChildView("chat_font_size")->setEnabled(TRUE);
 }
 
 void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 9b22c8c6dd..9db3816c92 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -373,6 +373,7 @@
     </text>
 
     <combo_box
+        enabled="false"
         control_name="KeepConversationLogTranscripts"
         height="23"
         layout="topleft"
@@ -428,6 +429,7 @@
     </text>
   
     <line_editor
+    	enabled="false"
         control_name="InstantMessageLogPath"
         border_style="line"
         border_thickness="1"
-- 
cgit v1.2.3


From 45849294cefd33c4875b5fe5b3fc8f04745452cf Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Mon, 18 Feb 2013 20:30:22 -0800
Subject: CHUI-739 FIX FUI toolbars not displayed when switching between CHUI
 and release viewer param blocks no longer write enums as ints

---
 indra/llcommon/llinitparam.h | 94 +++++++++++++++++---------------------------
 1 file changed, 35 insertions(+), 59 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 75c87c4bdb..66aac4f549 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -485,62 +485,6 @@ namespace LLInitParam
 		typedef std::map<const std::type_info*, parser_write_func_t>	parser_write_func_map_t;
 		typedef std::map<const std::type_info*, parser_inspect_func_t>	parser_inspect_func_map_t;
 
-	private:
-		template<typename T, bool is_enum = boost::is_enum<T>::value>
-		struct ReaderWriter
-		{
-			static bool read(T& param, Parser* parser)
-			{
-				parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(T));
-				if (found_it != parser->mParserReadFuncs->end())
-				{
-					return found_it->second(*parser, (void*)&param);
-				}
-				return false;
-			}
-			
-			static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
-			{
-				parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(T));
-				if (found_it != parser->mParserWriteFuncs->end())
-				{
-					return found_it->second(*parser, (const void*)&param, name_stack);
-				}
-				return false;
-			}
-		};
-
-		// read enums as ints
-		template<typename T>
-		struct ReaderWriter<T, true>
-		{
-			static bool read(T& param, Parser* parser)
-			{
-				// read all enums as ints
-				parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32));
-				if (found_it != parser->mParserReadFuncs->end())
-				{
-					S32 value;
-					if (found_it->second(*parser, (void*)&value))
-					{
-						param = (T)value;
-						return true;
-					}
-				}
-				return false;
-			}
-
-			static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
-			{
-				parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(S32));
-				if (found_it != parser->mParserWriteFuncs->end())
-				{
-					return found_it->second(*parser, (const void*)&param, name_stack);
-				}
-				return false;
-			}
-		};
-
 	public:
 
 		Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
@@ -552,14 +496,46 @@ namespace LLInitParam
 
 		virtual ~Parser();
 
-		template <typename T> bool readValue(T& param)
+		template <typename T> bool readValue(T& param, typename boost::disable_if<boost::is_enum<T> >::type* dummy = 0)
 	    {
-			return ReaderWriter<T>::read(param, this);
+			parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+			if (found_it != mParserReadFuncs->end())
+			{
+				return found_it->second(*this, (void*)&param);
+			}
+			
+			return false;
 	    }
 
+		template <typename T> bool readValue(T& param, typename boost::enable_if<boost::is_enum<T> >::type* dummy = 0)
+		{
+			parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+			if (found_it != mParserReadFuncs->end())
+			{
+				return found_it->second(*this, (void*)&param);
+			}
+			else
+			{
+				found_it = mParserReadFuncs->find(&typeid(S32));
+				if (found_it != mParserReadFuncs->end())
+				{
+					S32 int_value;
+					bool parsed = found_it->second(*this, (void*)&int_value);
+					param = (T)int_value;
+					return parsed;
+				}
+			}
+			return false;
+		}
+
 		template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
 		{
-			return ReaderWriter<T>::write(param, this, name_stack);
+			parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
+			if (found_it != mParserWriteFuncs->end())
+			{
+				return found_it->second(*this, (const void*)&param, name_stack);
+			}
+			return false;
 		}
 
 		// dispatch inspection to registered inspection functions, for each parameter in a param block
-- 
cgit v1.2.3


From 927fcf5d0b6eac067e40ac415b3a5ce10dbc4903 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 18 Feb 2013 16:36:55 +0200
Subject: CHUI-768 Conversation panel resize issue with message panel collapsed
 : manually resize of the conversations panel

---
 indra/newview/llfloaterimcontainer.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2f2b09b589..c1959729d1 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -535,6 +535,13 @@ void LLFloaterIMContainer::draw()
 		setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
 	}
 
+    // "Manually" resize of mConversationsPane: same as temporarity cancellation of the flag "auto_resize=false" for it
+	if (!mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed())
+	{
+		LLRect stack_rect = mConversationsStack->getRect();
+		mConversationsPane->reshape(stack_rect.getWidth(), stack_rect.getHeight(), true);
+	}
+
 	LLFloater::draw();
 }
 
@@ -654,6 +661,8 @@ void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
 	}
 
+	mConversationsPane->setIgnoreReshape(collapse);
+
 	// Show/hide the messages pane.
 	mConversationsStack->collapsePanel(mMessagesPane, collapse);
 
-- 
cgit v1.2.3


From 7b2cbf254ae102738d9e7b41e9cec55a867ec755 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 19 Feb 2013 15:45:36 +0200
Subject: CHUI-702 FIXED Call requestArrange() after showing Voice indicator to
 avoid overlapping.

---
 indra/newview/llconversationview.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 5ff013ccc4..5ac6353daa 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -340,6 +340,7 @@ LLConversationViewParticipant* LLConversationViewSession::findParticipant(const
 void LLConversationViewSession::showVoiceIndicator(bool visible)
 {
 	mCallIconLayoutPanel->setVisible(visible && LLVoiceChannel::getCurrentVoiceChannel()->getSessionID().isNull());
+	requestArrange();
 }
 
 void LLConversationViewSession::refresh()
-- 
cgit v1.2.3


From 50d50019d8b8350bc7b04b0b49c6107cde62f4b0 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 18 Feb 2013 20:02:43 +0200
Subject: CHUI-729 FIXED Messages pane displays incorrect after changing size
 and relogin

---
 indra/llui/llfloater.h                 |  2 +-
 indra/newview/llfloaterimcontainer.cpp | 14 ++++++++++++++
 indra/newview/llfloaterimcontainer.h   |  2 ++
 3 files changed, 17 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index a6a85fc7d1..157b9b0113 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -224,7 +224,7 @@ public:
 	void			openFloater(const LLSD& key = LLSD());
 
 	// If allowed, close the floater cleanly, releasing focus.
-	void			closeFloater(bool app_quitting = false);
+	virtual void	closeFloater(bool app_quitting = false);
 
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 	
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c1959729d1..86d205a920 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1851,4 +1851,18 @@ void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id,
 	}
 }
 
+void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
+{
+	// Always unminimize before trying to close.
+	// Most of the time the user will never see this state.
+	setMinimized(FALSE);
+
+	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
+
+	// Save the conversations pane width before collapsing it.
+	gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", conv_pane_width);
+
+	LLFloater::closeFloater(app_quitting);
+}
+
 // EOF
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 265ae8df4c..569fa9faab 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -109,6 +109,8 @@ public:
 
 	void assignResizeLimits();
 
+	/*virtual*/ void closeFloater(bool app_quitting = false);
+
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
 	avatarID_panel_map_t mSessions;
-- 
cgit v1.2.3


From becf7f8b605dfde99045e48274cb4cb3107443f5 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 19 Feb 2013 23:34:34 +0200
Subject: CHUI-729 FIXED Messages pane displays incorrect after changing size
 and relogin

---
 indra/newview/llfloaterimcontainer.cpp | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 86d205a920..5213413aea 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -230,12 +230,10 @@ BOOL LLFloaterIMContainer::postBuild()
 	mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
 	if (! mMessagesPane->isCollapsed())
 	{
-		S32 list_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
-		LLRect list_size = mConversationsPane->getRect();
-        S32 left_pad = mConversationsListPanel->getRect().mLeft;
-		list_size.mRight = list_size.mLeft + list_width - left_pad;
-
-        mConversationsPane->handleReshape(list_size, TRUE);
+		S32 conversations_panel_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
+		LLRect conversations_panel_rect = mConversationsPane->getRect();
+		conversations_panel_rect.mRight = conversations_panel_rect.mLeft + conversations_panel_width;
+        mConversationsPane->handleReshape(conversations_panel_rect, TRUE);
 	}
 
 	// Init the sort order now that the root had been created
-- 
cgit v1.2.3


From 3ae9124ce555dada3d14ede28a6658cddcfa53b8 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 20 Feb 2013 19:06:49 -0800
Subject: CHUI-395 : Fixed! Check the moderator status in the group data when
 loading the group list

---
 indra/newview/llspeakers.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index a2d8874cea..05df7261e1 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -557,7 +557,8 @@ void LLSpeakerMgr::updateSpeakerList()
 						// Add only the members who are online
 						if (member->getOnlineStatus() == "Online")
 						{
-							setSpeaker(member_it->first, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+							LLPointer<LLSpeaker> speakerp = setSpeaker(member_it->first, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+							speakerp->mIsModerator = ((member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR);
 						}
 						++member_it;
 					}
-- 
cgit v1.2.3


From c48e644220ad1708a93987faf9ac96bcdd097dec Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 20 Feb 2013 17:11:50 +0200
Subject: CHUI-773 ADD FIX Conversation line item does not flash for unselected
 conversation when Flash Toolbar Button preference is selected : repair case
 "open and not on top"

---
 indra/newview/llimview.cpp | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cf6a215970..d69bd89f13 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -199,8 +199,14 @@ void on_new_message(const LLSD& msg)
     // execution of the action
 
     LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
+	if (im_box->isFrontmost() && im_box->getSelectedSession() == session_id)
+	{
+		return;
+	}
+
+	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+	
     //session floater not focused (visible or not)
     bool session_floater_not_focused = session_floater && !session_floater->hasFocus();
 
@@ -250,25 +256,21 @@ void on_new_message(const LLSD& msg)
 
     else if ("flash" == action)
     {
-    	if (conversation_floater_not_focused)
+    	if (!gAgent.isDoNotDisturb())
     	{
-            if(!session_floater_is_open && !gAgent.isDoNotDisturb())
-            {
-            	//User is not focused on conversation containing the message
-                gToolBarView->flashCommand(LLCommandId("chat"), true);
-            }
-
-            im_box->flashConversationItemWidget(session_id, true);
-
-            //If a DND message, allow notification to be stored so upon DND exit 
-            //useMostItrusiveIMNotification will be called to notify user a message exists
-            if(session_id.notNull() 
-                && participant_id.notNull() 
-                && gAgent.isDoNotDisturb())
-            {
-                LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
-            }
-        }
+			im_box->flashConversationItemWidget(session_id, true);
+			if(conversation_floater_not_focused)
+			{
+				//User is not focused on conversation containing the message
+				gToolBarView->flashCommand(LLCommandId("chat"), true);
+			}
+		}
+		else if(session_id.notNull() && participant_id.notNull())
+		{
+			//If a DND message, allow notification to be stored so upon DND exit 
+			//useMostItrusiveIMNotification will be called to notify user a message exists
+			LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+		}
     }
 
     else if("openconversations" == action && !session_floater_is_open)
-- 
cgit v1.2.3


From 8ed2072aa25a99d1da6c18de990bf155e65dc1ca Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 20 Feb 2013 13:47:20 +0200
Subject: CHUI-768 ADD FIX Conversation panel resize issue with message panel
 collapse : correctly assign of a left panel resize limits

---
 indra/newview/llfloaterimcontainer.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 5213413aea..72febcf431 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -758,7 +758,9 @@ void LLFloaterIMContainer::assignResizeLimits()
 	// between the panels are merged into one
     S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3);
     S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH;
-	S32 conv_pane_current_width = is_conv_pane_expanded? mConversationsPane->getRect().getWidth() : mConversationsPane->getMinDim();
+	S32 conv_pane_current_width = is_msg_pane_expanded
+			? mConversationsPane->getRect().getWidth()
+			: (is_conv_pane_expanded? mConversationsPane->getExpandedMinDim() : mConversationsPane->getMinDim());
 	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
 	S32 new_min_width = conv_pane_current_width + msg_pane_min_width + summary_width_of_visible_borders;
 
-- 
cgit v1.2.3


From bfdd9b2e134110c7ed7b68925f78aac721e66905 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 19 Feb 2013 23:38:57 +0200
Subject: CHUI-756 Minimized chat opens when start new conversation : saving of
 the minimized state of an session floater

---
 indra/newview/llfloaterimcontainer.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 72febcf431..60e306eef4 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1384,7 +1384,9 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 		// Set the focus on the selected floater
 		if (!session_floater->hasFocus())
 		{
+			BOOL is_minimized = session_floater->isMinimized();
 			session_floater->setFocus(TRUE);
+			session_floater->setMinimized(is_minimized);
 		}
 	}
 
-- 
cgit v1.2.3


From 4eba77e7db0b60a9d422409521162ef4cd541128 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 20 Feb 2013 01:17:58 +0200
Subject: CHUI-590 FIXED Put voice volume control back into avatar inspector.

---
 indra/newview/llinspectavatar.cpp                  | 100 +++++++++++++++++++++
 .../skins/default/xui/en/inspect_avatar.xml        |  30 ++++++-
 2 files changed, 128 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 26d3a2bd12..1e15dc832c 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -28,13 +28,17 @@
 #include "llinspectavatar.h"
 
 // viewer files
+#include "llagent.h"
+#include "llavataractions.h"
 #include "llavatariconctrl.h"
 #include "llavatarnamecache.h"
 #include "llavatarpropertiesprocessor.h"
 #include "lldateutil.h"
 #include "llinspect.h"
+#include "llmutelist.h"
 #include "llslurl.h"
 #include "llstartup.h"
+#include "llvoiceclient.h"
 #include "lltransientfloatermgr.h"
 
 // Linden libraries
@@ -63,6 +67,8 @@ public:
 	// Inspector will be positioned relative to current mouse position
 	LLInspectAvatar(const LLSD& avatar_id);
 	virtual ~LLInspectAvatar();
+
+	/*virtual*/ BOOL postBuild(void);
 	
 	// Because floater is single instance, need to re-parse data on each spawn
 	// (for example, inspector about same avatar but in different position)
@@ -77,6 +83,14 @@ private:
 	// Make network requests for all the data to display in this view.
 	// Used on construction and if avatar id changes.
 	void requestUpdate();
+
+	// Set the volume slider to this user's current client-side volume setting,
+	// hiding/disabling if the user is not nearby.
+	void updateVolumeSlider();
+
+	// Button callbacks
+	void onClickMuteVolume();
+	void onVolumeChange(const LLSD& data);
 	
 	void onAvatarNameCache(const LLUUID& agent_id,
 						   const LLAvatarName& av_name);
@@ -165,6 +179,18 @@ LLInspectAvatar::~LLInspectAvatar()
 	LLTransientFloaterMgr::getInstance()->removeControlView(this);
 }
 
+/*virtual*/
+BOOL LLInspectAvatar::postBuild(void)
+{
+	getChild<LLUICtrl>("mute_btn")->setCommitCallback(
+		boost::bind(&LLInspectAvatar::onClickMuteVolume, this) );
+
+	getChild<LLUICtrl>("volume_slider")->setCommitCallback(
+		boost::bind(&LLInspectAvatar::onVolumeChange, this, _2));
+
+	return TRUE;
+}
+
 // Multiple calls to showInstance("inspect_avatar", foo) will provide different
 // LLSD for foo, which we will catch here.
 //virtual
@@ -193,6 +219,8 @@ void LLInspectAvatar::onOpen(const LLSD& data)
 
 	// can't call from constructor as widgets are not built yet
 	requestUpdate();
+
+	updateVolumeSlider();
 }
 
 void LLInspectAvatar::requestUpdate()
@@ -265,6 +293,78 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)
 	mPropertiesRequest = NULL;
 }
 
+void LLInspectAvatar::updateVolumeSlider()
+{
+	bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID);
+
+	// Do not display volume slider and mute button if it 
+	// is ourself or we are not in a voice channel together
+	if (!voice_enabled || (mAvatarID == gAgent.getID()))
+	{
+		getChild<LLUICtrl>("mute_btn")->setVisible(false);
+		getChild<LLUICtrl>("volume_slider")->setVisible(false);
+	}
+
+	else 
+	{
+		getChild<LLUICtrl>("mute_btn")->setVisible(true);
+		getChild<LLUICtrl>("volume_slider")->setVisible(true);
+
+		// By convention, we only display and toggle voice mutes, not all mutes
+		bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
+
+		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
+
+		bool is_linden = LLStringUtil::endsWith(mAvatarName.getDisplayName(), " Linden");
+
+		mute_btn->setEnabled( !is_linden);
+		mute_btn->setValue( is_muted );
+
+		LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
+		volume_slider->setEnabled( !is_muted );
+
+		F32 volume;
+		
+		if (is_muted)
+		{
+			// it's clearer to display their volume as zero
+			volume = 0.f;
+		}
+		else
+		{
+			// actual volume
+			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
+		}
+		volume_slider->setValue( (F64)volume );
+	}
+
+}
+
+void LLInspectAvatar::onClickMuteVolume()
+{
+	// By convention, we only display and toggle voice mutes, not all mutes
+	LLMuteList* mute_list = LLMuteList::getInstance();
+	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
+
+	LLMute mute(mAvatarID, mAvatarName.getDisplayName(), LLMute::AGENT);
+	if (!is_muted)
+	{
+		mute_list->add(mute, LLMute::flagVoiceChat);
+	}
+	else
+	{
+		mute_list->remove(mute, LLMute::flagVoiceChat);
+	}
+
+	updateVolumeSlider();
+}
+
+void LLInspectAvatar::onVolumeChange(const LLSD& data)
+{
+	F32 volume = (F32)data.asReal();
+	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
+}
+
 void LLInspectAvatar::onAvatarNameCache(
 		const LLUUID& agent_id,
 		const LLAvatarName& av_name)
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index c3481e6d4c..ef4f19cd4c 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -2,14 +2,14 @@
 <!--
   Not can_close / no title to avoid window chrome
   Single instance - only have one at a time, recycle it each spawn
--->
+--> 
 <floater
  legacy_header_height="25"
  bevel_style="in"
  bg_opaque_image="Inspector_Background"
  can_close="false"
  can_minimize="false"
- height="130"
+ height="160"
  layout="topleft"
  name="inspect_avatar"
  single_instance="true"
@@ -94,6 +94,32 @@
      use_ellipses="true"
      width="220">This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot
     </text>
+    <slider
+     follows="top|left"
+     height="23"
+     increment="0.01"
+     left="10"
+     max_val="0.95"
+     min_val="0.05"
+     name="volume_slider"
+     show_text="false"
+     tool_tip="Voice volume"
+     top_pad="5"
+     value="0.5"
+     width="200" />
+    <button
+     follows="top|left"
+     height="16"
+     image_disabled="Audio_Off"
+     image_disabled_selected="AudioMute_Off"
+     image_hover_selected="AudioMute_Over"
+     image_selected="AudioMute_Off"
+     image_unselected="Audio_Off"
+     is_toggle="true"
+     left_pad="5"
+     top_delta="4"
+     name="mute_btn"
+     width="16" />
     <text
      follows="top|left"
      height="16"
-- 
cgit v1.2.3


From 61c1b2fe2bde94a5f77597725e446a5345219ebe Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 19 Feb 2013 16:38:22 -0800
Subject: CHUI-778 (Saving preferences updates text in all open message panels
 in conversation floater to show as old messages) Problem was that closing the
 preferences floater was always acting as if the conversation transcripts/log
 files path had changed. If the path did not change then the user's
 conversations would be cleared and re-loaded as if they were part of the
 user's history (causing text to be grey). Solution: Now keep track of when
 the path was changed and only load up the transcripts/log upon change.

---
 indra/newview/llfloaterpreference.cpp | 28 ++++++++++++++++++++--------
 indra/newview/llfloaterpreference.h   |  1 +
 2 files changed, 21 insertions(+), 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3d8d0e15ec..b3e3a0678b 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -647,8 +647,12 @@ void LLFloaterPreference::cancel()
 		pPathfindingConsole->onRegionBoundaryCross();
 	}
 
-	std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
-	updateLogLocation(dir_name);
+	if(mInstantMessageLogPathChanged)
+	{
+		std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+		updateLogLocation(dir_name);
+		mInstantMessageLogPathChanged = false;
+	}
 }
 
 void LLFloaterPreference::onOpen(const LLSD& key)
@@ -1436,19 +1440,27 @@ void LLFloaterPreference::setAllIgnored()
 
 void LLFloaterPreference::onClickLogPath()
 {
-	std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));	 
+	std::string original_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+	std::string proposed_name(original_name);	 
+	mInstantMessageLogPathChanged = false;
 	
 	LLDirPicker& picker = LLDirPicker::instance();
+	//Launches a directory picker and waits for feedback
 	if (!picker.getDir(&proposed_name ) )
 	{
 		return; //Canceled!
 	}
 
-	std::string dir_name = picker.getDirName();
-	gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
-	
-	// enable/disable 'Delete transcripts button
-	updateDeleteTranscriptsButton();
+	//Path changed
+	if(original_name != proposed_name)
+	{
+		std::string dir_name = picker.getDirName();
+		gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+		mInstantMessageLogPathChanged = true;
+
+		// enable/disable 'Delete transcripts button
+		updateDeleteTranscriptsButton();
+	}
 }
 
 void LLFloaterPreference::updateLogLocation(const std::string& dir_name)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index dbd87f74a1..c72346c3b6 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -186,6 +186,7 @@ private:
 	bool mGotPersonalInfo;
 	bool mOriginalIMViaEmail;
 	bool mLanguageChanged;
+	bool mInstantMessageLogPathChanged;
 	bool mAvatarDataInitialized;
 	
 	bool mOriginalHideOnlineStatus;
-- 
cgit v1.2.3


From 2dfdd050d487df6aaa7a169208e02b30a313127f Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 20 Feb 2013 16:47:54 +0200
Subject: CHUI-784 FIXED Crash when closing expanded group chat

---
 indra/newview/llfloaterimcontainer.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 60e306eef4..c8088588da 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1526,10 +1526,10 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	if (widget)
 	{
 		is_widget_selected = widget->isSelected();
-		new_selection = mConversationsRoot->getNextFromChild(widget);
+		new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
 		if (!new_selection)
 		{
-			new_selection = mConversationsRoot->getPreviousFromChild(widget);
+			new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
 		}
 		widget->destroyView();
 	}
-- 
cgit v1.2.3


From 10dfe2d53413d2522038e79d4921a2305762dd63 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 20 Feb 2013 15:51:44 -0800
Subject: CHUI-778: Minor changes, prior commit was not changing the file path
 correctly due to logic error. Also clicking the 'Cancel' in preferences would
 still cause the file location to be saved instead of ignore the save.

---
 indra/newview/llfloaterpreference.cpp | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index b3e3a0678b..e5444583d6 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -646,13 +646,6 @@ void LLFloaterPreference::cancel()
 		LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
 		pPathfindingConsole->onRegionBoundaryCross();
 	}
-
-	if(mInstantMessageLogPathChanged)
-	{
-		std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
-		updateLogLocation(dir_name);
-		mInstantMessageLogPathChanged = false;
-	}
 }
 
 void LLFloaterPreference::onOpen(const LLSD& key)
@@ -802,6 +795,14 @@ void LLFloaterPreference::onBtnOK()
 		apply();
 		closeFloater(false);
 
+		//Conversation transcript and log path changed so reload conversations based on new location
+		if(mInstantMessageLogPathChanged)
+		{
+			std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+			updateLogLocation(dir_name);
+			mInstantMessageLogPathChanged = false;
+		}
+
 		LLUIColorTable::instance().saveUserSettings();
 		gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
 	}
@@ -1440,8 +1441,7 @@ void LLFloaterPreference::setAllIgnored()
 
 void LLFloaterPreference::onClickLogPath()
 {
-	std::string original_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
-	std::string proposed_name(original_name);	 
+	std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
 	mInstantMessageLogPathChanged = false;
 	
 	LLDirPicker& picker = LLDirPicker::instance();
@@ -1451,10 +1451,12 @@ void LLFloaterPreference::onClickLogPath()
 		return; //Canceled!
 	}
 
+	//Gets the path from the directory picker
+	std::string dir_name = picker.getDirName();
+
 	//Path changed
-	if(original_name != proposed_name)
+	if(proposed_name != dir_name)
 	{
-		std::string dir_name = picker.getDirName();
 		gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
 		mInstantMessageLogPathChanged = true;
 
-- 
cgit v1.2.3


From 1b464fae878550c22c98d9773e33be289447b503 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Thu, 21 Feb 2013 15:06:06 +0200
Subject: CHUI-783 FIXED Load logs from conversation.log file after changing
 preferences.

---
 indra/newview/llconversationlog.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index fc3bc8551c..b777edba77 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -206,6 +206,8 @@ void LLConversationLog::enableLogging(S32 log_mode)
 	mLoggingEnabled = log_mode > 0;
 	if (log_mode > 0)
 	{
+		mConversations.clear();
+		loadFromFile(getFileName());
 		LLIMMgr::instance().addSessionObserver(this);
 		mNewMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
 
-- 
cgit v1.2.3


From f79f9f111b0db67cacfe9bbe453737f3979b3ba9 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Thu, 21 Feb 2013 15:11:32 +0200
Subject: CHUI-774 FIXED Play a sound even if the conversation floater is open
 and conversation with user is the active.

---
 indra/newview/llnotificationofferhandler.cpp | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index a2bd96f35a..2657b84ef3 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -96,8 +96,21 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 
 			LLUUID from_id = notification->getPayload()["from_id"];
 
+			//Will not play a notification sound for inventory and teleport offer based upon chat preference
+			bool playSound = (!notification->isDND()
+							  && ((notification->getName() == "UserGiveItem"
+			                  && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
+			                  || (notification->getName() == "TeleportOffered"
+			                  && gSavedSettings.getBOOL("PlaySoundTeleportOffer"))));
+
+			            if(playSound)
+			            {
+			                notification->playSound();
+			            }
+
 			LLHandlerUtil::spawnIMSession(name, from_id);
 			LLHandlerUtil::addNotifPanelToIM(notification);
+
 		}
 
 		if (!notification->canShowToast())
@@ -119,17 +132,6 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 			if(channel)
 				channel->addToast(p);
 
-            //Will not play a notification sound for inventory and teleport offer based upon chat preference
-            bool playSound = (!notification->isDND()
-                               && ((notification->getName() == "UserGiveItem"
-                                    && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
-                               || (notification->getName() == "TeleportOffered"
-                                    && gSavedSettings.getBOOL("PlaySoundTeleportOffer"))));
-
-            if(playSound)
-            {
-                notification->playSound();
-            }
 		}
 
 		if (notification->canLogToIM())
-- 
cgit v1.2.3


From 86150b4019d1a84b4af73f0ea18c47baff955562 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Thu, 21 Feb 2013 19:15:48 -0800
Subject: CHUI-568 : WIP : Introduced Ctrl-T and Ctrl-H for conversations and
 nearby chat

---
 indra/llui/llfloater.cpp                           | 33 ++++++++++++++++++++--
 indra/llui/llfloater.h                             |  3 ++
 indra/llui/llfloaterreg.cpp                        | 30 ++++++++++++--------
 indra/newview/llfloaterimnearbychat.cpp            | 21 ++++++++++++++
 indra/newview/llfloaterimnearbychat.h              |  2 ++
 indra/newview/skins/default/xui/en/menu_viewer.xml |  8 +++---
 6 files changed, 79 insertions(+), 18 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 734e2cfda7..bf424883b3 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -812,6 +812,22 @@ void LLFloater::closeFloater(bool app_quitting)
 	}
 }
 
+/*virtual*/
+void LLFloater::closeHostedFloater()
+{
+	// When toggling *visibility*, close the host instead of the floater when hosted
+	if (getHost())
+	{
+		llinfos << "Merov debug : closeHostedFloater : host " << llendl;
+		getHost()->closeFloater();
+	}
+	else
+	{
+		llinfos << "Merov debug : closeHostedFloater : floater " << llendl;
+		closeFloater();
+	}
+}
+
 /*virtual*/
 void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
@@ -1609,8 +1625,19 @@ void LLFloater::bringToFront( S32 x, S32 y )
 // virtual
 void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
 {
-	setVisible(TRUE);
-	setFrontmost(take_focus);
+	LLMultiFloater* hostp = getHost();
+	if (hostp)
+	{
+		llinfos << "Merov debug : setVisibleAndFrontmost : hostp->setFrontmost " << llendl;
+		hostp->setVisible(TRUE);
+		hostp->setFrontmost(take_focus);
+	}
+	else
+	{
+		llinfos << "Merov debug : setVisibleAndFrontmost : setFrontmost " << llendl;
+		setVisible(TRUE);
+		setFrontmost(take_focus);
+	}
 }
 
 void LLFloater::setFrontmost(BOOL take_focus)
@@ -1618,12 +1645,14 @@ void LLFloater::setFrontmost(BOOL take_focus)
 	LLMultiFloater* hostp = getHost();
 	if (hostp)
 	{
+		llinfos << "Merov debug : setFrontmost : hostp->showFloater " << llendl;
 		// this will bring the host floater to the front and select
 		// the appropriate panel
 		hostp->showFloater(this);
 	}
 	else
 	{
+		llinfos << "Merov debug : setFrontmost : bringToFront " << llendl;
 		// there are more than one floater view
 		// so we need to query our parent directly
 		((LLFloaterView*)getParent())->bringToFront(this, take_focus);
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 157b9b0113..cb5bf28db3 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -226,6 +226,9 @@ public:
 	// If allowed, close the floater cleanly, releasing focus.
 	virtual void	closeFloater(bool app_quitting = false);
 
+	// Close the floater or its host. Use when hidding or toggling a floater instance.
+	virtual void	closeHostedFloater();
+
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 	
 	// Release keyboard and mouse focus
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 306caf2b91..c0be086671 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -264,11 +264,7 @@ bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
 	LLFloater* instance = findInstance(name, key); 
 	if (instance)
 	{
-		// When toggling *visibility*, close the host instead of the floater when hosted
-		if (instance->getHost())
-			instance->getHost()->closeFloater();
-		else
-			instance->closeFloater();
+		instance->closeHostedFloater();
 		return true;
 	}
 	else
@@ -281,18 +277,17 @@ bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
 // returns true if the instance is visible when completed
 bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
 {
+	llinfos << "Merov debug : toggleInstance, name = " << name << ", key = " << key.asString() << llendl;
 	LLFloater* instance = findInstance(name, key); 
 	if (LLFloater::isShown(instance))
 	{
-		// When toggling *visibility*, close the host instead of the floater when hosted
-		if (instance->getHost())
-			instance->getHost()->closeFloater();
-		else
-			instance->closeFloater();
+		llinfos << "Merov debug : call closeHostedFloater " << llendl;
+		instance->closeHostedFloater();
 		return false;
 	}
 	else
 	{
+		llinfos << "Merov debug : call show instance " << llendl;
 		return showInstance(name, key, TRUE) ? true : false;
 	}
 }
@@ -481,31 +476,42 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
 	//       * Also, if it is not on top, bring it forward when focus is given.
 	// * Else the target floater is open, close it.
 	// 
+	llinfos << "Merov debug : toggleInstanceOrBringToFront, name = " << sdname.asString() << ", key = " << key.asString() << llendl;
 
 	std::string name = sdname.asString();
 	LLFloater* instance = getInstance(name, key); 
+	
 
 	if (!instance)
 	{
 		lldebugs << "Unable to get instance of floater '" << name << "'" << llendl;
+		return;
 	}
-	else if (instance->isMinimized())
+	
+	// If hosted, we need to take that into account
+	//LLFloater* host = instance->getHost();
+	
+	if (instance->isMinimized())
 	{
+		llinfos << "Merov debug : unminimize, make visible and set to front " << llendl;
 		instance->setMinimized(FALSE);
 		instance->setVisibleAndFrontmost();
 	}
 	else if (!instance->isShown())
 	{
+		llinfos << "Merov debug : open, make visible and set to front " << llendl;
 		instance->openFloater(key);
 		instance->setVisibleAndFrontmost();
 	}
 	else if (!instance->isFrontmost())
 	{
+		llinfos << "Merov debug : make visible and set to front " << llendl;
 		instance->setVisibleAndFrontmost();
 	}
 	else
 	{
-		instance->closeFloater();
+		llinfos << "Merov debug : closeHostedFloater " << llendl;
+		instance->closeHostedFloater();
 	}
 }
 
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 430326203f..80051eb7f1 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -135,6 +135,27 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 	return result;
 }
 
+// virtual
+void LLFloaterIMNearbyChat::closeFloater(bool app_quitting)
+{
+	llinfos << "Merov debug : LLFloaterIMNearbyChat::closeFloater! " << llendl;
+	LLFloater::closeFloater(app_quitting);
+}
+
+// virtual
+void LLFloaterIMNearbyChat::closeHostedFloater()
+{
+	if (getHost())
+	{
+		llinfos << "Merov debug : LLFloaterIMNearbyChat::closeHostedFloater : hosted -> do nothing" << llendl;
+	}
+	else
+	{
+		llinfos << "Merov debug : LLFloaterIMNearbyChat::closeHostedFloater : close floater " << llendl;
+		LLFloater::closeFloater();
+	}
+}
+
 // virtual
 void LLFloaterIMNearbyChat::refresh()
 {
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index 14c7d01ecd..2d32bb3fc9 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -54,6 +54,8 @@ public:
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void closeFloater(bool app_quitting = false);
+	/*virtual*/ void closeHostedFloater();
 
 	void loadHistory();
     void reloadMessages(bool clean_messages = false);
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b50deb7d7a..544f06ac0c 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -183,8 +183,7 @@
         </menu_item_call>
          <menu_item_call
          label="Toolbar buttons..."
-         name="Toolbars"
-         shortcut="control|T">
+         name="Toolbars">
             <menu_item_call.on_click
              function="Floater.Toggle"
              parameter="toybox" />
@@ -223,7 +222,8 @@
      tear_off="true">
        <menu_item_check
          label="Conversations..."
-         name="Conversations">
+         name="Conversations"
+         shortcut="control|T">
             <menu_item_check.on_check
              function="Floater.IsOpen"
              parameter="im_container" />
@@ -240,7 +240,7 @@
              function="Floater.Visible"
              parameter="nearby_chat" />
             <menu_item_check.on_click
-             function="Floater.Toggle"
+             function="Floater.ToggleOrBringToFront"
              parameter="nearby_chat" />
         </menu_item_check>
         <menu_item_check
-- 
cgit v1.2.3


From 3f71eabbbbe4ee54c29b0e3598569cc484505258 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 22 Feb 2013 14:02:14 +0200
Subject: CHUI-702 FIXED Calling requestArrange() in refresh() has to fix the
 problem.

---
 indra/newview/llconversationview.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 5ac6353daa..5ff6841646 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -375,7 +375,7 @@ void LLConversationViewSession::refresh()
 			}
 		}
 	}
-	
+	requestArrange();
 	// Do the regular upstream refresh
 	LLFolderViewFolder::refresh();
 }
-- 
cgit v1.2.3


From 5284da1acee1c92f2d465088cee7488d5de2c8b3 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 22 Feb 2013 14:23:10 +0200
Subject: CHUI-781 FIXED Select conversation if user selects participant that
 belongs to this conversation.

---
 indra/newview/llconversationview.cpp | 48 +++++++++++++++++++++++++++---------
 indra/newview/llconversationview.h   |  2 +-
 2 files changed, 37 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 5ff6841646..441de2e1a5 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -241,20 +241,23 @@ void LLConversationViewSession::draw()
 
 BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
 {
-	LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
-    LLUUID session_id = item? item->getUUID() : LLUUID();
-    //Will try to select a child node and then itself (if a child was not selected)
+	//Will try to select a child node and then itself (if a child was not selected)
     BOOL result = LLFolderViewFolder::handleMouseDown(x, y, mask);
 
     //This node (conversation) was selected and a child (participant) was not
-    if(result && getRoot()->getCurSelectedItem() == this)
-	{
-		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-		im_container->flashConversationItemWidget(session_id,false);
-		im_container->selectConversationPair(session_id, false);
-		im_container->collapseMessagesPane(false);
-	}
-
+    if(result && getRoot())
+    {
+    	if(getRoot()->getCurSelectedItem() == this)
+    	{
+    		LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
+    		LLUUID session_id = item? item->getUUID() : LLUUID();
+
+    		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+    		im_container->flashConversationItemWidget(session_id,false);
+    		im_container->selectConversationPair(session_id, false);
+    		im_container->collapseMessagesPane(false);
+    	}
+    }
 	return result;
 }
 
@@ -536,7 +539,7 @@ void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
     LLFolderViewItem::addToFolder(folder);
 	
     // Retrieve the folder (conversation) UUID, which is also the speaker session UUID
-    LLConversationItem* vmi = this->getParentFolder() ? dynamic_cast<LLConversationItem*>(this->getParentFolder()->getViewModelItem()) : NULL;
+    LLConversationItem* vmi = getParentFolder() ? dynamic_cast<LLConversationItem*>(getParentFolder()->getViewModelItem()) : NULL;
     if (vmi)
     {
 		addToSession(vmi->getUUID());
@@ -557,6 +560,27 @@ void LLConversationViewParticipant::onInfoBtnClick()
 	LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID));
 }
 
+BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask);
+
+    if(result && getRoot())
+    {
+    	if(getRoot()->getCurSelectedItem() == this)
+		{
+    		LLConversationItem* vmi = getParentFolder() ? dynamic_cast<LLConversationItem*>(getParentFolder()->getViewModelItem()) : NULL;
+    		LLUUID session_id = vmi? vmi->getUUID() : LLUUID();
+
+    		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+    		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+			im_container->flashConversationItemWidget(session_id,false);
+			im_container->selectFloater(session_floater);
+			im_container->collapseMessagesPane(false);
+		}
+    }
+    return result;
+}
+
 void LLConversationViewParticipant::onMouseEnter(S32 x, S32 y, MASK mask)
 {
     mInfoBtn->setVisible(true);
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index f2fa2fb042..f9b45073f4 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -138,7 +138,7 @@ public:
     void onMouseLeave(S32 x, S32 y, MASK mask);
 
     /*virtual*/ S32 getLabelXPos();
-
+    /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
 	void hideSpeakingIndicator();
 
 protected:
-- 
cgit v1.2.3


From 4b6e1c26f05d89aa130a899803553940069457c0 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Fri, 22 Feb 2013 17:08:33 +0200
Subject: CHUI-633 FIXED User is not able to open chat history by 'View chat
 history' menu item from pop-up menu of People floater

---
 indra/newview/llavataractions.cpp              | 14 +++++++++++++-
 indra/newview/llfloaterconversationpreview.cpp | 17 ++++++++++++++---
 indra/newview/llfloaterconversationpreview.h   |  5 +++++
 indra/newview/lllogchat.cpp                    | 26 ++++++++++++++++++++++++++
 indra/newview/lllogchat.h                      |  1 +
 indra/newview/llpanelpeoplemenus.cpp           |  7 ++++++-
 6 files changed, 65 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index d6e457887b..ce063a9887 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -44,6 +44,7 @@
 #include "llcallingcard.h"		// for LLAvatarTracker
 #include "llconversationlog.h"
 #include "llfloateravatarpicker.h"	// for LLFloaterAvatarPicker
+#include "llfloaterconversationpreview.h"
 #include "llfloatergroupinvite.h"
 #include "llfloatergroups.h"
 #include "llfloaterreg.h"
@@ -926,9 +927,20 @@ void LLAvatarActions::viewChatHistory(const LLUUID& id)
 		if (iter->getParticipantID() == id)
 		{
 			LLFloaterReg::showInstance("preview_conversation", iter->getSessionID(), true);
-			break;
+			return;
 		}
 	}
+
+	if (LLLogChat::isTranscriptExist(id))
+	{
+		LLAvatarName avatar_name;
+		LLSD extended_id(id);
+
+		LLAvatarNameCache::get(id, &avatar_name);
+		extended_id[LL_FCP_COMPLETE_NAME] = avatar_name.getCompleteName();
+		extended_id[LL_FCP_ACCOUNT_NAME] = avatar_name.getAccountName();
+		LLFloaterReg::showInstance("preview_conversation", extended_id, true);
+	}
 }
 
 //== private methods ========================================================================================
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 48e0caa0ce..a3d715530d 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -33,13 +33,19 @@
 #include "llspinctrl.h"
 #include "lltrans.h"
 
+const std::string LL_FCP_COMPLETE_NAME("complete_name");
+const std::string LL_FCP_ACCOUNT_NAME("user_name");
+
 LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
 :	LLFloater(session_id),
 	mChatHistory(NULL),
 	mSessionID(session_id.asUUID()),
 	mCurrentPage(0),
-	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize"))
-{}
+	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")),
+	mAccountName(session_id[LL_FCP_ACCOUNT_NAME]),
+	mCompleteName(session_id[LL_FCP_COMPLETE_NAME])
+{
+}
 
 BOOL LLFloaterConversationPreview::postBuild()
 {
@@ -49,7 +55,12 @@ BOOL LLFloaterConversationPreview::postBuild()
 	std::string name;
 	std::string file;
 
-	if (mSessionID != LLUUID::null && conv)
+	if (mAccountName != "")
+	{
+		name = mCompleteName;
+		file = mAccountName;
+	}
+	else if (mSessionID != LLUUID::null && conv)
 	{
 		name = conv->getConversationName();
 		file = conv->getHistoryFileName();
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index 0341e5d2a0..b17ae84b63 100644
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -29,6 +29,9 @@
 #include "llchathistory.h"
 #include "llfloater.h"
 
+extern const std::string LL_FCP_COMPLETE_NAME;	//"complete_name"
+extern const std::string LL_FCP_ACCOUNT_NAME;		//"user_name"
+
 class LLSpinCtrl;
 
 class LLFloaterConversationPreview : public LLFloater
@@ -54,6 +57,8 @@ private:
 	int				mPageSize;
 
 	std::list<LLSD> mMessages;
+	std::string		mAccountName;
+	std::string		mCompleteName;
 };
 
 #endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 17b72c5023..09f816a4e6 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -28,6 +28,7 @@
 
 #include "llagent.h"
 #include "llagentui.h"
+#include "llavatarnamecache.h"
 #include "lllogchat.h"
 #include "lltrans.h"
 #include "llviewercontrol.h"
@@ -540,6 +541,31 @@ void LLLogChat::deleteTranscripts()
 	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
 }
 
+// static
+bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id)
+{
+	std::vector<std::string> list_of_transcriptions;
+	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
+
+	if (list_of_transcriptions.size() > 0)
+	{
+		LLAvatarName avatar_name;
+		LLAvatarNameCache::get(avatar_id, &avatar_name);
+		std::string avatar_user_name = avatar_name.getAccountName();
+		std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_');
+
+		BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
+		{
+			if (std::string::npos != transcript_file_name.find(avatar_user_name))
+			{
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 //*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
 //which are more strict by its nature (only firstname and secondname)
 //Example, an object's name can be written like "Object <actual_object's_name>"
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 5fbb4ade96..b981d9ce04 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -57,6 +57,7 @@ public:
 	static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
 
 	static void deleteTranscripts();
+	static bool isTranscriptExist(const LLUUID& avatar_id);
 
 private:
 	static std::string cleanFileName(std::string filename);
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 61e9468ce5..47d6b49a50 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -37,6 +37,7 @@
 #include "llagentdata.h"			// for gAgentID
 #include "llavataractions.h"
 #include "llcallingcard.h"			// for LLAvatarTracker
+#include "lllogchat.h"
 #include "llviewermenu.h"			// for gMenuHolder
 
 namespace LLPanelPeopleMenus
@@ -180,7 +181,11 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
 	{
 		return LLAvatarActions::canOfferTeleport(mUUIDs);
 	}
-	else if (item == std::string("can_im") || item == std::string("can_callog") || item == std::string("can_invite") ||
+	else if (item == std::string("can_callog"))
+	{
+		return LLLogChat::isTranscriptExist(mUUIDs.front());
+	}
+	else if (item == std::string("can_im") || item == std::string("can_invite") ||
 	         item == std::string("can_share") || item == std::string("can_pay"))
 	{
 		return true;
-- 
cgit v1.2.3


From 6185c16a0af02c90625dec71119d12dec07bb056 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 22 Feb 2013 20:54:58 +0000
Subject: CHUI-772 FIX User sees no notification of conversation activity not
 visible in long scrolling conversation list Added
 LLFLoaterIMContainer::isConversationItemWidgetvisible() which is now used in
 LLConversationViewSession::startFlashing() to flash chat toolbar button if
 out of view

---
 indra/newview/llconversationview.cpp   | 12 ++++++++++++
 indra/newview/llfloaterimcontainer.cpp | 16 ++++++++++++++++
 indra/newview/llfloaterimcontainer.h   |  1 +
 3 files changed, 29 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 441de2e1a5..850668388f 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -39,6 +39,7 @@
 #include "llfloaterreg.h"
 #include "llgroupiconctrl.h"
 #include "lluictrlfactory.h"
+#include "lltoolbarview.h"
 
 //
 // Implementation of conversations list session widgets
@@ -114,6 +115,17 @@ void LLConversationViewSession::startFlashing()
 	{
 		mFlashStarted = true;
 		mFlashTimer->startFlashing();
+		
+		// get session id
+		LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+		if (vmi)
+		{
+			// flash chat toolbar button if scrolled out of view (because flashing will not be visible)
+			if (!mContainer->isConversationItemWidgetVisible(vmi->getUUID()))
+			{
+				gToolBarView->flashCommand(LLCommandId("chat"), true);
+			}
+		}
 	}
 }
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c8088588da..0260f2b89e 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1853,6 +1853,22 @@ void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id,
 	}
 }
 
+bool LLFloaterIMContainer::isConversationItemWidgetVisible(const LLUUID& session_id)
+{
+    // find the conversation line item using the session_id
+	LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets, session_id));
+
+	if (widget)
+	{
+		// check whether the widget is in the visible portion of the scroll container
+		LLRect widget_rect;
+		widget->localRectToOtherView(widget->getLocalRect(), &widget_rect, mConversationsRoot);
+		return (mConversationsRoot->getVisibleRect().overlaps(widget_rect));
+	}
+
+	return false;
+}
+
 void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
 {
 	// Always unminimize before trying to close.
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 569fa9faab..156f11f14e 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -185,6 +185,7 @@ public:
 	void updateSpeakBtnState();
 	static bool isConversationLoggingAllowed();
 	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
+	bool isConversationItemWidgetVisible(const LLUUID& session_id);
 	boost::signals2::connection mMicroChangedSignal;
 
 private:
-- 
cgit v1.2.3


From 6194302a849431e84c046325d3cd19e92f62aa6f Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 22 Feb 2013 21:42:08 +0000
Subject: CHUI-772 FIX User sees no notification of conversation activity not
 visible in long scrolling conversation list Renamed
 LLFLoaterIMContainer::isConversationItemWidgetvisible() to
 isScrolledOutOfView() with opposite return value

---
 indra/newview/llconversationview.cpp   | 11 +++--------
 indra/newview/llfloaterimcontainer.cpp | 18 ++++++------------
 indra/newview/llfloaterimcontainer.h   |  2 +-
 3 files changed, 10 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 850668388f..73b2c6f88c 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -116,15 +116,10 @@ void LLConversationViewSession::startFlashing()
 		mFlashStarted = true;
 		mFlashTimer->startFlashing();
 		
-		// get session id
-		LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
-		if (vmi)
+		// flash chat toolbar button if scrolled out of sight (because flashing will not be visible)
+		if (mContainer->isScrolledOutOfSight(this))
 		{
-			// flash chat toolbar button if scrolled out of view (because flashing will not be visible)
-			if (!mContainer->isConversationItemWidgetVisible(vmi->getUUID()))
-			{
-				gToolBarView->flashCommand(LLCommandId("chat"), true);
-			}
+			gToolBarView->flashCommand(LLCommandId("chat"), true);
 		}
 	}
 }
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 0260f2b89e..2d12d4ec21 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1853,20 +1853,14 @@ void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id,
 	}
 }
 
-bool LLFloaterIMContainer::isConversationItemWidgetVisible(const LLUUID& session_id)
+bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget)
 {
-    // find the conversation line item using the session_id
-	LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets, session_id));
+	llassert(conversation_item_widget != NULL);
 
-	if (widget)
-	{
-		// check whether the widget is in the visible portion of the scroll container
-		LLRect widget_rect;
-		widget->localRectToOtherView(widget->getLocalRect(), &widget_rect, mConversationsRoot);
-		return (mConversationsRoot->getVisibleRect().overlaps(widget_rect));
-	}
-
-	return false;
+	// check whether the widget is in the visible portion of the scroll container
+	LLRect widget_rect;
+	conversation_item_widget->localRectToOtherView(conversation_item_widget->getLocalRect(), &widget_rect, mConversationsRoot);
+	return !mConversationsRoot->getVisibleRect().overlaps(widget_rect);
 }
 
 void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 156f11f14e..5ba29b8cfb 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -185,7 +185,7 @@ public:
 	void updateSpeakBtnState();
 	static bool isConversationLoggingAllowed();
 	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
-	bool isConversationItemWidgetVisible(const LLUUID& session_id);
+	bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget);
 	boost::signals2::connection mMicroChangedSignal;
 
 private:
-- 
cgit v1.2.3


From 05f4e8a10517b3b341359a210aeb0af06c44d43a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 22 Feb 2013 18:53:40 -0800
Subject: CHUI-778 (Saving preferences updates text in all open message panels
 in conversation floater to show as old messages) Now changing the
 log/transcripts file location actually moves the files to the new location.
 Prior behavior just started a new history at that location. Also a fix was
 made so that if the user changed the log/transcripts path then after pressing
 the Preferences 'OK' button the new location will be saved to the
 corresponding .xml file.

---
 indra/llvfs/lldir.cpp                              |  5 ++
 indra/llvfs/lldir.h                                |  1 +
 indra/newview/llconversationlog.cpp                | 21 ++++++
 indra/newview/llconversationlog.h                  | 13 ++--
 indra/newview/llfloaterpreference.cpp              | 86 +++++++++++++++++++---
 indra/newview/llfloaterpreference.h                |  4 +-
 indra/newview/lllogchat.cpp                        | 60 +++++++++++++++
 indra/newview/lllogchat.h                          |  4 +
 .../newview/skins/default/xui/en/notifications.xml | 11 +++
 9 files changed, 186 insertions(+), 19 deletions(-)

(limited to 'indra')

diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index f7bc19574a..6899e9a44a 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -347,6 +347,11 @@ const std::string &LLDir::getLLPluginDir() const
 	return mLLPluginDir;
 }
 
+const std::string &LLDir::getUserName() const
+{
+	return mUserName;
+}
+
 static std::string ELLPathToString(ELLPath location)
 {
 	typedef std::map<ELLPath, const char*> ELLPathMap;
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 95cab65149..cc10ed5bbd 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -104,6 +104,7 @@ class LLDir
 	const std::string &getUserSkinDir() const;		// User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin
 	const std::string getSkinBaseDir() const;		// folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins
 	const std::string &getLLPluginDir() const;		// Directory containing plugins and plugin shell
+	const std::string &getUserName() const;
 
 	// Expanded filename
 	std::string getExpandedFilename(ELLPath location, const std::string &filename) const;
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index fc3bc8551c..88671a789f 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -376,6 +376,27 @@ void LLConversationLog::cache()
 	}
 }
 
+bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)
+{
+	//Does the file exist in the current path
+	if(LLFile::isfile(originDirectory))
+	{
+		//Does same file exist in the destination path, if so try to remove it
+		if(LLFile::isfile(targetDirectory))
+		{
+			LLFile::remove(targetDirectory);
+		}
+
+		//Move the file from the current path to destination path
+		if(LLFile::rename(originDirectory, targetDirectory) != 0)
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
 std::string LLConversationLog::getFileName()
 {
 	std::string filename = "conversation";
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index fd38556131..58e698de25 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -137,6 +137,7 @@ public:
 	 * public method which is called on viewer exit to save conversation log
 	 */
 	void cache();
+	bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);
 
 	void onClearLog();
 	void onClearLogResponse(const LLSD& notification, const LLSD& response);
@@ -144,6 +145,12 @@ public:
 	bool getIsLoggingEnabled() { return mLoggingEnabled; }
 	bool isLogEmpty() { return mConversations.empty(); }
 
+	/**
+	 * constructs file name in which conversations log will be saved
+	 * file name is conversation.log
+	 */
+	std::string getFileName();
+
 private:
 
 	LLConversationLog();
@@ -164,12 +171,6 @@ private:
 
 	void notifyParticularConversationObservers(const LLUUID& session_id, U32 mask);
 
-	/**
-	 * constructs file name in which conversations log will be saved
-	 * file name is conversation.log
-	 */
-	std::string getFileName();
-
 	bool saveToFile(const std::string& filename);
 	bool loadFromFile(const std::string& filename);
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index e5444583d6..b9239b544f 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -796,15 +796,25 @@ void LLFloaterPreference::onBtnOK()
 		closeFloater(false);
 
 		//Conversation transcript and log path changed so reload conversations based on new location
-		if(mInstantMessageLogPathChanged)
+		if(mPriorInstantMessageLogPath.length())
 		{
-			std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
-			updateLogLocation(dir_name);
-			mInstantMessageLogPathChanged = false;
+			//Couldn't move files so restore the old path and show a notification
+			if(!moveTranscriptsAndLog())
+			{
+				gSavedPerAccountSettings.setString("InstantMessageLogPath", mPriorInstantMessageLogPath);
+				LLNotificationsUtil::add("PreferenceChatPathChanged");
+			}
+			mPriorInstantMessageLogPath.clear();
 		}
 
 		LLUIColorTable::instance().saveUserSettings();
 		gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
+		
+		//Only save once logged in and loaded per account settings
+		if(mGotPersonalInfo)
+		{
+			gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
+		}
 	}
 	else
 	{
@@ -1442,7 +1452,7 @@ void LLFloaterPreference::setAllIgnored()
 void LLFloaterPreference::onClickLogPath()
 {
 	std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
-	mInstantMessageLogPathChanged = false;
+	mPriorInstantMessageLogPath.clear();
 	
 	LLDirPicker& picker = LLDirPicker::instance();
 	//Launches a directory picker and waits for feedback
@@ -1458,21 +1468,75 @@ void LLFloaterPreference::onClickLogPath()
 	if(proposed_name != dir_name)
 	{
 		gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
-		mInstantMessageLogPathChanged = true;
+		mPriorInstantMessageLogPath = proposed_name;
 
 		// enable/disable 'Delete transcripts button
 		updateDeleteTranscriptsButton();
 	}
 }
 
-void LLFloaterPreference::updateLogLocation(const std::string& dir_name)
+bool LLFloaterPreference::moveTranscriptsAndLog()
 {
-	gDirUtilp->setChatLogsDir(dir_name);
+	std::string instantMessageLogPath(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+	std::string chatLogPath = gDirUtilp->add(instantMessageLogPath, gDirUtilp->getUserName());
+
+	bool madeDirectory = false;
+
+	//Does the directory really exist, if not then make it
+	if(!LLFile::isdir(chatLogPath))
+	{
+		//mkdir success is defined as zero
+		if(LLFile::mkdir(chatLogPath) != 0)
+		{
+			return false;
+		}
+		madeDirectory = true;
+	}
+	
+	std::string originalConversationLogDir = LLConversationLog::instance().getFileName();
+	std::string targetConversationLogDir = gDirUtilp->add(chatLogPath, "conversation.log");
+	//Try to move the conversation log
+	if(!LLConversationLog::instance().moveLog(originalConversationLogDir, targetConversationLogDir))
+	{
+		//Couldn't move the log and created a new directory so remove the new directory
+		if(madeDirectory)
+		{
+			LLFile::rmdir(chatLogPath);
+		}
+		return false;
+	}
+
+	//Attempt to move transcripts
+	std::vector<std::string> listOfTranscripts;
+	std::vector<std::string> listOfFilesMoved;
+
+	LLLogChat::getListOfTranscriptFiles(listOfTranscripts);
+
+	if(!LLLogChat::moveTranscripts(gDirUtilp->getChatLogsDir(), 
+									instantMessageLogPath, 
+									listOfTranscripts,
+									listOfFilesMoved))
+	{
+		//Couldn't move all the transcripts so restore those that moved back to their old location
+		LLLogChat::moveTranscripts(instantMessageLogPath, 
+			gDirUtilp->getChatLogsDir(), 
+			listOfFilesMoved);
+
+		//Move the conversation log back
+		LLConversationLog::instance().moveLog(targetConversationLogDir, originalConversationLogDir);
+
+		if(madeDirectory)
+		{
+			LLFile::rmdir(chatLogPath);
+		}
+
+		return false;
+	}
+
+	gDirUtilp->setChatLogsDir(instantMessageLogPath);
 	gDirUtilp->updatePerAccountChatLogsDir();
-	LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
 
-	// refresh IM floaters with new logs from files from new selected directory
-	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+	return true;
 }
 
 void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index c72346c3b6..22e80a21cb 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -143,7 +143,7 @@ public:
 	void resetAllIgnored();
 	void setAllIgnored();
 	void onClickLogPath();
-	void updateLogLocation(const std::string& dir_name);
+	bool moveTranscriptsAndLog();
 	void enableHistory();
 	void setPersonalInfo(const std::string& visibility, bool im_via_email);
 	void refreshEnabledState();
@@ -186,8 +186,8 @@ private:
 	bool mGotPersonalInfo;
 	bool mOriginalIMViaEmail;
 	bool mLanguageChanged;
-	bool mInstantMessageLogPathChanged;
 	bool mAvatarDataInitialized;
+	std::string mPriorInstantMessageLogPath;
 	
 	bool mOriginalHideOnlineStatus;
 	std::string mDirectoryVisibility;
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 17b72c5023..b60e2aa44e 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -500,6 +500,66 @@ boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_s
 	return sSaveHistorySignal->connect(cb);
 }
 
+//static
+bool LLLogChat::moveTranscripts(const std::string originDirectory, 
+								const std::string targetDirectory, 
+								std::vector<std::string>& listOfFilesToMove,
+								std::vector<std::string>& listOfFilesMoved)
+{
+	std::string newFullPath;
+	bool movedAllTranscripts = true;
+
+	BOOST_FOREACH(const std::string& fullpath, listOfFilesToMove)
+	{
+		newFullPath = targetDirectory + fullpath.substr(originDirectory.length(), std::string::npos);
+
+		S32 retry_count = 0;
+		while (retry_count < 5)
+		{
+			//success is zero
+			if (LLFile::rename(fullpath, newFullPath) != 0)
+			{
+				retry_count++;
+				S32 result = errno;
+				LL_WARNS("LLLogChat::moveTranscripts") << "Problem renaming " << fullpath << " - errorcode: "
+					<< result << " attempt " << retry_count << LL_ENDL;
+
+				if(retry_count >= 5)
+				{
+					LL_WARNS("LLLogChat::moveTranscripts") << "Failed to rename " << fullpath << LL_ENDL;
+					return false;
+				}
+
+				//If the file already exists in the new location, remove it then try again
+				if(LLFile::isfile(newFullPath))
+				{
+					LLFile::remove(newFullPath);
+					LL_WARNS("LLLogChat::moveTranscripts") << "File already exists " << fullpath << LL_ENDL;
+				}
+
+				ms_sleep(100);
+			}
+			else
+			{
+				listOfFilesMoved.push_back(newFullPath);
+
+				if (retry_count)
+				{
+					LL_WARNS("LLLogChat::moveTranscripts") << "Successfully renamed " << fullpath << LL_ENDL;
+				}
+				break;
+			}			
+		}
+	}
+
+	if(listOfFilesMoved.size() != listOfFilesToMove.size())
+	{
+		movedAllTranscripts = false;
+	}		
+
+	return movedAllTranscripts;
+}
+
 //static
 void LLLogChat::deleteTranscripts()
 {
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 5fbb4ade96..b9aede0b29 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -56,6 +56,10 @@ public:
 	typedef boost::signals2::signal<void ()> save_history_signal_t;
 	static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
 
+	static bool moveTranscripts(const std::string currentDirectory, 
+									const std::string newDirectory, 
+									std::vector<std::string>& listOfFilesToMove,
+									std::vector<std::string>& listOfFilesMoved = std::vector<std::string>());
 	static void deleteTranscripts();
 
 private:
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 3ae9b206a4..234c6d7c0f 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -10028,4 +10028,15 @@ Cannot create large prims that intersect other players.  Please re-try when othe
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alert.tga"
+   name="PreferenceChatPathChanged"
+   type="alert">
+   Unable to move files. Restored previous path.
+    <usetemplate
+     ignoretext="Unable to move files. Restored previous path."
+     name="okignore"
+     yestext="OK"/>
+  </notification>
+  
 </notifications>
-- 
cgit v1.2.3


From 7f51bd7897a3ced0edc74a32b9148febd7866721 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Sat, 23 Feb 2013 11:22:09 -0800
Subject: CHUI-568 : Fixed! Implemented Ctrl-H for Nearby Chat, taking into
 account the existence of other conversations and docked/torn off state

---
 indra/llui/llfloater.cpp                |  6 ---
 indra/llui/llfloaterreg.cpp             | 65 +++++++++++++++++++--------------
 indra/newview/llfloaterimcontainer.cpp  | 24 ++++++++++++
 indra/newview/llfloaterimcontainer.h    |  2 +
 indra/newview/llfloaterimnearbychat.cpp | 20 +++++-----
 indra/newview/llfloaterimnearbychat.h   |  1 -
 6 files changed, 72 insertions(+), 46 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index bf424883b3..27dd7f5b32 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -818,12 +818,10 @@ void LLFloater::closeHostedFloater()
 	// When toggling *visibility*, close the host instead of the floater when hosted
 	if (getHost())
 	{
-		llinfos << "Merov debug : closeHostedFloater : host " << llendl;
 		getHost()->closeFloater();
 	}
 	else
 	{
-		llinfos << "Merov debug : closeHostedFloater : floater " << llendl;
 		closeFloater();
 	}
 }
@@ -1628,13 +1626,11 @@ void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
 	LLMultiFloater* hostp = getHost();
 	if (hostp)
 	{
-		llinfos << "Merov debug : setVisibleAndFrontmost : hostp->setFrontmost " << llendl;
 		hostp->setVisible(TRUE);
 		hostp->setFrontmost(take_focus);
 	}
 	else
 	{
-		llinfos << "Merov debug : setVisibleAndFrontmost : setFrontmost " << llendl;
 		setVisible(TRUE);
 		setFrontmost(take_focus);
 	}
@@ -1645,14 +1641,12 @@ void LLFloater::setFrontmost(BOOL take_focus)
 	LLMultiFloater* hostp = getHost();
 	if (hostp)
 	{
-		llinfos << "Merov debug : setFrontmost : hostp->showFloater " << llendl;
 		// this will bring the host floater to the front and select
 		// the appropriate panel
 		hostp->showFloater(this);
 	}
 	else
 	{
-		llinfos << "Merov debug : setFrontmost : bringToFront " << llendl;
 		// there are more than one floater view
 		// so we need to query our parent directly
 		((LLFloaterView*)getParent())->bringToFront(this, take_focus);
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index c0be086671..c20d863612 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -265,29 +265,22 @@ bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
 	if (instance)
 	{
 		instance->closeHostedFloater();
-		return true;
-	}
-	else
-	{
-		return false;
 	}
+	return (instance != NULL);
 }
 
 //static
 // returns true if the instance is visible when completed
 bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
 {
-	llinfos << "Merov debug : toggleInstance, name = " << name << ", key = " << key.asString() << llendl;
 	LLFloater* instance = findInstance(name, key); 
 	if (LLFloater::isShown(instance))
 	{
-		llinfos << "Merov debug : call closeHostedFloater " << llendl;
 		instance->closeHostedFloater();
 		return false;
 	}
 	else
 	{
-		llinfos << "Merov debug : call show instance " << llendl;
 		return showInstance(name, key, TRUE) ? true : false;
 	}
 }
@@ -476,8 +469,6 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
 	//       * Also, if it is not on top, bring it forward when focus is given.
 	// * Else the target floater is open, close it.
 	// 
-	llinfos << "Merov debug : toggleInstanceOrBringToFront, name = " << sdname.asString() << ", key = " << key.asString() << llendl;
-
 	std::string name = sdname.asString();
 	LLFloater* instance = getInstance(name, key); 
 	
@@ -489,29 +480,47 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
 	}
 	
 	// If hosted, we need to take that into account
-	//LLFloater* host = instance->getHost();
+	LLFloater* host = instance->getHost();
 	
-	if (instance->isMinimized())
-	{
-		llinfos << "Merov debug : unminimize, make visible and set to front " << llendl;
-		instance->setMinimized(FALSE);
-		instance->setVisibleAndFrontmost();
-	}
-	else if (!instance->isShown())
-	{
-		llinfos << "Merov debug : open, make visible and set to front " << llendl;
-		instance->openFloater(key);
-		instance->setVisibleAndFrontmost();
-	}
-	else if (!instance->isFrontmost())
+	if (host)
 	{
-		llinfos << "Merov debug : make visible and set to front " << llendl;
-		instance->setVisibleAndFrontmost();
+		if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
+		{
+			host->setMinimized(FALSE);
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost();
+		}
+		else if (!instance->getVisible())
+		{
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost();
+			instance->setFocus(TRUE);
+		}
+		else
+		{
+			instance->closeHostedFloater();
+		}
 	}
 	else
 	{
-		llinfos << "Merov debug : closeHostedFloater " << llendl;
-		instance->closeHostedFloater();
+		if (instance->isMinimized())
+		{
+			instance->setMinimized(FALSE);
+			instance->setVisibleAndFrontmost();
+		}
+		else if (!instance->isShown())
+		{
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost();
+		}
+		else if (!instance->isFrontmost())
+		{
+			instance->setVisibleAndFrontmost();
+		}
+		else
+		{
+			instance->closeHostedFloater();
+		}
 	}
 }
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c8088588da..73fcfa244e 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1337,6 +1337,30 @@ void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
     selectConversationPair(session_id, true);
 }
 
+// Select the conversation *after* (or before if none after) the passed uuid conversation
+// Used to change the selection on key hits
+void LLFloaterIMContainer::selectNextConversation(const LLUUID& uuid)
+{
+	LLFolderViewItem* new_selection = NULL;
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+	if (widget)
+	{
+		new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
+		if (!new_selection)
+		{
+			new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
+		}
+	}
+	if (new_selection)
+	{
+		LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+		if (vmi)
+		{
+			selectConversationPair(vmi->getUUID(), true);
+		}
+	}
+}
+
 // Synchronous select the conversation item and the conversation floater
 BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
 {
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 569fa9faab..33d63a391c 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -69,6 +69,7 @@ public:
 	void returnFloaterToHost();
     void showConversation(const LLUUID& session_id);
     void selectConversation(const LLUUID& session_id);
+	void selectNextConversation(const LLUUID& session_id);
     BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
     void clearAllFlashStates();
 
@@ -186,6 +187,7 @@ public:
 	static bool isConversationLoggingAllowed();
 	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
 	boost::signals2::connection mMicroChangedSignal;
+	S32 getConversationListItemSize() { return mConversationsWidgets.size(); }
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 80051eb7f1..a3b81e037a 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -135,24 +135,22 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 	return result;
 }
 
-// virtual
-void LLFloaterIMNearbyChat::closeFloater(bool app_quitting)
-{
-	llinfos << "Merov debug : LLFloaterIMNearbyChat::closeFloater! " << llendl;
-	LLFloater::closeFloater(app_quitting);
-}
-
 // virtual
 void LLFloaterIMNearbyChat::closeHostedFloater()
 {
-	if (getHost())
+	// Should check how many conversations are ongoing. Close all if 1 only (the Nearby Chat), select next one otherwise
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	if (floater_container->getConversationListItemSize() == 1)
 	{
-		llinfos << "Merov debug : LLFloaterIMNearbyChat::closeHostedFloater : hosted -> do nothing" << llendl;
+		floater_container->closeFloater();
 	}
 	else
 	{
-		llinfos << "Merov debug : LLFloaterIMNearbyChat::closeHostedFloater : close floater " << llendl;
-		LLFloater::closeFloater();
+		if (!getHost())
+		{
+			setVisible(FALSE);
+		}
+		floater_container->selectNextConversation(LLUUID());
 	}
 }
 
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index 2d32bb3fc9..2992c12436 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -54,7 +54,6 @@ public:
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setVisible(BOOL visible);
-	/*virtual*/ void closeFloater(bool app_quitting = false);
 	/*virtual*/ void closeHostedFloater();
 
 	void loadHistory();
-- 
cgit v1.2.3


From c6929e42486dd6aa212dc523be4f3b65f431b016 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 25 Feb 2013 04:20:08 -0800
Subject: CHUI-788 (Saving preferences updates text in all open message panels
 in conversation floater to show as old messages) Fixed build error for
 mac/linux

---
 indra/newview/lllogchat.cpp | 9 +++++++++
 indra/newview/lllogchat.h   | 6 +++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index b60e2aa44e..95b0e6b9d6 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -560,6 +560,15 @@ bool LLLogChat::moveTranscripts(const std::string originDirectory,
 	return movedAllTranscripts;
 }
 
+//static
+bool LLLogChat::moveTranscripts(const std::string currentDirectory, 
+	const std::string newDirectory, 
+	std::vector<std::string>& listOfFilesToMove)
+{
+	std::vector<std::string> listOfFilesMoved;
+	return moveTranscripts(currentDirectory, newDirectory, listOfFilesToMove, listOfFilesMoved);
+}
+
 //static
 void LLLogChat::deleteTranscripts()
 {
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index b9aede0b29..244f1c8790 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -59,7 +59,11 @@ public:
 	static bool moveTranscripts(const std::string currentDirectory, 
 									const std::string newDirectory, 
 									std::vector<std::string>& listOfFilesToMove,
-									std::vector<std::string>& listOfFilesMoved = std::vector<std::string>());
+									std::vector<std::string>& listOfFilesMoved);
+	static bool moveTranscripts(const std::string currentDirectory, 
+		const std::string newDirectory, 
+		std::vector<std::string>& listOfFilesToMove);
+
 	static void deleteTranscripts();
 
 private:
-- 
cgit v1.2.3


From fbf7217b49101faad3a4e910d8c88150c39e73d6 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 25 Feb 2013 15:00:48 +0200
Subject: CHUI-790 FIXED Just disable "+" if selected participant is your own
 avatar

---
 indra/newview/llpanelpeople.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 6667706333..c5283404f1 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -812,19 +812,20 @@ void LLPanelPeople::updateButtons()
 	else
 	{
 		bool is_friend = true;
-
+		bool is_self = false;
 		// Check whether selected avatar is our friend.
 		if (item_selected)
 		{
 			selected_id = selected_uuids.front();
 			is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL;
+			is_self = gAgent.getID() == selected_id;
 		}
 
 		LLPanel* cur_panel = mTabContainer->getCurrentPanel();
 		if (cur_panel)
 		{
 			if (cur_panel->hasChild("add_friend_btn", TRUE))
-				cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend);
+				cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend && !is_self);
 
 			if (friends_tab_active)
 			{
-- 
cgit v1.2.3


From c70a951abd0993c85aa96a930a54ff89c93cd03a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 25 Feb 2013 11:41:22 -0800
Subject: CHUI-778: Pushing a quick fix that only pertains to CHUI-778 so we
 can close out this issue.

---
 indra/newview/llfloaterpreference.cpp | 32 +++++++++++++++++++++++---------
 indra/newview/llfloaterpreference.h   |  1 +
 2 files changed, 24 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3d8d0e15ec..688d453789 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -646,9 +646,6 @@ void LLFloaterPreference::cancel()
 		LLFloaterPathfindingConsole* pPathfindingConsole = pathfindingConsoleHandle.get();
 		pPathfindingConsole->onRegionBoundaryCross();
 	}
-
-	std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
-	updateLogLocation(dir_name);
 }
 
 void LLFloaterPreference::onOpen(const LLSD& key)
@@ -798,6 +795,14 @@ void LLFloaterPreference::onBtnOK()
 		apply();
 		closeFloater(false);
 
+		//Conversation transcript and log path changed so reload conversations based on new location
+		if(mPriorInstantMessageLogPath.length())
+		{
+			std::string dir_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+			updateLogLocation(dir_name);
+			mPriorInstantMessageLogPath.clear();
+		}
+
 		LLUIColorTable::instance().saveUserSettings();
 		gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
 	}
@@ -1436,19 +1441,28 @@ void LLFloaterPreference::setAllIgnored()
 
 void LLFloaterPreference::onClickLogPath()
 {
-	std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));	 
-	
+	std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+	mPriorInstantMessageLogPath.clear();
+
 	LLDirPicker& picker = LLDirPicker::instance();
+	//Launches a directory picker and waits for feedback
 	if (!picker.getDir(&proposed_name ) )
 	{
 		return; //Canceled!
 	}
 
+	//Gets the path from the directory picker
 	std::string dir_name = picker.getDirName();
-	gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
-	
-	// enable/disable 'Delete transcripts button
-	updateDeleteTranscriptsButton();
+
+	//Path changed
+	if(proposed_name != dir_name)
+	{
+		gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+		mPriorInstantMessageLogPath = proposed_name;
+
+		// enable/disable 'Delete transcripts button
+		updateDeleteTranscriptsButton();
+	}
 }
 
 void LLFloaterPreference::updateLogLocation(const std::string& dir_name)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index dbd87f74a1..31c1e2d9e5 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -187,6 +187,7 @@ private:
 	bool mOriginalIMViaEmail;
 	bool mLanguageChanged;
 	bool mAvatarDataInitialized;
+	std::string mPriorInstantMessageLogPath;
 	
 	bool mOriginalHideOnlineStatus;
 	std::string mDirectoryVisibility;
-- 
cgit v1.2.3


From 57935506c29e4dfde82626a91a853d87a46aead3 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 25 Feb 2013 13:41:37 -0800
Subject: merge

---
 indra/newview/llconversationlog.cpp | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 4953bcbd02..03d1647c5e 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -380,13 +380,32 @@ void LLConversationLog::cache()
 
 bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)
 {
+
+	std::string backupFileName;
+	UINT backupFileCount = 0;
+
 	//Does the file exist in the current path
 	if(LLFile::isfile(originDirectory))
 	{
-		//Does same file exist in the destination path, if so try to remove it
+		
+		//File already exists so make a backup file
 		if(LLFile::isfile(targetDirectory))
 		{
-			LLFile::remove(targetDirectory);
+			backupFileName = targetDirectory + ".backup";
+
+			//If needed store backup file as .backup1 etc.
+			while(LLFile::isfile(backupFileName))
+			{
+				backupFileName = targetDirectory + ".backup";
+
+				if(backupFileCount)
+				{
+					backupFileName += backupFileCount;
+				}
+			}
+
+			//Rename the file to its backup name so it is not overwritten
+			LLFile::rename(targetDirectory, backupFileName);
 		}
 
 		//Move the file from the current path to destination path
-- 
cgit v1.2.3


From 9ebe7db402af546211b65faf43d1635f3b92937e Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 25 Feb 2013 17:29:15 -0500
Subject: increment minor version: 3.5.0

---
 indra/llcommon/llversionviewer.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 6a5ff314e4..1554e9e665 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -28,8 +28,8 @@
 #define LL_LLVERSIONVIEWER_H
 
 const S32 LL_VERSION_MAJOR = 3;
-const S32 LL_VERSION_MINOR = 4;
-const S32 LL_VERSION_PATCH = 6;
+const S32 LL_VERSION_MINOR = 5;
+const S32 LL_VERSION_PATCH = 0;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";
-- 
cgit v1.2.3


From f7100331ebc7913d7117501ccac86f93f4ffb0e3 Mon Sep 17 00:00:00 2001
From: Oz Linden <oz@lindenlab.com>
Date: Mon, 25 Feb 2013 17:41:36 -0500
Subject: increment version to 3.5.1

---
 indra/llcommon/llversionviewer.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 1554e9e665..0b0c74b3d3 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -29,7 +29,7 @@
 
 const S32 LL_VERSION_MAJOR = 3;
 const S32 LL_VERSION_MINOR = 5;
-const S32 LL_VERSION_PATCH = 0;
+const S32 LL_VERSION_PATCH = 1;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";
-- 
cgit v1.2.3


From 084ea74d43471eec1ae8781c4946fcf2a3a76a78 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 25 Feb 2013 16:48:09 -0800
Subject: CHUI-778: Now when conversation log and trascript files are moved
 they will not overwrite prior files with the same name. Instead the prior
 files will be stored as *.backup.

---
 indra/newview/llconversationlog.cpp | 21 +++++++++------------
 indra/newview/lllogchat.cpp         | 24 +++++++++++++++---------
 2 files changed, 24 insertions(+), 21 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 03d1647c5e..4be169e267 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -31,6 +31,8 @@
 #include "llnotificationsutil.h"
 #include "lltrans.h"
 
+#include "boost/lexical_cast.hpp"
+
 const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec
 
 struct ConversationParams
@@ -382,13 +384,12 @@ bool LLConversationLog::moveLog(const std::string &originDirectory, const std::s
 {
 
 	std::string backupFileName;
-	UINT backupFileCount = 0;
+	unsigned backupFileCount = 0;
 
-	//Does the file exist in the current path
-	if(LLFile::isfile(originDirectory))
+	//Does the file exist in the current path, if it does lets move it
+	if(LLFile::isfile(originDirectory)) 
 	{
-		
-		//File already exists so make a backup file
+		//The target directory contains that file already, so lets store it
 		if(LLFile::isfile(targetDirectory))
 		{
 			backupFileName = targetDirectory + ".backup";
@@ -396,19 +397,15 @@ bool LLConversationLog::moveLog(const std::string &originDirectory, const std::s
 			//If needed store backup file as .backup1 etc.
 			while(LLFile::isfile(backupFileName))
 			{
-				backupFileName = targetDirectory + ".backup";
-
-				if(backupFileCount)
-				{
-					backupFileName += backupFileCount;
-				}
+				++backupFileCount;
+				backupFileName = targetDirectory + ".backup" + boost::lexical_cast<std::string>(backupFileCount);
 			}
 
 			//Rename the file to its backup name so it is not overwritten
 			LLFile::rename(targetDirectory, backupFileName);
 		}
 
-		//Move the file from the current path to destination path
+		//Move the file from the current path to target path
 		if(LLFile::rename(originDirectory, targetDirectory) != 0)
 		{
 			return false;
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index d9d28c6d70..6562cfe1bb 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -509,9 +509,12 @@ bool LLLogChat::moveTranscripts(const std::string originDirectory,
 {
 	std::string newFullPath;
 	bool movedAllTranscripts = true;
+	std::string backupFileName;
+	unsigned backupFileCount;
 
 	BOOST_FOREACH(const std::string& fullpath, listOfFilesToMove)
 	{
+		backupFileCount = 0;
 		newFullPath = targetDirectory + fullpath.substr(originDirectory.length(), std::string::npos);
 
 		S32 retry_count = 0;
@@ -525,17 +528,20 @@ bool LLLogChat::moveTranscripts(const std::string originDirectory,
 				LL_WARNS("LLLogChat::moveTranscripts") << "Problem renaming " << fullpath << " - errorcode: "
 					<< result << " attempt " << retry_count << LL_ENDL;
 
-				if(retry_count >= 5)
-				{
-					LL_WARNS("LLLogChat::moveTranscripts") << "Failed to rename " << fullpath << LL_ENDL;
-					return false;
-				}
-
-				//If the file already exists in the new location, remove it then try again
+				//The target directory contains that file already, so lets store it
 				if(LLFile::isfile(newFullPath))
 				{
-					LLFile::remove(newFullPath);
-					LL_WARNS("LLLogChat::moveTranscripts") << "File already exists " << fullpath << LL_ENDL;
+					backupFileName = newFullPath + ".backup";
+
+					//If needed store backup file as .backup1 etc.
+					while(LLFile::isfile(backupFileName))
+					{
+						++backupFileCount;
+						backupFileName = newFullPath + ".backup" + boost::lexical_cast<std::string>(backupFileCount);
+					}
+
+					//Rename the file to its backup name so it is not overwritten
+					LLFile::rename(newFullPath, backupFileName);
 				}
 
 				ms_sleep(100);
-- 
cgit v1.2.3


From 31e5465158db171a4ac6d3aa48d44e8a62c012f9 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 27 Feb 2013 01:35:27 +0200
Subject: CHUI-788 FIXED Mute icon not shown in participant list in
 conversation floater

---
 indra/newview/llconversationmodel.cpp | 29 +++++++++++++++++++++++++----
 indra/newview/llconversationmodel.h   |  6 +++---
 indra/newview/llconversationview.cpp  | 13 -------------
 indra/newview/llconversationview.h    |  1 -
 indra/newview/lloutputmonitorctrl.cpp |  6 +++---
 indra/newview/lloutputmonitorctrl.h   |  3 ---
 6 files changed, 31 insertions(+), 27 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 0977056b2a..009fce0a92 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -322,7 +322,7 @@ void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_
 	LLConversationItemParticipant* participant = findParticipant(participant_id);
 	if (participant)
 	{
-		participant->setIsMuted(is_muted);
+		participant->muteVoice(is_muted);
 	}
 }
 
@@ -462,7 +462,6 @@ void LLConversationItemSession::onAvatarNameCache(const LLAvatarName& av_name)
 
 LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(display_name,uuid,root_view_model),
-	mIsMuted(false),
 	mIsModerator(false),
 	mDisplayModeratorLabel(false),
 	mDistToAgent(-1.0)
@@ -473,7 +472,6 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display
 
 LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
 	LLConversationItem(uuid,root_view_model),
-	mIsMuted(false),
 	mIsModerator(false),
 	mDisplayModeratorLabel(false),
 	mDistToAgent(-1.0)
@@ -549,7 +547,7 @@ LLConversationItemSession* LLConversationItemParticipant::getParentSession()
 
 void LLConversationItemParticipant::dumpDebugData()
 {
-	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << mIsMuted << ", moderator = " << mIsModerator << llendl;
+	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << isVoiceMuted() << ", moderator = " << mIsModerator << llendl;
 }
 
 void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole)
@@ -561,6 +559,29 @@ void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole)
 	}
 }
 
+bool LLConversationItemParticipant::isVoiceMuted()
+{
+	return LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat);
+}
+
+void LLConversationItemParticipant::muteVoice(bool mute_voice)
+{
+	std::string name;
+	gCacheName->getFullName(mUUID, name);
+	LLMuteList * mute_listp = LLMuteList::getInstance();
+	bool voice_already_muted = mute_listp->isMuted(mUUID, name);
+
+	LLMute mute(mUUID, name, LLMute::AGENT);
+	if (voice_already_muted && !mute_voice)
+	{
+		mute_listp->remove(mute);
+	}
+	else if (!voice_already_muted && mute_voice)
+	{
+		mute_listp->add(mute);
+	}
+}
+
 //
 // LLConversationSort
 // 
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index c907d1d6d2..8766585049 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -189,9 +189,9 @@ public:
 	
 	virtual const std::string& getDisplayName() const { return mDisplayName; }
 
-	bool isMuted() { return mIsMuted; }
-	bool isModerator() {return mIsModerator; }
-	void setIsMuted(bool is_muted) { mIsMuted = is_muted; mNeedsRefresh = true; }
+	bool isVoiceMuted();
+	bool isModerator() const { return mIsModerator; }
+	void muteVoice(bool mute_voice);
 	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
 	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; }
 	void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; }
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 73b2c6f88c..882ef64715 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -527,19 +527,6 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
     return arranged;
 }
 
-void LLConversationViewParticipant::refresh()
-{
-	// Refresh the participant view from its model data
-	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
-	participant_model->resetRefresh();
-	
-	// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
-	mSpeakingIndicator->setIsMuted(participant_model->isMuted());
-	
-	// Do the regular upstream refresh
-	LLFolderViewItem::refresh();
-}
-
 void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
 {
     // Add the item to the folder (conversation)
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index f9b45073f4..76d3d079ea 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -130,7 +130,6 @@ public:
     virtual ~LLConversationViewParticipant( void );
 
     bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
-    virtual void refresh();
     void addToFolder(LLFolderViewFolder* folder);
 	void addToSession(const LLUUID& session_id);
 
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index f6e3c0cac0..6c26073d5b 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -284,12 +284,12 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
 	{
 		if (speaker_id == gAgentID)
 		{
-			setIsMuted(false);
+			mIsMuted = false;
 		}
 		else
 		{
 			// check only blocking on voice. EXT-3542
-			setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
+			mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
 			LLMuteList::getInstance()->addObserver(this);
 		}
 	}
@@ -298,7 +298,7 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
 void LLOutputMonitorCtrl::onChange()
 {
 	// check only blocking on voice. EXT-3542
-	setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
+	mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
 }
 
 // virtual
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index af2fd45823..a346909027 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -73,9 +73,6 @@ public:
 	void			setPower(F32 val);
 	F32				getPower(F32 val) const { return mPower; }
 	
-	bool			getIsMuted() const { return mIsMuted; }
-	void			setIsMuted(bool val) { mIsMuted = val; }
-
 	// For the current user, need to know the PTT state to show
 	// correct button image.
 	void			setIsAgentControl(bool val) { mIsAgentControl = val; }
-- 
cgit v1.2.3


From 2439956242670cfc52e6d27f0b37bb3b6f0ab6e0 Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Thu, 28 Feb 2013 15:33:33 +0200
Subject: CHUI-789 (Letter m appears in Conversations while exit from outlook
 view using 'M' keyboard key)

---
 indra/newview/llfloaterimcontainer.cpp | 6 +++---
 indra/newview/llfloaterimcontainer.h   | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c5edd11c12..f9f0173ec7 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -605,7 +605,7 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
             setSelectedSession(LLUUID(NULL));
 		}
 		openNearbyChat();
-        selectConversationPair(getSelectedSession(), false);
+        selectConversationPair(getSelectedSession(), false, false);
 	}
 
 	nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
@@ -1362,7 +1362,7 @@ void LLFloaterIMContainer::selectNextConversation(const LLUUID& uuid)
 }
 
 // Synchronous select the conversation item and the conversation floater
-BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
+BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater/*=true*/)
 {
     BOOL handled = TRUE;
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
@@ -1409,7 +1409,7 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 		if (!session_floater->hasFocus())
 		{
 			BOOL is_minimized = session_floater->isMinimized();
-			session_floater->setFocus(TRUE);
+			session_floater->setFocus(focus_floater);
 			session_floater->setMinimized(is_minimized);
 		}
 	}
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 419239f90b..f1415cd2e6 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -70,7 +70,7 @@ public:
     void showConversation(const LLUUID& session_id);
     void selectConversation(const LLUUID& session_id);
 	void selectNextConversation(const LLUUID& session_id);
-    BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
+    BOOL selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater = true);
     void clearAllFlashStates();
 
 	/*virtual*/ void tabClose();
-- 
cgit v1.2.3


From 9530b9d2b717d338af79108c60c2aa67e33ba6e5 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 1 Mar 2013 14:24:47 +0200
Subject: CHUI-694 FIXED Handle ALT + Up/Down and ALT + Right/Left to switch
 conversations in the list. Handle ALT + Enter to expand participant list of
 selected conversation.

---
 indra/llui/llfolderviewitem.cpp         |  2 +-
 indra/newview/llfloaterimcontainer.cpp  | 88 ++++++++++++++++++++++++++-------
 indra/newview/llfloaterimcontainer.h    |  6 ++-
 indra/newview/llfloaterimnearbychat.cpp | 17 ++++++-
 indra/newview/llfloaterimsessiontab.cpp | 21 ++++++++
 indra/newview/llfloaterimsessiontab.h   |  2 +-
 indra/newview/llviewerwindow.cpp        |  9 +++-
 7 files changed, 121 insertions(+), 24 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index f67c134751..fdb4108afb 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -2072,7 +2072,7 @@ LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* it
 		if (fit != fend)
 		{
 			// try selecting child element of this folder
-			if ((*fit)->isOpen())
+			if ((*fit)->isOpen() && include_children)
 			{
 				result = (*fit)->getPreviousFromChild(NULL);
 			}
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index f9f0173ec7..49c30e8768 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1339,25 +1339,14 @@ void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
 
 // Select the conversation *after* (or before if none after) the passed uuid conversation
 // Used to change the selection on key hits
-void LLFloaterIMContainer::selectNextConversation(const LLUUID& uuid)
+void LLFloaterIMContainer::selectNextConversationByID(const LLUUID& uuid)
 {
-	LLFolderViewItem* new_selection = NULL;
-	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
-	if (widget)
+	bool new_selection = false;
+	selectConversation(uuid);
+	new_selection = selectNextorPreviousConversation(true);
+	if (!new_selection)
 	{
-		new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
-		if (!new_selection)
-		{
-			new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
-		}
-	}
-	if (new_selection)
-	{
-		LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
-		if (vmi)
-		{
-			selectConversationPair(vmi->getUUID(), true);
-		}
+		selectNextorPreviousConversation(false);
 	}
 }
 
@@ -1887,6 +1876,71 @@ bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conve
 	return !mConversationsRoot->getVisibleRect().overlaps(widget_rect);
 }
 
+BOOL LLFloaterIMContainer::handleKeyHere(KEY key, MASK mask )
+{
+	if(mask == MASK_ALT)
+	{
+		if (KEY_RETURN == key )
+		{
+			expandConversation();
+		}
+
+		if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
+		{
+			selectNextorPreviousConversation(true);
+		}
+		if ((KEY_UP == key) || (KEY_LEFT == key))
+		{
+			selectNextorPreviousConversation(false);
+		}
+	}
+	return TRUE;
+}
+
+bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next)
+{
+	if (mConversationsWidgets.size() > 1)
+	{
+		LLFolderViewItem* new_selection = NULL;
+		LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,getSelectedSession());
+		if (widget)
+		{
+			if(select_next)
+			{
+				new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
+			}
+			else
+			{
+				new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
+			}
+			if (new_selection)
+			{
+				LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+				if (vmi)
+				{
+					selectConversationPair(vmi->getUUID(), true);
+					LLFloater* floaterp = get_ptr_in_map(mSessions, getSelectedSession());
+					if(floaterp && !floaterp->isTornOff())
+					{
+						setFocus(TRUE);
+					}
+					return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+
+void LLFloaterIMContainer::expandConversation()
+{
+	LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession()));
+	if (widget)
+	{
+		widget->setOpen(!widget->isOpen());
+	}
+}
+
 void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
 {
 	// Always unminimize before trying to close.
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index f1415cd2e6..c84d4978ec 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -69,9 +69,11 @@ public:
 	void returnFloaterToHost();
     void showConversation(const LLUUID& session_id);
     void selectConversation(const LLUUID& session_id);
-	void selectNextConversation(const LLUUID& session_id);
+	void selectNextConversationByID(const LLUUID& session_id);
     BOOL selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater = true);
     void clearAllFlashStates();
+    bool selectNextorPreviousConversation(bool select_next);
+    void expandConversation();
 
 	/*virtual*/ void tabClose();
 	void showStub(bool visible);
@@ -109,7 +111,7 @@ public:
     void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
 
 	void assignResizeLimits();
-
+	virtual BOOL handleKeyHere(KEY key, MASK mask );
 	/*virtual*/ void closeFloater(bool app_quitting = false);
 
 private:
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index a3b81e037a..02f54e76db 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -150,7 +150,7 @@ void LLFloaterIMNearbyChat::closeHostedFloater()
 		{
 			setVisible(FALSE);
 		}
-		floater_container->selectNextConversation(LLUUID());
+		floater_container->selectNextConversationByID(LLUUID());
 	}
 }
 
@@ -354,6 +354,21 @@ BOOL LLFloaterIMNearbyChat::handleKeyHere( KEY key, MASK mask )
 		handled = TRUE;
 	}
 
+	if((mask == MASK_ALT) && isTornOff())
+	{
+		LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+		if ((KEY_UP == key) || (KEY_LEFT == key))
+		{
+			floater_container->selectNextorPreviousConversation(false);
+			handled = TRUE;
+		}
+		if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
+		{
+			floater_container->selectNextorPreviousConversation(true);
+			handled = TRUE;
+		}
+	}
+
 	return handled;
 }
 
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 6dbcdb4474..47744b6ba0 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -918,3 +918,24 @@ LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()
 
 	return conversationItem;
 }
+
+BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )
+{
+	if(mask == MASK_ALT)
+	{
+		LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+		if (KEY_RETURN == key && !isTornOff())
+		{
+			floater_container->expandConversation();
+		}
+		if ((KEY_UP == key) || (KEY_LEFT == key))
+		{
+			floater_container->selectNextorPreviousConversation(false);
+		}
+		if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
+		{
+			floater_container->selectNextorPreviousConversation(true);
+		}
+	}
+	return TRUE;
+}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index e90fcbb806..b52bdfd8cd 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -95,8 +95,8 @@ public:
 	void initBtns();
 	virtual void updateMessages() {}
 	LLConversationItem* getCurSelectedViewModelItem();
-
 	void forceReshape();
+	virtual BOOL handleKeyHere( KEY key, MASK mask );
 
 protected:
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e6e93d81bc..e44a2cc4df 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2515,7 +2515,9 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 			{
 				// let Control-Up and Control-Down through for chat line history,
 				if (!(key == KEY_UP && mask == MASK_CONTROL)
-					&& !(key == KEY_DOWN && mask == MASK_CONTROL))
+					&& !(key == KEY_DOWN && mask == MASK_CONTROL)
+					&& !(key == KEY_UP && mask == MASK_ALT)
+					&& !(key == KEY_DOWN && mask == MASK_ALT))
 				{
 					switch(key)
 					{
@@ -2607,7 +2609,10 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
 	if ((uni_char == 13 && mask != MASK_CONTROL)
 		|| (uni_char == 3 && mask == MASK_NONE))
 	{
-		return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+		if (mask != MASK_ALT)
+		{
+			return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+		}
 	}
 
 	// let menus handle navigation (jump) keys
-- 
cgit v1.2.3


From ae8f8c6999c4ccc396c4f329842e61592a59586e Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 1 Mar 2013 14:36:39 +0200
Subject: CHUI-794 FIXED Disable context menu options if you select yourself
 with other participants

---
 indra/newview/llfloaterimcontainer.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 49c30e8768..d6571845cc 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1213,6 +1213,15 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
 		return false;
 	}
 
+	// If the user agent is selected with others, everything is disabled
+	for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
+	{
+		if (gAgent.getID() == *id)
+		{
+			return false;
+		}
+	}
+
 	// Handle all other options
 	if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
 	{
-- 
cgit v1.2.3


From 7b8822a24ae0a26228b975ebff3f22a0365ffd9e Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 28 Feb 2013 19:59:26 +0200
Subject: CHUI-795 FIXED 'Chat history' is enabled but not functional in
 context menu for friend in Conversation pane while all logs cleared.

---
 indra/newview/llfloaterimcontainer.cpp | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index d6571845cc..46ec1d510d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1096,12 +1096,9 @@ void LLFloaterIMContainer::doToSelectedConversation(const std::string& command,
         }
         else if("chat_history" == command)
         {
-			const LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(conversationItem->getUUID());
-
-			if (NULL != session)
+			if (selectedIDS.size() > 0)
 			{
-				const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
-				LLFloaterReg::showInstance("preview_conversation", session_id, true);
+				LLAvatarActions::viewChatHistory(selectedIDS.front());
 			}
         }
         else
@@ -1165,15 +1162,9 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 	}
 
 	//Enable Chat history item for ad-hoc and group conversations
-	if ("can_chat_history" == item)
+	if ("can_chat_history" == item && uuids.size() > 0)
 	{
-		if(getCurSelectedViewModelItem())
-		{
-			if (getCurSelectedViewModelItem()->getType() != LLConversationItem::CONV_PARTICIPANT)
-			{
-				return isConversationLoggingAllowed();
-			}
-		}
+		return LLLogChat::isTranscriptExist(uuids.front());
 	}
 
 	// If nothing is selected(and selected item is not group chat), everything needs to be disabled
-- 
cgit v1.2.3


From e42e6bc68ae0b0f7a0bd2ca6f500ba783cc201a3 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 1 Mar 2013 17:02:51 -0800
Subject: CHUI-807 : Fixed (attempt) : Defensive coding to prevent potential
 crash

---
 indra/llui/lltabcontainer.cpp | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'indra')

diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 91527c68f2..0c43a571b8 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1483,6 +1483,8 @@ BOOL LLTabContainer::setTab(S32 which)
 		for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
 		{
 			LLTabTuple* tuple = *iter;
+			if (!tuple)
+				continue;
 			BOOL is_selected = ( tuple == selected_tuple );
 			tuple->mButton->setUseEllipses(mUseTabEllipses);
 			tuple->mButton->setHAlign(mFontHalign);
-- 
cgit v1.2.3


From 23ca3a1f2ce113cde94bdfea5fd794ecf808535e Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Mon, 4 Mar 2013 17:11:14 +0200
Subject: CHUI-806 (IM floater is not become as a top while geting message with
 enabled  'Open conversation window' option)

---
 indra/newview/llimview.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d69bd89f13..8f3f5145a9 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -273,7 +273,7 @@ void on_new_message(const LLSD& msg)
 		}
     }
 
-    else if("openconversations" == action && !session_floater_is_open)
+    else if("openconversations" == action)
     {
         //User is not focused on conversation containing the message
         if(session_floater_not_focused)
@@ -291,7 +291,8 @@ void on_new_message(const LLSD& msg)
             //useMostItrusiveIMNotification will be called to notify user a message exists
             if(session_id.notNull() 
                 && participant_id.notNull()
-                && gAgent.isDoNotDisturb())
+                && gAgent.isDoNotDisturb()
+				&& !session_floater_is_open)
             {
                 LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
 			}
-- 
cgit v1.2.3


From 19033255ee2952bd5ee1ebf6114b518548106f34 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 4 Mar 2013 19:10:40 +0200
Subject: CHUI-821 FIXED Conversation size regression when logging out with
 conversation list minimized to icons : save current conv. panel's width

---
 indra/newview/llfloaterimcontainer.cpp | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 46ec1d510d..8d630b9d50 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -764,6 +764,14 @@ void LLFloaterIMContainer::assignResizeLimits()
 	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
 	S32 new_min_width = conv_pane_current_width + msg_pane_min_width + summary_width_of_visible_borders;
 
+    if (is_conv_pane_expanded)
+    {
+    	// Save the conversations pane width.
+	    gSavedPerAccountSettings.setS32(
+	            "ConversationsListPaneWidth",
+                mConversationsPane->getRect().getWidth());
+    }
+
 	setResizeLimits(new_min_width, getMinHeight());
 }
 
@@ -1947,10 +1955,10 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
 	// Most of the time the user will never see this state.
 	setMinimized(FALSE);
 
-	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
-
-	// Save the conversations pane width before collapsing it.
-	gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", conv_pane_width);
+	// Save the conversations pane width.
+	gSavedPerAccountSettings.setS32(
+			"ConversationsListPaneWidth",
+			mConversationsPane->getRect().getWidth());
 
 	LLFloater::closeFloater(app_quitting);
 }
-- 
cgit v1.2.3


From ce7db31b7f113967d1fb8033bb41261700fca109 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Mon, 4 Mar 2013 18:46:37 +0200
Subject: CHUI-822 FIXED Resizing conversation floater with conversation list
 minimized to icons sets to fixed width that cannot be reduced : set resize
 limits to conv.panel's minDim() when conv. panel is collapsed

---
 indra/newview/llfloaterimcontainer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 8d630b9d50..413707baae 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -759,7 +759,7 @@ void LLFloaterIMContainer::assignResizeLimits()
     S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3);
     S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH;
 	S32 conv_pane_current_width = is_msg_pane_expanded
-			? mConversationsPane->getRect().getWidth()
+			? (is_conv_pane_expanded? mConversationsPane->getRect().getWidth() : mConversationsPane->getMinDim())
 			: (is_conv_pane_expanded? mConversationsPane->getExpandedMinDim() : mConversationsPane->getMinDim());
 	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
 	S32 new_min_width = conv_pane_current_width + msg_pane_min_width + summary_width_of_visible_borders;
-- 
cgit v1.2.3


From a26c1672235578f3a4e21be370b11522207e2c57 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 4 Mar 2013 20:05:35 +0200
Subject: CHUI-757 FIXED CHUI viewer shows Autopilot cancelled notification
 toast when interrupting click to walk:  - The AutopilotCanceled notification
 was disabled for this viewer;

---
 indra/newview/skins/default/xui/en/notifications.xml | 8 --------
 1 file changed, 8 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 3ae9b206a4..9c81c877b5 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -9706,14 +9706,6 @@ There is no suitable surface to sit on, try another spot.
 No room to sit here, try another spot.
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="AutopilotCanceled"
-   type="notify">
-   <tag>fail</tag>
-Autopilot canceled
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="ClaimObjectFailedNoPermission"
-- 
cgit v1.2.3


From 9f965be297422ddab79ff9be47fb6d5c64a5096f Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 4 Mar 2013 10:11:51 -0800
Subject: CHUI-778: Now when changing paths for chat logs and transcripts any
 empty conversations will be reloaded with data from the new location. Use
 case for this is if the users nearby chat is empty and they switch to a
 location that has a nearby chat file, then the nearby chat file be loaded.

---
 indra/newview/llfloaterimnearbychat.h   |  1 +
 indra/newview/llfloaterimsession.h      |  1 +
 indra/newview/llfloaterimsessiontab.cpp | 21 +++++++++++++++++++++
 indra/newview/llfloaterimsessiontab.h   |  1 +
 indra/newview/llfloaterpreference.cpp   |  7 ++++++-
 indra/newview/lllogchat.cpp             | 32 ++++++++++++++++----------------
 6 files changed, 46 insertions(+), 17 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index 2992c12436..4ad37eb0c7 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -69,6 +69,7 @@ public:
 	LLChatEntry* getChatBox() { return mInputEditor; }
 
 	std::string getCurrentChat();
+	S32 getMessageArchiveLength() {return mMessageArchive.size();}
 
 	virtual BOOL handleKeyHere( KEY key, MASK mask );
 
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 381b3cf721..cb330bca0f 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -133,6 +133,7 @@ public:
 	static floater_showed_signal_t sIMFloaterShowedSignal;
 
 	bool needsTitleOverwrite() { return mSessionNameUpdatedForTyping && mOtherTyping; }
+	S32 getLastChatMessageIndex() {return mLastMessageIndex;}
 private:
 
 	/*virtual*/ void refresh();
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 6dbcdb4474..f773ed4e23 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -725,6 +725,27 @@ void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/*
 	}
 }
 
+// static
+void LLFloaterIMSessionTab::reloadEmptyFloaters()
+{
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+		iter != inst_list.end(); ++iter)
+	{
+		LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
+		if (floater && floater->getLastChatMessageIndex() == -1)
+		{
+			floater->reloadMessages(true);
+		}
+	}
+
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat && nearby_chat->getMessageArchiveLength() == 0)
+	{
+		nearby_chat->reloadMessages(true);
+	}
+}
+
 void LLFloaterIMSessionTab::updateCallBtnState(bool callIsActive)
 {
 	LLButton* voiceButton = getChild<LLButton>("voice_call_btn");
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index e90fcbb806..b245049137 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -54,6 +54,7 @@ public:
 
 	// reload all message with new settings of visual modes
 	static void processChatHistoryStyleUpdate(bool clean_messages = false);
+	static void reloadEmptyFloaters();
 
 	/**
 	 * Returns true if chat is displayed in multi tabbed floater
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 988190f96a..3f8c23ba83 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -798,8 +798,13 @@ void LLFloaterPreference::onBtnOK()
 		//Conversation transcript and log path changed so reload conversations based on new location
 		if(mPriorInstantMessageLogPath.length())
 		{
+			if(moveTranscriptsAndLog())
+			{
+				//When floaters are empty but have a chat history files, reload chat history into them
+				LLFloaterIMSessionTab::reloadEmptyFloaters();
+			}
 			//Couldn't move files so restore the old path and show a notification
-			if(!moveTranscriptsAndLog())
+			else
 			{
 				gSavedPerAccountSettings.setString("InstantMessageLogPath", mPriorInstantMessageLogPath);
 				LLNotificationsUtil::add("PreferenceChatPathChanged");
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 6562cfe1bb..448100c5d6 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -517,6 +517,22 @@ bool LLLogChat::moveTranscripts(const std::string originDirectory,
 		backupFileCount = 0;
 		newFullPath = targetDirectory + fullpath.substr(originDirectory.length(), std::string::npos);
 
+		//The target directory contains that file already, so lets store it
+		if(LLFile::isfile(newFullPath))
+		{
+			backupFileName = newFullPath + ".backup";
+
+			//If needed store backup file as .backup1 etc.
+			while(LLFile::isfile(backupFileName))
+			{
+				++backupFileCount;
+				backupFileName = newFullPath + ".backup" + boost::lexical_cast<std::string>(backupFileCount);
+			}
+
+			//Rename the file to its backup name so it is not overwritten
+			LLFile::rename(newFullPath, backupFileName);
+		}
+
 		S32 retry_count = 0;
 		while (retry_count < 5)
 		{
@@ -528,22 +544,6 @@ bool LLLogChat::moveTranscripts(const std::string originDirectory,
 				LL_WARNS("LLLogChat::moveTranscripts") << "Problem renaming " << fullpath << " - errorcode: "
 					<< result << " attempt " << retry_count << LL_ENDL;
 
-				//The target directory contains that file already, so lets store it
-				if(LLFile::isfile(newFullPath))
-				{
-					backupFileName = newFullPath + ".backup";
-
-					//If needed store backup file as .backup1 etc.
-					while(LLFile::isfile(backupFileName))
-					{
-						++backupFileCount;
-						backupFileName = newFullPath + ".backup" + boost::lexical_cast<std::string>(backupFileCount);
-					}
-
-					//Rename the file to its backup name so it is not overwritten
-					LLFile::rename(newFullPath, backupFileName);
-				}
-
 				ms_sleep(100);
 			}
 			else
-- 
cgit v1.2.3


From f352c81f11f26dfe9fe2cf494407045bab41dabf Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Mon, 4 Mar 2013 14:18:49 -0800
Subject: For MAINT-2423 fix regression from CHUI merge. Code review: DaveP

---
 indra/newview/lldrawable.cpp | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 59c2f15dd9..ba1759f642 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -643,18 +643,9 @@ BOOL LLDrawable::updateMove()
 		return FALSE;
 	}
 	
-	BOOL done;
+	makeActive();
 
-	if (isState(MOVE_UNDAMPED))
-	{
-		done = updateMoveUndamped();
-	}
-	else
-	{
-		makeActive();
-		done = updateMoveDamped();
-	}
-	return done;
+	return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped();
 }
 
 BOOL LLDrawable::updateMoveUndamped()
-- 
cgit v1.2.3


From a5861a4a49b06fe8e61c5d120df637062e10799d Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Tue, 5 Mar 2013 00:41:22 +0000
Subject: CHUI-772 FIX User sees no notification of conversation activity not
 visible in long scrolling conversation list Added call to
 setSelectedSession() from LLConversationViewParticipant::handleMouseDown()

---
 indra/newview/llconversationview.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 882ef64715..74b348cd81 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -567,6 +567,7 @@ BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
 
     		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
     		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+			im_container->setSelectedSession(session_id);
 			im_container->flashConversationItemWidget(session_id,false);
 			im_container->selectFloater(session_floater);
 			im_container->collapseMessagesPane(false);
-- 
cgit v1.2.3


From 49319a90ef1fcca590e077805d5aaa65322a1a6d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 4 Mar 2013 19:35:31 -0800
Subject: CHUI-778: Now when delete transcripts is pressed the backup files
 will be deleted as well. Also if clear logs is pressed then backup logs will
 be cleared.

---
 indra/newview/llconversationlog.cpp | 33 +++++++++++++++++++++++++++++++++
 indra/newview/llconversationlog.h   |  2 ++
 indra/newview/lllogchat.cpp         |  2 +-
 3 files changed, 36 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 4be169e267..dd20ca15ae 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -28,9 +28,11 @@
 #include "llagent.h"
 #include "llavatarnamecache.h"
 #include "llconversationlog.h"
+#include "lldiriterator.h"
 #include "llnotificationsutil.h"
 #include "lltrans.h"
 
+#include <boost/foreach.hpp>
 #include "boost/lexical_cast.hpp"
 
 const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec
@@ -380,6 +382,36 @@ void LLConversationLog::cache()
 	}
 }
 
+void LLConversationLog::getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs)
+{
+	// get Users log directory
+	std::string dirname = gDirUtilp->getPerAccountChatLogsDir();
+
+	// add final OS dependent delimiter
+	dirname += gDirUtilp->getDirDelimiter();
+
+	// create search pattern
+	std::string pattern = "conversation.log.backup*";
+
+	LLDirIterator iter(dirname, pattern);
+	std::string filename;
+	while (iter.next(filename))
+	{
+		list_of_backup_logs.push_back(gDirUtilp->add(dirname, filename));
+	}
+}
+
+void LLConversationLog::deleteBackupLogs()
+{
+	std::vector<std::string> backup_logs;
+	getListOfBackupLogs(backup_logs);
+
+	BOOST_FOREACH(const std::string& fullpath, backup_logs)
+	{
+		LLFile::remove(fullpath);
+	}
+}
+
 bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)
 {
 
@@ -575,5 +607,6 @@ void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD&
 		mConversations.clear();
 		notifyObservers();
 		cache();
+		deleteBackupLogs();
 	}
 }
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 58e698de25..265b1f0ef0 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -138,6 +138,8 @@ public:
 	 */
 	void cache();
 	bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);
+	void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs);
+	void deleteBackupLogs();
 
 	void onClearLog();
 	void onClearLogResponse(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 448100c5d6..7f4b925b53 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -453,7 +453,7 @@ void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_trans
 	dirname += gDirUtilp->getDirDelimiter();
 
 	// create search pattern
-	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
+	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION + "*";
 
 	LLDirIterator iter(dirname, pattern);
 	std::string filename;
-- 
cgit v1.2.3


From 67741ae9786a88bb00f3419ad6a8ac8533481acb Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 5 Mar 2013 15:28:41 +0200
Subject: CHUI-815 FIXED Handle SHIFT+ENTER to whisper in Nearby chat

---
 indra/newview/llfloaterimnearbychat.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 02f54e76db..dfaf4bbdd6 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -353,6 +353,13 @@ BOOL LLFloaterIMNearbyChat::handleKeyHere( KEY key, MASK mask )
 		sendChat(CHAT_TYPE_SHOUT);
 		handled = TRUE;
 	}
+	else if (KEY_RETURN == key && mask == MASK_SHIFT)
+	{
+		// whisper
+		sendChat(CHAT_TYPE_WHISPER);
+		handled = TRUE;
+	}
+
 
 	if((mask == MASK_ALT) && isTornOff())
 	{
-- 
cgit v1.2.3


From 477920b13834c977659d11d91d8f2d52e05f54b8 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 5 Mar 2013 15:40:31 +0200
Subject: CHUI-809 FIXED "Start IM" menu item is added

---
 indra/llui/lltextbase.cpp                             |  1 +
 indra/llui/llurlaction.cpp                            | 14 ++++++++++++++
 indra/llui/llurlaction.h                              |  1 +
 indra/newview/skins/default/xui/en/menu_url_agent.xml |  7 +++++++
 4 files changed, 23 insertions(+)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7cee9f5b46..4bb819a7f6 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1911,6 +1911,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));
 	registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
 	registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
+	registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
 	registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
 	registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
 	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index fd9b3d9a6d..fd872eca4b 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -157,3 +157,17 @@ void LLUrlAction::showProfile(std::string url)
 		}
 	}
 }
+
+void LLUrlAction::sendIM(std::string url)
+{
+	LLURI uri(url);
+	LLSD path_array = uri.pathArray();
+	if (path_array.size() == 4)
+	{
+		std::string id_str = path_array.get(2).asString();
+		if (LLUUID::validate(id_str))
+		{
+			executeSLURL("secondlife:///app/agent/" + id_str + "/im");
+		}
+	}
+}
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index c34960b826..f5f2ceba72 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -76,6 +76,7 @@ public:
 
 	/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
 	static void showProfile(std::string url);
+	static void sendIM(std::string url);
 
 	/// specify the callbacks to enable this class's functionality
 	typedef boost::function<void (const std::string&)> url_callback_t;
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
index 73f0fa7979..88ae441bd3 100644
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -2,6 +2,13 @@
 <context_menu
  layout="topleft"
  name="Url Popup">
+    <menu_item_call
+     label="Send IM"
+     layout="topleft"
+     name="show_agent">
+        <menu_item_call.on_click
+         function="Url.SendIM" />        
+    </menu_item_call>
     <menu_item_call
      label="Show Resident Profile"
      layout="topleft"
-- 
cgit v1.2.3


From 84662ce63bea0d5ff8ff8bed0b12e4162a8514a5 Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Tue, 5 Mar 2013 18:54:43 +0200
Subject: CHUI-764 (Group Profile is not opened after selecting 'Show group
 information' in context menu of 'About Land' dialog)

---
 indra/newview/skins/default/xui/en/menu_url_group.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/menu_url_group.xml b/indra/newview/skins/default/xui/en/menu_url_group.xml
index c5eaf94d22..2cb125ce09 100644
--- a/indra/newview/skins/default/xui/en/menu_url_group.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_group.xml
@@ -7,7 +7,7 @@
      layout="topleft"
      name="show_group">
         <menu_item_call.on_click
-         function="Url.Execute" />
+         function="Url.ShowProfile" />
     </menu_item_call>
     <menu_item_separator
      layout="topleft" />
-- 
cgit v1.2.3


From 95cea4aa71b84fb203167084c51892f09520fd48 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 5 Mar 2013 13:20:24 -0800
Subject: CHUI-778: Adjusted deletion of transcripts/logs to be more clean
 code-wise.

---
 indra/newview/lllogchat.cpp | 22 ++++++++++++++++++----
 indra/newview/lllogchat.h   |  2 ++
 2 files changed, 20 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 7f4b925b53..2d7454b636 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -444,7 +444,7 @@ std::string LLLogChat::oldLogFileName(std::string filename)
 }
 
 // static
-void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions)
+void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions)
 {
 	// get Users log directory
 	std::string dirname = gDirUtilp->getPerAccountChatLogsDir();
@@ -452,9 +452,6 @@ void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_trans
 	// add final OS dependent delimiter
 	dirname += gDirUtilp->getDirDelimiter();
 
-	// create search pattern
-	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION + "*";
-
 	LLDirIterator iter(dirname, pattern);
 	std::string filename;
 	while (iter.next(filename))
@@ -490,6 +487,22 @@ void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_trans
 	}
 }
 
+// static
+void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions)
+{
+	// create search pattern
+	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
+	findTranscriptFiles(pattern, list_of_transcriptions);
+}
+
+// static
+void LLLogChat::getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions)
+{
+	// create search pattern
+	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION + ".backup*";
+	findTranscriptFiles(pattern, list_of_transcriptions);
+}
+
 //static
 boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_signal_t::slot_type& cb)
 {
@@ -581,6 +594,7 @@ void LLLogChat::deleteTranscripts()
 {
 	std::vector<std::string> list_of_transcriptions;
 	getListOfTranscriptFiles(list_of_transcriptions);
+	getListOfTranscriptBackupFiles(list_of_transcriptions);
 
 	BOOST_FOREACH(const std::string& fullpath, list_of_transcriptions)
 	{
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 784786a565..e819f00dd9 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -49,7 +49,9 @@ public:
 				const std::string& from,
 				const LLUUID& from_id,
 				const std::string& line);
+	static void findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions);
 	static void getListOfTranscriptFiles(std::vector<std::string>& list);
+	static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions);
 
 	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
 
-- 
cgit v1.2.3


From f135503a9ed99f5e9b009a6608a9c4bc21c5e8cf Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 5 Mar 2013 13:41:30 -0800
Subject: CHUI-829 (Allow Conversations floater to display a different chat
 than the torn off and selected window): Now when selecting a torn off
 conversation this will not select the conversation line item.

---
 indra/newview/llfloaterimcontainer.cpp  | 4 ++++
 indra/newview/llfloaterimsessiontab.cpp | 7 -------
 2 files changed, 4 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 46ec1d510d..429ea09f56 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1392,6 +1392,10 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 				// Switch to the conversation floater that is being selected
 				selectFloater(session_floater);
 			}
+			else
+			{
+				showStub(true);
+			}
 		}
 
 		// Set the focus on the selected floater
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index d3fcfbbc56..de1b398131 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -324,13 +324,6 @@ void LLFloaterIMSessionTab::onFocusReceived()
 	}
 
 	LLTransientDockableFloater::onFocusReceived();
-
-	LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
-	if (container)
-	{
-		container->selectConversationPair(mSessionID, true);
-		container->showStub(! getHost());
-	}
 }
 
 void LLFloaterIMSessionTab::onFocusLost()
-- 
cgit v1.2.3


From 2ea750ebcad8335aeb0ec77a483831b62d05f643 Mon Sep 17 00:00:00 2001
From: "Graham Madarasz (Graham)" <graham@lindenlab.com>
Date: Tue, 5 Mar 2013 13:47:02 -0800
Subject: For MAINT-2247 MAINT-1742 MAINT-2275 contrib from STORM-1934.

---
 indra/newview/lldrawable.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index ba1759f642..4b0d3b361d 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -577,6 +577,12 @@ F32 LLDrawable::updateXform(BOOL undamped)
 			mVObjp->dirtySpatialGroup();
 		}
 	}
+	else if (!isRoot() &&
+			((dist_vec_squared(old_pos, target_pos) > 0.f)
+			|| (1.f - dot(old_rot, target_rot)) > 0.f))
+	{ //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247
+			gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+	}
 	else if (!getVOVolume() && !isAvatar())
 	{
 		movePartition();
-- 
cgit v1.2.3


From 4a50271c19f584916c84abc117636f45fc050e61 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 6 Mar 2013 19:00:28 +0200
Subject: CHUI-821 Clean up code

---
 indra/newview/llfloaterimcontainer.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 413707baae..29ff037d59 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -758,11 +758,16 @@ void LLFloaterIMContainer::assignResizeLimits()
 	// between the panels are merged into one
     S32 number_of_visible_borders = llmin((is_conv_pane_expanded? 2 : 0) + (is_msg_pane_expanded? 2 : 0), 3);
     S32 summary_width_of_visible_borders = number_of_visible_borders * LLPANEL_BORDER_WIDTH;
-	S32 conv_pane_current_width = is_msg_pane_expanded
+	S32 conv_pane_target_width = is_conv_pane_expanded?
+			(is_msg_pane_expanded?
+					mConversationsPane->getRect().getWidth()
+					: mConversationsPane->getExpandedMinDim())
+			: mConversationsPane->getMinDim();
+	S32 conv_pane_target_width = is_msg_pane_expanded
 			? (is_conv_pane_expanded? mConversationsPane->getRect().getWidth() : mConversationsPane->getMinDim())
 			: (is_conv_pane_expanded? mConversationsPane->getExpandedMinDim() : mConversationsPane->getMinDim());
 	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
-	S32 new_min_width = conv_pane_current_width + msg_pane_min_width + summary_width_of_visible_borders;
+	S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders;
 
     if (is_conv_pane_expanded)
     {
-- 
cgit v1.2.3


From 82c92ce5a97d6a83505c775348aef692e18e42ed Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 6 Mar 2013 19:02:19 +0200
Subject: CHUI-821 Clean up code

---
 indra/newview/llfloaterimcontainer.cpp | 3 ---
 1 file changed, 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 29ff037d59..a0c386717b 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -763,9 +763,6 @@ void LLFloaterIMContainer::assignResizeLimits()
 					mConversationsPane->getRect().getWidth()
 					: mConversationsPane->getExpandedMinDim())
 			: mConversationsPane->getMinDim();
-	S32 conv_pane_target_width = is_msg_pane_expanded
-			? (is_conv_pane_expanded? mConversationsPane->getRect().getWidth() : mConversationsPane->getMinDim())
-			: (is_conv_pane_expanded? mConversationsPane->getExpandedMinDim() : mConversationsPane->getMinDim());
 	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
 	S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders;
 
-- 
cgit v1.2.3


From d73ca40667527a1fdaf29ac3629ec7ce8a7e0f40 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Wed, 6 Mar 2013 17:43:10 -0800
Subject: CHUI-834 (Conversation selection in conversation list does not update
 when redocking torn off conversations): Now when click to dock a torn off
 floater, the correct conversation line item will be selected.

---
 indra/newview/llfloaterimsessiontab.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index de1b398131..164625fc95 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -798,6 +798,12 @@ void LLFloaterIMSessionTab::onTearOffClicked()
 	{
 		forceReshape();
 	}
+	//Upon re-docking the torn off floater, select the corresponding conversation line item
+	else
+	{
+		LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
+		container->selectConversation(mSessionID);
+	}
 	refreshConversation();
 	updateGearBtn();
 }
-- 
cgit v1.2.3


From 4458986cf22a749d3387085a70ea07930519b8ab Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 6 Mar 2013 18:44:02 -0800
Subject: CHUI-705 : Fixed! Force hide context menu when deleting line editor
 widget

---
 indra/llui/lllineeditor.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'indra')

diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 2e64be89fa..6976b06a92 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -202,6 +202,14 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 LLLineEditor::~LLLineEditor()
 {
 	mCommitOnFocusLost = FALSE;
+    
+    // Make sure no context menu linger around once the widget is deleted
+	LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
+	if (menu)
+	{
+        menu->hide();
+    }
+	setContextMenu(NULL);
 
 	// calls onCommit() while LLLineEditor still valid
 	gFocusMgr.releaseFocusIfNeeded( this );
-- 
cgit v1.2.3


From 8e924c850569b8aa2d2765c6514d742f51f3392b Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Thu, 7 Mar 2013 13:49:29 +0200
Subject: CHUI-823 ([CHUIBUG]Triple-clicking on the scroll back button in the
 CHUI causes all the conversation to be selected)

---
 indra/llui/lltextbase.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7cee9f5b46..89d9f47dc2 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1086,7 +1086,14 @@ BOOL LLTextBase::handleRightMouseUp(S32 x, S32 y, MASK mask)
 
 BOOL LLTextBase::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
-	mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
+	//Don't start triple click timer if user have clicked on scrollbar
+	mVisibleTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect();
+	if (x >= mVisibleTextRect.mLeft && x <= mVisibleTextRect.mRight
+	    && y >= mVisibleTextRect.mBottom && y <= mVisibleTextRect.mTop)
+	{
+		mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
+	}
+
 	LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
 	if (cur_segment && cur_segment->handleDoubleClick(x, y, mask))
 	{
-- 
cgit v1.2.3


From 014376b49a1e6bf41fa8b0f1b36c0c02fca3096e Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 7 Mar 2013 16:26:37 -0800
Subject: CHUI-832 (Different conversation than is selected shown in message
 panel after tearing off conversation): Now when a conversation is torn off an
 adjacent conversation is selected (but not focused).

---
 indra/newview/llfloaterimcontainer.cpp  | 21 ++++++++++++++-------
 indra/newview/llfloaterimcontainer.h    |  3 ++-
 indra/newview/llfloaterimsessiontab.cpp |  4 +++-
 3 files changed, 19 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 5a37b5b57b..d67f2be658 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1912,7 +1912,19 @@ BOOL LLFloaterIMContainer::handleKeyHere(KEY key, MASK mask )
 	return TRUE;
 }
 
-bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next)
+bool LLFloaterIMContainer::selectAdjacentConversation(bool focus_selected)
+{
+	bool selectedAdjacentConversation = selectNextorPreviousConversation(true, focus_selected);
+
+	if(!selectedAdjacentConversation)
+	{
+		selectedAdjacentConversation = selectNextorPreviousConversation(false, focus_selected);
+	}
+
+	return selectedAdjacentConversation;
+}
+
+bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next, bool focus_selected)
 {
 	if (mConversationsWidgets.size() > 1)
 	{
@@ -1933,12 +1945,7 @@ bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next)
 				LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
 				if (vmi)
 				{
-					selectConversationPair(vmi->getUUID(), true);
-					LLFloater* floaterp = get_ptr_in_map(mSessions, getSelectedSession());
-					if(floaterp && !floaterp->isTornOff())
-					{
-						setFocus(TRUE);
-					}
+					selectConversationPair(vmi->getUUID(), true, focus_selected);
 					return true;
 				}
 			}
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index c84d4978ec..1e760a8710 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -72,7 +72,8 @@ public:
 	void selectNextConversationByID(const LLUUID& session_id);
     BOOL selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater = true);
     void clearAllFlashStates();
-    bool selectNextorPreviousConversation(bool select_next);
+	bool selectAdjacentConversation(bool focus_selected);
+    bool selectNextorPreviousConversation(bool select_next, bool focus_selected = true);
     void expandConversation();
 
 	/*virtual*/ void tabClose();
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 164625fc95..faeb860712 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -794,14 +794,16 @@ void LLFloaterIMSessionTab::onTearOffClicked()
     mSaveRect = isTornOff();
     initRectControl();
 	LLFloater::onClickTearOff(this);
+	LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
+
 	if (isTornOff())
 	{
+		container->selectAdjacentConversation(false);
 		forceReshape();
 	}
 	//Upon re-docking the torn off floater, select the corresponding conversation line item
 	else
 	{
-		LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
 		container->selectConversation(mSessionID);
 	}
 	refreshConversation();
-- 
cgit v1.2.3


From 228d868cf6b3436f9cace3db5bd304e7ea639609 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Fri, 8 Mar 2013 02:02:45 +0000
Subject: CHUI-772 FIX User sees no notification of conversation activity not
 visible in long scrolling conversation list Added call to
 mConversationsRoot->arrange() in LLFloaterIMContainer::isScrolledOutOfSight()

---
 indra/newview/llconversationview.cpp   | 15 +++++++++------
 indra/newview/llfloaterimcontainer.cpp |  3 +++
 2 files changed, 12 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 74b348cd81..837389aed5 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -104,6 +104,15 @@ LLConversationViewSession::~LLConversationViewSession()
 
 void LLConversationViewSession::setFlashState(bool flash_state)
 {
+	if (flash_state && !mFlashStateOn)
+	{
+		// flash chat toolbar button if scrolled out of sight (because flashing will not be visible)
+		if (mContainer->isScrolledOutOfSight(this))
+		{
+			gToolBarView->flashCommand(LLCommandId("chat"), true);
+		}
+	}
+
 	mFlashStateOn = flash_state;
 	mFlashStarted = false;
 	mFlashTimer->stopFlashing();
@@ -115,12 +124,6 @@ void LLConversationViewSession::startFlashing()
 	{
 		mFlashStarted = true;
 		mFlashTimer->startFlashing();
-		
-		// flash chat toolbar button if scrolled out of sight (because flashing will not be visible)
-		if (mContainer->isScrolledOutOfSight(this))
-		{
-			gToolBarView->flashCommand(LLCommandId("chat"), true);
-		}
 	}
 }
 
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 74490b695c..e2b9723537 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1881,6 +1881,9 @@ bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conve
 {
 	llassert(conversation_item_widget != NULL);
 
+	// make sure the widget is actually in the right spot first
+	mConversationsRoot->arrange(NULL, NULL);
+
 	// check whether the widget is in the visible portion of the scroll container
 	LLRect widget_rect;
 	conversation_item_widget->localRectToOtherView(conversation_item_widget->getLocalRect(), &widget_rect, mConversationsRoot);
-- 
cgit v1.2.3


From 24e650b4039d3b3515109fa9e271abfa2a2ebd6a Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 8 Mar 2013 18:34:40 -0800
Subject: CHUI-835 (ctrl-h does not select nearby chat conversation in list):
 Modified setVisibleAndFrontMost() to now take a arguement for the key that
 was pressed (if one was pressed). This allows the floater to select the
 converation line item when becoming visible/frontmost.

---
 indra/llui/llfloater.cpp                |  2 +-
 indra/llui/llfloater.h                  |  2 +-
 indra/llui/llfloaterreg.cpp             | 10 +++++-----
 indra/newview/llfloaterimnearbychat.cpp | 11 +++++++++++
 indra/newview/llfloaterimnearbychat.h   |  1 +
 5 files changed, 19 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 27dd7f5b32..09e27a264a 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1621,7 +1621,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
 
 
 // virtual
-void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
+void LLFloater::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
 {
 	LLMultiFloater* hostp = getHost();
 	if (hostp)
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index cb5bf28db3..4dba1e645f 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -305,7 +305,7 @@ public:
 	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override
 	
 	void			setFrontmost(BOOL take_focus = TRUE);
-    virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE);    
+    virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());    
 	
 	// Defaults to false.
 	virtual BOOL	canSaveAs() const { return FALSE; }
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index c20d863612..1cdddf0d5b 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -488,12 +488,12 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
 		{
 			host->setMinimized(FALSE);
 			instance->openFloater(key);
-			instance->setVisibleAndFrontmost();
+			instance->setVisibleAndFrontmost(true, key);
 		}
 		else if (!instance->getVisible())
 		{
 			instance->openFloater(key);
-			instance->setVisibleAndFrontmost();
+			instance->setVisibleAndFrontmost(true, key);
 			instance->setFocus(TRUE);
 		}
 		else
@@ -506,16 +506,16 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
 		if (instance->isMinimized())
 		{
 			instance->setMinimized(FALSE);
-			instance->setVisibleAndFrontmost();
+			instance->setVisibleAndFrontmost(true, key);
 		}
 		else if (!instance->isShown())
 		{
 			instance->openFloater(key);
-			instance->setVisibleAndFrontmost();
+			instance->setVisibleAndFrontmost(true, key);
 		}
 		else if (!instance->isFrontmost())
 		{
-			instance->setVisibleAndFrontmost();
+			instance->setVisibleAndFrontmost(true, key);
 		}
 		else
 		{
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index dfaf4bbdd6..cfee5001a6 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -257,6 +257,17 @@ void LLFloaterIMNearbyChat::setVisible(BOOL visible)
 	}
 }
 
+
+void LLFloaterIMNearbyChat::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
+{
+	LLFloaterIMSessionTab::setVisibleAndFrontmost(take_focus, key);
+
+	if(!isTornOff() && matchesKey(key))
+	{
+		LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, false);
+	}
+}
+
 // virtual
 void LLFloaterIMNearbyChat::onTearOffClicked()
 {
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index 4ad37eb0c7..05b48cccb0 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -54,6 +54,7 @@ public:
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
 	/*virtual*/ void closeHostedFloater();
 
 	void loadHistory();
-- 
cgit v1.2.3


From 7f5dee6161c6eed96275722cbb52a3fb1fcb3eb7 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 7 Mar 2013 17:31:44 +0200
Subject: CHUI-738 FIXED Your own nametag disappears - mysteriously: reset
 display time when nametag is changes

---
 indra/newview/llvoavatar.cpp | 81 ++++++++++++++++++++++----------------------
 1 file changed, 41 insertions(+), 40 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 157be08f45..c74d9f1292 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2994,43 +2994,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-		BOOL new_name = FALSE;
-		if (visible_chat != mVisibleChat)
+	BOOL new_name = FALSE;
+	if (visible_chat != mVisibleChat)
+	{
+		mVisibleChat = visible_chat;
+		new_name = TRUE;
+	}
+
+	if (sRenderGroupTitles != mRenderGroupTitles)
+	{
+		mRenderGroupTitles = sRenderGroupTitles;
+		new_name = TRUE;
+	}
+
+	// First Calculate Alpha
+	// If alpha > 0, create mNameText if necessary, otherwise delete it
+	F32 alpha = 0.f;
+	if (mAppAngle > 5.f)
+	{
+		const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
+		if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
 		{
-			mVisibleChat = visible_chat;
-			new_name = TRUE;
+			alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
 		}
-		
-		if (sRenderGroupTitles != mRenderGroupTitles)
+		else
 		{
-			mRenderGroupTitles = sRenderGroupTitles;
-			new_name = TRUE;
+			// ...not fading, full alpha
+			alpha = 1.f;
 		}
-
-		// First Calculate Alpha
-		// If alpha > 0, create mNameText if necessary, otherwise delete it
-			F32 alpha = 0.f;
-			if (mAppAngle > 5.f)
-			{
-				const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
-				if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
-				{
-					alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
-				}
-				else
-				{
-					// ...not fading, full alpha
-					alpha = 1.f;
-				}
-			}
-			else if (mAppAngle > 2.f)
-			{
-				// far away is faded out also
-				alpha = (mAppAngle-2.f)/3.f;
-			}
+	}
+	else if (mAppAngle > 2.f)
+	{
+		// far away is faded out also
+		alpha = (mAppAngle-2.f)/3.f;
+	}
 
 	if (alpha <= 0.f)
-			{
+	{
 		if (mNameText)
 		{
 			mNameText->markDead();
@@ -3040,19 +3040,19 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-				if (!mNameText)
-				{
+	if (!mNameText)
+	{
 		mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
 			LLHUDObject::LL_HUD_NAME_TAG) );
 		//mNameText->setMass(10.f);
-					mNameText->setSourceObject(this);
+		mNameText->setSourceObject(this);
 		mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
-					mNameText->setVisibleOffScreen(TRUE);
-					mNameText->setMaxLines(11);
-					mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
-					sNumVisibleChatBubbles++;
-					new_name = TRUE;
-				}
+		mNameText->setVisibleOffScreen(TRUE);
+		mNameText->setMaxLines(11);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+		sNumVisibleChatBubbles++;
+		new_name = TRUE;
+    }
 				
 	idleUpdateNameTagPosition(root_pos_last);
 	idleUpdateNameTagText(new_name);			
@@ -3303,6 +3303,7 @@ void LLVOAvatar::clearNameTag()
 		mNameText->setLabel("");
 		mNameText->setString( "" );
 	}
+	mTimeVisible.reset();
 }
 
 //static
-- 
cgit v1.2.3


From f51a39574722ffaea5912a084b02f8f22972e81c Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 7 Mar 2013 15:59:51 +0200
Subject: CHUI-821 ADD FIX Conversation size regression when logging out with
 conversation list minimized to icons: deleted redundant savings of the
 convers. panel width; added a manually reshape of the conv. panel after
 change it's collapse state; function with uninformative name "updateState"
 was renamed to "reshapeFloaterAndSetResizeLimits"

---
 indra/newview/llfloaterimcontainer.cpp | 49 ++++++++++++++++------------------
 indra/newview/llfloaterimcontainer.h   |  4 +--
 2 files changed, 25 insertions(+), 28 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index cdffdcf806..7437dd8cda 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -226,10 +226,11 @@ BOOL LLFloaterIMContainer::postBuild()
 	childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this));
 
 	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
-	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
+	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"), false);
 	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
 	mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
-	if (! mMessagesPane->isCollapsed())
+
+	if (! mMessagesPane->isCollapsed() && ! mConversationsPane->isCollapsed())
 	{
 		S32 conversations_panel_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
 		LLRect conversations_panel_rect = mConversationsPane->getRect();
@@ -668,7 +669,7 @@ void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 	// Make sure layout is updated before resizing conversation pane.
 	mConversationsStack->updateLayout();
 
-	updateState(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+	reshapeFloaterAndSetResizeLimits(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
 
 	if (!collapse)
 	{
@@ -677,7 +678,7 @@ void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 	}
 }
 
-void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
+void LLFloaterIMContainer::collapseConversationsPane(bool collapse, bool save_is_allowed /*=true*/)
 {
 	if (mConversationsPane->isCollapsed() == collapse)
 	{
@@ -691,7 +692,7 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 	// Save current width of Conversation panel before collapsing/expanding right pane.
 	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
 
-	if (collapse)
+	if (collapse && save_is_allowed)
 	{
 		// Save the conversations pane width before collapsing it.
 		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", conv_pane_width);
@@ -701,10 +702,18 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 	}
 
 	mConversationsStack->collapsePanel(mConversationsPane, collapse);
+	if (!collapse)
+	{
+		// Make sure layout is updated before resizing conversation pane.
+		mConversationsStack->updateLayout();
+		// Restore conversation's pane previous width.
+		mConversationsPane->setTargetDim(gSavedPerAccountSettings.getS32("ConversationsListPaneWidth"));
+	}
 
-	S32 delta_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - mConversationsPane->getMinDim();
+	S32 delta_width =
+			gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - mConversationsPane->getMinDim();
 
-	updateState(collapse, delta_width);
+	reshapeFloaterAndSetResizeLimits(collapse, delta_width);
 
 	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
 			widget_it != mConversationsWidgets.end(); ++widget_it)
@@ -724,21 +733,20 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 	}
 }
 
-void LLFloaterIMContainer::updateState(bool collapse, S32 delta_width)
+void LLFloaterIMContainer::reshapeFloaterAndSetResizeLimits(bool collapse, S32 delta_width)
 {
 	LLRect floater_rect = getRect();
 	floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
 
 	// Set by_user = true so that reshaped rect is saved in user_settings.
 	setShape(floater_rect, true);
-
 	updateResizeLimits();
 
-	bool is_left_pane_expanded = !mConversationsPane->isCollapsed();
-	bool is_right_pane_expanded = !mMessagesPane->isCollapsed();
+	bool at_least_one_panel_is_expanded =
+			! (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed());
 
-	setCanResize(is_left_pane_expanded || is_right_pane_expanded);
-	setCanMinimize(is_left_pane_expanded || is_right_pane_expanded);
+	setCanResize(at_least_one_panel_is_expanded);
+	setCanMinimize(at_least_one_panel_is_expanded);
 
     assignResizeLimits();
 
@@ -767,15 +775,9 @@ void LLFloaterIMContainer::assignResizeLimits()
 	S32 msg_pane_min_width  = is_msg_pane_expanded ? mMessagesPane->getExpandedMinDim() : 0;
 	S32 new_min_width = conv_pane_target_width + msg_pane_min_width + summary_width_of_visible_borders;
 
-    if (is_conv_pane_expanded)
-    {
-    	// Save the conversations pane width.
-	    gSavedPerAccountSettings.setS32(
-	            "ConversationsListPaneWidth",
-                mConversationsPane->getRect().getWidth());
-    }
-
 	setResizeLimits(new_min_width, getMinHeight());
+
+	mConversationsStack->updateLayout();
 }
 
 void LLFloaterIMContainer::onAddButtonClicked()
@@ -1972,11 +1974,6 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
 	// Most of the time the user will never see this state.
 	setMinimized(FALSE);
 
-	// Save the conversations pane width.
-	gSavedPerAccountSettings.setS32(
-			"ConversationsListPaneWidth",
-			mConversationsPane->getRect().getWidth());
-
 	LLFloater::closeFloater(app_quitting);
 }
 
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 1e760a8710..5139651d8d 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -129,9 +129,9 @@ private:
 	void processParticipantsStyleUpdate();
 	void onSpeakButtonClicked();
 
-	void collapseConversationsPane(bool collapse);
+	void collapseConversationsPane(bool collapse, bool save_is_allowed=true);
 
-	void updateState(bool collapse, S32 delta_width);
+	void reshapeFloaterAndSetResizeLimits(bool collapse, S32 delta_width);
 
 	void onAddButtonClicked();
 	void onAvatarPicked(const uuid_vec_t& ids);
-- 
cgit v1.2.3


From 11199f2bef65f67f3ddd798944cb4ad62affa8ed Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Thu, 7 Mar 2013 17:04:06 +0200
Subject: CHUI-824 FIXED Open Message panel when session is activated.

---
 indra/newview/llfloaterimcontainer.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index a0c386717b..74490b695c 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -114,6 +114,7 @@ void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::str
 void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
 	selectConversationPair(session_id, true);
+	collapseMessagesPane(false);
 }
 
 void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
-- 
cgit v1.2.3


From d29bec7f4d390b932705ac9342f01f0b2412dd97 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 8 Mar 2013 19:04:01 -0800
Subject: CHUI-793 : WIP : Limit the number of participants we load on groups
 when we load from the local group data

---
 indra/newview/llspeakers.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 05df7261e1..301b489c34 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -409,12 +409,10 @@ void LLSpeakerMgr::update(BOOL resort_ok)
 
 	// update status of all current speakers
 	BOOL voice_channel_active = (!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
-	for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end();)
+	for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); speaker_it++)
 	{
 		LLUUID speaker_id = speaker_it->first;
 		LLSpeaker* speakerp = speaker_it->second;
-		
-		speaker_map_t::iterator  cur_speaker_it = speaker_it++;
 
 		if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id))
 		{
@@ -551,18 +549,25 @@ void LLSpeakerMgr::updateSpeakerList()
 				{
 					// Add group members when we get the complete list (note: can take a while before we get that list)
 					LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin();
+                    S32 updated = 0;
 					while (member_it != gdatap->mMembers.end())
 					{
 						LLGroupMemberData* member = member_it->second;
-						// Add only the members who are online
-						if (member->getOnlineStatus() == "Online")
+                        LLUUID id = member_it->first;
+						// Add only members who are online and not already in the list
+						if ((member->getOnlineStatus() == "Online") && (mSpeakers.find(id) == mSpeakers.end()))
 						{
-							LLPointer<LLSpeaker> speakerp = setSpeaker(member_it->first, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+							LLPointer<LLSpeaker> speakerp = setSpeaker(id, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 							speakerp->mIsModerator = ((member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR);
+                            updated++;
 						}
 						++member_it;
+                        // Limit the number of "manually updated" participants to a reasonable number to avoid severe fps drop
+                        // *TODO : solve the perf issue of having several hundreds of widgets in the conversation list
+                        if (updated >= 100)
+                            break;
 					}
-					mSpeakerListUpdated = true;
+                    mSpeakerListUpdated = true;
 				}
 			}
 			else if (mSpeakers.size() == 0)
-- 
cgit v1.2.3


From 40f61ae60091909bae8229b7d0496154a87fefbf Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Mon, 11 Mar 2013 12:32:34 +0200
Subject: CHUI-840 (Right clicking on unselected group conversation can have
 unpredictable results for menu options)

---
 indra/newview/llconversationview.cpp | 36 +++++++++++++++++++++++++++---------
 indra/newview/llconversationview.h   |  2 ++
 2 files changed, 29 insertions(+), 9 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 74b348cd81..85c9a11b43 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -254,20 +254,38 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
     //This node (conversation) was selected and a child (participant) was not
     if(result && getRoot())
     {
-    	if(getRoot()->getCurSelectedItem() == this)
-    	{
-    		LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
-    		LLUUID session_id = item? item->getUUID() : LLUUID();
+		selectConversationItem();
+    }
 
-    		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-    		im_container->flashConversationItemWidget(session_id,false);
-    		im_container->selectConversationPair(session_id, false);
-    		im_container->collapseMessagesPane(false);
-    	}
+	return result;
+}
+
+BOOL LLConversationViewSession::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+    BOOL result = LLFolderViewFolder::handleRightMouseDown(x, y, mask);
+
+    if(result)
+    {
+		selectConversationItem();
     }
+
 	return result;
 }
 
+void LLConversationViewSession::selectConversationItem()
+{
+	if(getRoot()->getCurSelectedItem() == this)
+	{
+		LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
+		LLUUID session_id = item? item->getUUID() : LLUUID();
+
+		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+		im_container->flashConversationItemWidget(session_id,false);
+		im_container->selectConversationPair(session_id, false);
+		im_container->collapseMessagesPane(false);
+	}
+}
+
 // virtual
 S32 LLConversationViewSession::arrange(S32* width, S32* height)
 {
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 76d3d079ea..3eb2e63792 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -68,6 +68,7 @@ public:
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
 	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
 
 	/*virtual*/ S32 arrange(S32* width, S32* height);
 
@@ -90,6 +91,7 @@ private:
 
 	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
 	void startFlashing();
+	void selectConversationItem();
 
 	LLPanel*				mItemPanel;
 	LLPanel*				mCallIconLayoutPanel;
-- 
cgit v1.2.3


From d2a689be4aee7487a18183d6208c52dc15c39051 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 11 Mar 2013 15:30:49 +0200
Subject: CHUI-815 FIXED Display whispered text in italics and shouted text as
 bold

---
 indra/newview/llchathistory.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index c4f63d9256..0152571e20 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -820,6 +820,15 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		body_message_params.font.style = "ITALIC";
 	}
 
+	if(chat.mChatType == CHAT_TYPE_WHISPER)
+	{
+		body_message_params.font.style = "ITALIC";
+	}
+	else if(chat.mChatType == CHAT_TYPE_SHOUT)
+	{
+		body_message_params.font.style = "BOLD";
+	}
+
 	bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
 	// We graying out chat history by graying out messages that contains full date in a time string
 	if (message_from_log)
-- 
cgit v1.2.3


From 9fb00841669ed75479b57cccaa124747d09bbf97 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Mon, 11 Mar 2013 14:52:15 +0200
Subject: CHUI-836 FIXED [CHUIBUG]Opening chat history from the conversation
 log sometimes crashes the viewer

---
 indra/newview/llconversationloglist.cpp | 69 ++++++++++++++++++++++-----------
 1 file changed, 46 insertions(+), 23 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index 96b225b841..b202cfc9d3 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -198,6 +198,8 @@ void LLConversationLogList::refresh()
 
 void LLConversationLogList::rebuildList()
 {
+	const LLConversation * selected_conversationp = getSelectedConversation();
+
 	clear();
 
 	bool have_filter = !mNameFilter.empty();
@@ -214,7 +216,12 @@ void LLConversationLogList::rebuildList()
 
 		addNewItem(&*iter);
 	}
-	
+
+	// try to restore selection of item
+	if (NULL != selected_conversationp)
+	{
+		selectItemByUUID(selected_conversationp->getSessionID());
+	}
 
 	bool logging_enabled = log_instance.getIsLoggingEnabled();
 	bool log_empty = log_instance.isLogEmpty();
@@ -238,8 +245,16 @@ void LLConversationLogList::rebuildList()
 
 void LLConversationLogList::onCustomAction(const LLSD& userdata)
 {
+	const LLConversation * selected_conversationp = getSelectedConversation();
+
+	if (NULL == selected_conversationp)
+	{
+		return;
+	}
+
 	const std::string command_name = userdata.asString();
-	const LLUUID& selected_id = getSelectedConversation()->getParticipantID();
+	const LLUUID& selected_conversation_participant_id = selected_conversationp->getParticipantID();
+	const LLUUID& selected_conversation_session_id = selected_conversationp->getSessionID();
 	LLIMModel::LLIMSession::SType stype = getSelectedSessionType();
 
 	if ("im" == command_name)
@@ -247,11 +262,11 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
 		switch (stype)
 		{
 		case LLIMModel::LLIMSession::P2P_SESSION:
-			LLAvatarActions::startIM(selected_id);
+			LLAvatarActions::startIM(selected_conversation_participant_id);
 			break;
 
 		case LLIMModel::LLIMSession::GROUP_SESSION:
-			LLGroupActions::startIM(getSelectedConversation()->getSessionID());
+			LLGroupActions::startIM(selected_conversation_session_id);
 			break;
 
 		default:
@@ -263,11 +278,11 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
 		switch (stype)
 		{
 		case LLIMModel::LLIMSession::P2P_SESSION:
-			LLAvatarActions::startCall(selected_id);
+			LLAvatarActions::startCall(selected_conversation_participant_id);
 			break;
 
 		case LLIMModel::LLIMSession::GROUP_SESSION:
-			LLGroupActions::startCall(getSelectedConversation()->getSessionID());
+			LLGroupActions::startCall(selected_conversation_session_id);
 			break;
 
 		default:
@@ -279,11 +294,11 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
 		switch (stype)
 		{
 		case LLIMModel::LLIMSession::P2P_SESSION:
-			LLAvatarActions::showProfile(selected_id);
+			LLAvatarActions::showProfile(selected_conversation_participant_id);
 			break;
 
 		case LLIMModel::LLIMSession::GROUP_SESSION:
-			LLGroupActions::show(getSelectedConversation()->getSessionID());
+			LLGroupActions::show(selected_conversation_session_id);
 			break;
 
 		default:
@@ -292,52 +307,53 @@ void LLConversationLogList::onCustomAction(const LLSD& userdata)
 	}
 	else if ("chat_history" == command_name)
 	{
-		const LLUUID& session_id = getSelectedConversation()->getSessionID();
-		LLFloaterReg::showInstance("preview_conversation", session_id, true);
+		LLFloaterReg::showInstance("preview_conversation", selected_conversation_session_id, true);
 	}
 	else if ("offer_teleport" == command_name)
 	{
-		LLAvatarActions::offerTeleport(selected_id);
+		LLAvatarActions::offerTeleport(selected_conversation_participant_id);
 	}
 	else if("add_friend" == command_name)
 	{
-		if (!LLAvatarActions::isFriend(selected_id))
+		if (!LLAvatarActions::isFriend(selected_conversation_participant_id))
 		{
-			LLAvatarActions::requestFriendshipDialog(selected_id);
+			LLAvatarActions::requestFriendshipDialog(selected_conversation_participant_id);
 		}
 	}
 	else if("remove_friend" == command_name)
 	{
-		if (LLAvatarActions::isFriend(selected_id))
+		if (LLAvatarActions::isFriend(selected_conversation_participant_id))
 		{
-			LLAvatarActions::removeFriendDialog(selected_id);
+			LLAvatarActions::removeFriendDialog(selected_conversation_participant_id);
 		}
 	}
 	else if ("invite_to_group" == command_name)
 	{
-		LLAvatarActions::inviteToGroup(selected_id);
+		LLAvatarActions::inviteToGroup(selected_conversation_participant_id);
 	}
 	else if ("show_on_map" == command_name)
 	{
-		LLAvatarActions::showOnMap(selected_id);
+		LLAvatarActions::showOnMap(selected_conversation_participant_id);
 	}
 	else if ("share" == command_name)
 	{
-		LLAvatarActions::share(selected_id);
+		LLAvatarActions::share(selected_conversation_participant_id);
 	}
 	else if ("pay" == command_name)
 	{
-		LLAvatarActions::pay(selected_id);
+		LLAvatarActions::pay(selected_conversation_participant_id);
 	}
 	else if ("block" == command_name)
 	{
-		LLAvatarActions::toggleBlock(selected_id);
+		LLAvatarActions::toggleBlock(selected_conversation_participant_id);
 	}
 }
 
 bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
 {
-	if (numSelected() != 1)
+	const LLConversation * selected_conversationp = getSelectedConversation();
+
+	if (NULL == selected_conversationp || numSelected() > 1)
 	{
 		return false;
 	}
@@ -345,7 +361,7 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
 	const std::string command_name = userdata.asString();
 
 	LLIMModel::LLIMSession::SType stype = getSelectedSessionType();
-	const LLUUID& selected_id = getSelectedConversation()->getParticipantID();
+	const LLUUID& selected_id = selected_conversationp->getParticipantID();
 
 	bool is_p2p   = LLIMModel::LLIMSession::P2P_SESSION == stype;
 	bool is_group = LLIMModel::LLIMSession::GROUP_SESSION == stype;
@@ -384,9 +400,16 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
 
 bool LLConversationLogList::isActionChecked(const LLSD& userdata)
 {
+	const LLConversation * selected_conversationp = getSelectedConversation();
+
+	if (NULL == selected_conversationp)
+	{
+		return false;
+	}
+
 	const std::string command_name = userdata.asString();
 
-	const LLUUID& selected_id = getSelectedConversation()->getParticipantID();
+	const LLUUID& selected_id = selected_conversationp->getParticipantID();
 	bool is_p2p = LLIMModel::LLIMSession::P2P_SESSION == getSelectedSessionType();
 
 	if ("is_blocked" == command_name)
-- 
cgit v1.2.3


From 6b067125a0d338c3acc6fd1c786620e474a80aa8 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 11 Mar 2013 14:49:24 -0700
Subject: CHUI-778: Adjusted text in prompts for deleting chat log and chat
 transcripts (per UX).

---
 indra/newview/llfloaterpreference.cpp                | 5 ++++-
 indra/newview/skins/default/xui/en/notifications.xml | 4 ++--
 2 files changed, 6 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3f8c23ba83..b308a820b2 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1667,7 +1667,10 @@ void LLFloaterPreference::onClickActionChange()
 
 void LLFloaterPreference::onDeleteTranscripts()
 {
-	LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", LLSD(), LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
+	LLSD args;
+	args["FOLDER"] = gDirUtilp->getUserName();
+
+	LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", args, LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
 }
 
 void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response)
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 88c02fc84e..c681e39002 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -9998,7 +9998,7 @@ Cannot create large prims that intersect other players.  Please re-try when othe
    icon="alertmodal.tga"
    name="PreferenceChatClearLog"
    type="alertmodal">
-    This will delete the log of previous conversations. Proceed?
+    This will delete the logs of previous conversations, and any backups of that file.
     <tag>confirm</tag>
     <usetemplate
      ignoretext="Confirm before I delete the log of previous conversations."
@@ -10011,7 +10011,7 @@ Cannot create large prims that intersect other players.  Please re-try when othe
    icon="alertmodal.tga"
    name="PreferenceChatDeleteTranscripts"
    type="alertmodal">
-    This will delete transcripts for all previous conversations. The list of conversations will not be affected. If you run scripts on your chat transcript files, you may want to proceed with caution. Proceed?
+    This will delete the transcripts for all previous conversations. The list of past conversations will not be affected. All files with the suffixes .txt and txt.backup in the folder [FOLDER] will be deleted.
     <tag>confirm</tag>
     <usetemplate
      ignoretext="Confirm before I delete transcripts."
-- 
cgit v1.2.3


From e5aa9088f01f8689e19be82e3caa56fffbab85c1 Mon Sep 17 00:00:00 2001
From: merov_linden <none@none>
Date: Mon, 11 Mar 2013 14:59:53 -0700
Subject: CHUI-810 : Merged Marine Kelley's patch on selected text and use of
 return key in chat

---
 indra/llui/llchatentry.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'indra')

diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
index 8e9c6555c3..9e48dcde7e 100644
--- a/indra/llui/llchatentry.cpp
+++ b/indra/llui/llchatentry.cpp
@@ -169,6 +169,15 @@ BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
 {
 	BOOL handled = FALSE;
 
+    // In the case of a chat entry, pressing RETURN when something is selected
+    // should NOT erase the selection (unlike a notecard, for example)
+    if (key == KEY_RETURN)
+    {
+        endOfDoc();
+        startSelection();
+        endSelection();
+    }
+
 	LLTextEditor::handleSpecialKey(key, mask);
 
 	switch(key)
-- 
cgit v1.2.3


From e7a4cce3566988d5b58dc070196a32844d705318 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Tue, 12 Mar 2013 00:41:35 +0200
Subject: CHUI-846 FIXED [crashhunters] crash in LLFontGL::maxDrawableChars

---
 indra/llrender/llfontgl.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 647512eb2e..8772779645 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -599,6 +599,11 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 		if(!fgi)
 		{
 			fgi = mFontFreetype->getGlyphInfo(wch);
+
+			if (NULL == fgi)
+			{
+				return 0;
+			}
 		}
 
 		// account for glyphs that run beyond the starting point for the next glyphs
-- 
cgit v1.2.3


From ac63601a2aeb05f67d6be87d7ad40495bbc3080b Mon Sep 17 00:00:00 2001
From: merov <none@none>
Date: Mon, 11 Mar 2013 21:32:40 -0700
Subject: CHUI-793 : Fixed! Introduced ChatLoadGroupTimeout and
 ChatLoadGroupMaxMembers to mitigate slow group loading.

---
 indra/newview/app_settings/settings.xml | 22 ++++++++++++++++++++++
 indra/newview/llspeakers.cpp            | 11 ++++++++---
 indra/newview/llspeakers.h              |  1 +
 3 files changed, 31 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 79376f7467..e216c7865d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1584,6 +1584,28 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>ChatLoadGroupMaxMembers</key>
+    <map>
+        <key>Comment</key>
+        <string>Max number of active members we'll show up for an unresponsive group</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>S32</string>
+        <key>Value</key>
+        <real>100</real>
+    </map>
+    <key>ChatLoadGroupTimeout</key>
+    <map>
+        <key>Comment</key>
+        <string>Time we give the server to send group participants before we hit the server for group info (seconds)</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>F32</string>
+        <key>Value</key>
+        <real>10.0</real>
+    </map>
     <key>ChatOnlineNotification</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 301b489c34..8783d99b11 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -38,6 +38,8 @@
 #include "llvoavatar.h"
 #include "llworld.h"
 
+extern LLControlGroup gSavedSettings;
+
 const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
 const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
 
@@ -311,6 +313,7 @@ LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) :
 	mModerateModeHandledFirstTime(false),
 	mSpeakerListUpdated(false)
 {
+    mGetListTime.reset();
 	static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
 
 	mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay);
@@ -537,18 +540,20 @@ void LLSpeakerMgr::updateSpeakerList()
 			LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
 			if (session->isGroupSessionType() && (mSpeakers.size() <= 1))
 			{
+                const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout");
 				// For groups, we need to hit the group manager.
 				// Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail.
 				LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id);
-				if (!gdatap)
+				if (!gdatap && (mGetListTime.getElapsedTimeF32() >= load_group_timeout))
 				{
 					// Request the data the first time around
 					LLGroupMgr::getInstance()->sendCapGroupMembersRequest(session_id);
 				}
-				else if (gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())
+				else if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())
 				{
 					// Add group members when we get the complete list (note: can take a while before we get that list)
 					LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin();
+                    const S32 load_group_max_members = gSavedSettings.getS32("ChatLoadGroupMaxMembers");
                     S32 updated = 0;
 					while (member_it != gdatap->mMembers.end())
 					{
@@ -564,7 +569,7 @@ void LLSpeakerMgr::updateSpeakerList()
 						++member_it;
                         // Limit the number of "manually updated" participants to a reasonable number to avoid severe fps drop
                         // *TODO : solve the perf issue of having several hundreds of widgets in the conversation list
-                        if (updated >= 100)
+                        if (updated >= load_group_max_members)
                             break;
 					}
                     mSpeakerListUpdated = true;
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 5f5095097e..e953dd0e1a 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -264,6 +264,7 @@ protected:
 	typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
 	speaker_map_t		mSpeakers;
 	bool                mSpeakerListUpdated;
+    LLTimer             mGetListTime;
 
 	speaker_list_t		mSpeakersSorted;
 	LLFrameTimer		mSpeechTimer;
-- 
cgit v1.2.3


From d81226f1707a93b6be52264fc00cae9c60057cc5 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Tue, 12 Mar 2013 15:38:10 +0200
Subject: CHUI-809 FIXED Changes in menu items to make them consistent. Do not
 start IM if selected person is self.

---
 indra/llui/lltextbase.cpp                          |  1 +
 indra/llui/llurlaction.cpp                         | 31 +++++++++++++++++-----
 indra/llui/llurlaction.h                           |  2 ++
 indra/newview/llavataractions.cpp                  |  2 +-
 indra/newview/llchathistory.cpp                    | 13 ++++++++-
 .../skins/default/xui/en/menu_object_icon.xml      | 18 +++++++++++++
 .../skins/default/xui/en/menu_url_agent.xml        | 17 ++++++++----
 .../skins/default/xui/en/menu_url_objectim.xml     |  2 +-
 8 files changed, 71 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index a1b6d61cda..0f6947ca19 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1919,6 +1919,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
 	registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
 	registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
+	registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
 	registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
 	registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
 	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index fd872eca4b..f51aeaec13 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -24,7 +24,6 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
-
 #include "linden_common.h"
 
 #include "llurlaction.h"
@@ -32,6 +31,7 @@
 #include "llwindow.h"
 #include "llurlregistry.h"
 
+
 // global state for the callback functions
 LLUrlAction::url_callback_t 		LLUrlAction::sOpenURLCallback;
 LLUrlAction::url_callback_t 		LLUrlAction::sOpenURLInternalCallback;
@@ -158,16 +158,33 @@ void LLUrlAction::showProfile(std::string url)
 	}
 }
 
-void LLUrlAction::sendIM(std::string url)
+std::string LLUrlAction::getUserID(std::string url)
 {
 	LLURI uri(url);
 	LLSD path_array = uri.pathArray();
+	std::string id_str;
 	if (path_array.size() == 4)
 	{
-		std::string id_str = path_array.get(2).asString();
-		if (LLUUID::validate(id_str))
-		{
-			executeSLURL("secondlife:///app/agent/" + id_str + "/im");
-		}
+		id_str = path_array.get(2).asString();
 	}
+	return id_str;
 }
+
+void LLUrlAction::sendIM(std::string url)
+{
+	std::string id_str = getUserID(url);
+	if (LLUUID::validate(id_str))
+	{
+		executeSLURL("secondlife:///app/agent/" + id_str + "/im");
+	}
+}
+
+void LLUrlAction::addFriend(std::string url)
+{
+	std::string id_str = getUserID(url);
+	if (LLUUID::validate(id_str))
+	{
+		executeSLURL("secondlife:///app/agent/" + id_str + "/requestfriend");
+	}
+}
+
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index f5f2ceba72..e31cd71a20 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -76,7 +76,9 @@ public:
 
 	/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
 	static void showProfile(std::string url);
+	static std::string getUserID(std::string url);
 	static void sendIM(std::string url);
+	static void addFriend(std::string url);
 
 	/// specify the callbacks to enable this class's functionality
 	typedef boost::function<void (const std::string&)> url_callback_t;
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index ce063a9887..b513a52ff7 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -193,7 +193,7 @@ static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
 // static
 void LLAvatarActions::startIM(const LLUUID& id)
 {
-	if (id.isNull())
+	if (id.isNull() || gAgent.getID() == id)
 		return;
 
 	LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_im, _1, _2));
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 0152571e20..53926c1fef 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -58,7 +58,7 @@
 #include "llworld.h"
 #include "lluiconstants.h"
 #include "llstring.h"
-
+#include "llurlaction.h"
 #include "llviewercontrol.h"
 
 static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
@@ -156,6 +156,17 @@ public:
 			LLFloaterSidePanelContainer::showPanel("people", "panel_people",
 				LLSD().with("people_panel_tab_name", "blocked_panel").with("blocked_to_select", getAvatarId()));
 		}
+		else if (level == "map")
+		{
+			std::string url = "secondlife://" + mObjectData["slurl"].asString();
+			LLUrlAction::showLocationOnMap(url);
+		}
+		else if (level == "teleport")
+		{
+			std::string url = "secondlife://" + mObjectData["slurl"].asString();
+			LLUrlAction::teleportToLocation(url);
+		}
+
 	}
 
 	void onAvatarIconContextMenuItemClicked(const LLSD& userdata)
diff --git a/indra/newview/skins/default/xui/en/menu_object_icon.xml b/indra/newview/skins/default/xui/en/menu_object_icon.xml
index 0c8a2af002..2d4f1792c2 100644
--- a/indra/newview/skins/default/xui/en/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_object_icon.xml
@@ -24,4 +24,22 @@
          function="ObjectIcon.Action"
          parameter="block" />
     </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Show on Map"
+     layout="topleft"
+     name="show_on_map">
+        <menu_item_call.on_click
+         function="ObjectIcon.Action" 
+         parameter="map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Teleport to Object Location"
+     layout="topleft"
+     name="teleport_to_object">
+        <menu_item_call.on_click
+         function="ObjectIcon.Action"
+         parameter="teleport" />
+    </menu_item_call>
 </menu>
diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml
index 88ae441bd3..7cd56f257a 100644
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -1,20 +1,27 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <context_menu
  layout="topleft"
- name="Url Popup">
+ name="Url Popup">  
     <menu_item_call
-     label="Send IM"
+     label="View Profile"
      layout="topleft"
      name="show_agent">
+        <menu_item_call.on_click
+         function="Url.ShowProfile" />         
+    </menu_item_call>
+    <menu_item_call
+     label="Send IM..."
+     layout="topleft"
+     name="send_im">
         <menu_item_call.on_click
          function="Url.SendIM" />        
     </menu_item_call>
     <menu_item_call
-     label="Show Resident Profile"
+     label="Add Friend..."
      layout="topleft"
-     name="show_agent">
+     name="add_friend">
         <menu_item_call.on_click
-         function="Url.ShowProfile" />
+         function="Url.AddFriend" />        
     </menu_item_call>
     <menu_item_separator
      layout="topleft" />
diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
index 35c2269b0d..87ab58e622 100644
--- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
@@ -3,7 +3,7 @@
  layout="topleft"
  name="Url Popup">
     <menu_item_call
-     label="Show Object Information"
+     label="Object Profile..."
      layout="topleft"
      name="show_object">
         <menu_item_call.on_click
-- 
cgit v1.2.3


From cb6574c905806feac3846733ca0ead77e431beb1 Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Tue, 12 Mar 2013 19:38:01 -0700
Subject: CHUI-845 : Avoid some xml param parsing error that seems to be linked
 with crashers

---
 indra/llui/lltextbase.cpp               | 1 -
 indra/llui/lltexteditor.cpp             | 1 -
 indra/newview/llfloaterimsessiontab.cpp | 1 +
 3 files changed, 1 insertion(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index a1b6d61cda..af29f3b56f 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -2337,7 +2337,6 @@ const LLWString& LLTextBase::getWText() const
 S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line) const
 {
 	// Figure out which line we're nearest to.
-	LLRect visible_region = getVisibleDocumentRect();
 	LLRect doc_rect = mDocumentView->getRect();
 
 	S32 doc_y = local_y - doc_rect.mBottom;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 2f120479d9..d5e08fa29b 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2515,7 +2515,6 @@ void LLTextEditor::updateSegments()
 		mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
 
 		clearSegments();
-		segment_set_t::iterator insert_it = mSegments.begin();
 		for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it)
 		{
 			insertSegment(*list_it);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index faeb860712..85b25afe43 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -253,6 +253,7 @@ BOOL LLFloaterIMSessionTab::postBuild()
     p.root = NULL;
     p.use_ellipses = true;
     p.options_menu = "menu_conversation.xml";
+    p.name = "root";
 	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
     mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 	// Attach that root to the scroller
-- 
cgit v1.2.3


From aa8809ff3b2f29ad2140328be955e338725d613b Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 12 Mar 2013 17:20:15 +0200
Subject: CHUI-831 Minimized conversation floater is not opened with Open
 Conversation Window preference if conversation receiving message is selected
 : force unminimized of the session's floater

---
 indra/newview/llimview.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 8f3f5145a9..37f5888e8c 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -285,6 +285,11 @@ void on_new_message(const LLSD& msg)
             {
 				//Surface conversations floater
 				LLFloaterReg::showInstance("im_container");
+
+				if (session_floater && session_floater->isMinimized())
+				{
+					LLFloater::onClickMinimize(session_floater);
+				}
 			}
 
             //If in DND mode, allow notification to be stored so upon DND exit 
-- 
cgit v1.2.3


From 212e21f3526d7d979a0950cc3c8c7ddaceef6cdc Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Tue, 12 Mar 2013 15:43:07 +0200
Subject: CHUI-847 Fixed [CHUIBUG]Collapse Participant List, operates on all
 torn off chats: make flag mIsPartListExpanded for saving of the participant
 list panel expand/collapse state

---
 indra/newview/llfloaterimsessiontab.cpp | 15 +++++++++++----
 indra/newview/llfloaterimsessiontab.h   |  1 +
 2 files changed, 12 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 85b25afe43..5fc7f46ca3 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -61,6 +61,7 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
   , mRefreshTimer(new LLTimer())
   , mIsHostAttached(false)
   , mHasVisibleBeenInitialized(false)
+  , mIsParticipantListExpanded(true)
 {
     setAutoFocus(FALSE);
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
@@ -180,6 +181,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 				// LLFloater::mLastHostHandle = floater_container (a "future" host)
 				conversp->setHost(floater_container);
 				conversp->setHost(NULL);
+
 				conversp->forceReshape();
 			}
 			// Added floaters share some state (like sort order) with their host
@@ -269,6 +271,12 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mRefreshTimer->setTimerExpirySec(0);
 	mRefreshTimer->start();
 	initBtns();
+
+	if (mIsParticipantListExpanded != gSavedSettings.getBOOL("IMShowControlPanel"))
+	{
+		LLFloaterIMSessionTab::onSlide(this);
+	}
+
 	return result;
 }
 
@@ -638,7 +646,7 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 	// Participant list should be visible only in torn off floaters.
 	bool is_participant_list_visible =
 			!is_not_torn_off
-			&& gSavedSettings.getBOOL("IMShowControlPanel")
+			&& mIsParticipantListExpanded
 			&& !mIsP2PChat;
 
 	mParticipantListPanel->setVisible(is_participant_list_visible);
@@ -769,9 +777,8 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
 
 			// Expand/collapse the IM control panel
 			self->mParticipantListPanel->setVisible(expand);
-
-			gSavedSettings.setBOOL("IMShowControlPanel", expand);
-
+            gSavedSettings.setBOOL("IMShowControlPanel", expand);
+            self->mIsParticipantListExpanded = expand;
 			self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon"));
 		}
 	}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index d55b021df7..e8ae557412 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -138,6 +138,7 @@ protected:
 
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
+	bool mIsParticipantListExpanded;
 
 	LLIMModel::LLIMSession* mSession;
 
-- 
cgit v1.2.3


From 3468d2d93b7ea3ec4a86445a6187aa6738d8fc16 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 13 Mar 2013 16:08:23 +0200
Subject: CHUI-816 [CHUIBUG]CHUI does not remember undocked state and position
 of Nearby Chat : canceled the erroneous torn-off/docked state saving when
 nearby chat is closes

---
 indra/newview/llfloaterimnearbychat.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index cfee5001a6..eb1a1f54ed 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -274,7 +274,7 @@ void LLFloaterIMNearbyChat::onTearOffClicked()
 	LLFloaterIMSessionTab::onTearOffClicked();
 
 	// see CHUI-170: Save torn-off state of the nearby chat between sessions
-	BOOL in_the_multifloater = !isTornOff();
+	BOOL in_the_multifloater = (BOOL)getHost();
 	gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
 }
 
@@ -297,8 +297,10 @@ void LLFloaterIMNearbyChat::onClose(bool app_quitting)
 void LLFloaterIMNearbyChat::onClickCloseBtn()
 {
 	if (!isTornOff())
+	{
 		return;
-	onTearOffClicked();
+	}
+	LLFloaterIMSessionTab::onTearOffClicked();
 	
 	LLFloaterIMContainer *im_box = LLFloaterIMContainer::findInstance();
 	if (im_box)
-- 
cgit v1.2.3


From 7e26f6a59e043fd22296452755d532e2a37b0399 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 13 Mar 2013 19:34:41 +0200
Subject: build fix

---
 indra/newview/llfloaterimsessiontab.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 5fc7f46ca3..9fd22b1537 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -272,7 +272,7 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mRefreshTimer->start();
 	initBtns();
 
-	if (mIsParticipantListExpanded != gSavedSettings.getBOOL("IMShowControlPanel"))
+	if (mIsParticipantListExpanded != (bool)gSavedSettings.getBOOL("IMShowControlPanel"))
 	{
 		LLFloaterIMSessionTab::onSlide(this);
 	}
-- 
cgit v1.2.3


From 5cddf709acb93a17059e5539258fc30b534a8e99 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Thu, 14 Mar 2013 22:34:15 +0100
Subject: CHUI-700 FIX [CHUIBUG]"Zoom in" feature for avatars has disappeared
 Disabled "Zoom In" menu item in the case where gObjectList.findObject()
 returns nothing

---
 indra/newview/llfloaterimcontainer.cpp |  7 ++++++-
 indra/newview/llpanelpeoplemenus.cpp   | 10 ++++++++--
 2 files changed, 14 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 53daaabe3d..e91717312e 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -53,6 +53,7 @@
 #include "llcallbacklist.h"
 #include "llworld.h"
 #include "llsdserialize.h"
+#include "llviewerobjectlist.h"
 
 //
 // LLFloaterIMContainer
@@ -1231,7 +1232,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
 	}
 
 	// Handle all other options
-	if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item) || ("can_zoom_in" == item))
+	if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
 	{
 		// Those menu items are enable only if a single avatar is selected
 		return is_single_select;
@@ -1261,6 +1262,10 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
     {
         return LLAvatarActions::canCall();
     }
+	else if ("can_zoom_in" == item)
+	{
+		return is_single_select && gObjectList.findObject(single_id);
+	}
     else if ("can_show_on_map" == item)
     {
         return (is_single_select ? (LLAvatarTracker::instance().isBuddyOnline(single_id) && is_agent_mappable(single_id)) || gAgent.isGodlike() : false);
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index aa14b74869..49f7361c4a 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -40,6 +40,7 @@
 #include "lllogchat.h"
 #include "llviewermenu.h"			// for gMenuHolder
 #include "llconversationmodel.h"
+#include "llviewerobjectlist.h"
 
 namespace LLPanelPeopleMenus
 {
@@ -212,6 +213,12 @@ bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata)
 	{
 		return LLAvatarActions::canCall();
 	}
+	else if (item == std::string("can_zoom_in"))
+	{
+		const LLUUID& id = mUUIDs.front();
+
+		return gObjectList.findObject(id);
+	}
 	else if (item == std::string("can_show_on_map"))
 	{
 		const LLUUID& id = mUUIDs.front();
@@ -228,8 +235,7 @@ bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata)
 		return LLLogChat::isTranscriptExist(mUUIDs.front());
 	}
 	else if (item == std::string("can_im") || item == std::string("can_invite") ||
-	         item == std::string("can_share") || item == std::string("can_pay") ||
-			 item == std::string("can_zoom_in"))
+	         item == std::string("can_share") || item == std::string("can_pay"))
 	{
 		return true;
 	}
-- 
cgit v1.2.3


From f0b1d1c7ea6e31e89165ff805bf2314767a7e23d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 14 Mar 2013 16:55:11 -0700
Subject: CHUI-853 (Crashing on ejecting member in group): Upon  receiving the
 rejection response message, the incorrect session id was being used to
 display the message. session_id was being used instead of new_session_id.

---
 indra/newview/llimview.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cd47a0c171..1d62a32fc2 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2638,7 +2638,7 @@ void LLIMMgr::addMessage(
 	if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
 	{
 		// Evaluate if we need to skip this message when that setting is true (default is false)
-		LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
+		LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(new_session_id);
 		skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL);	// Skip non friends...
 		skip_message &= !session->isGroupSessionType();			// Do not skip group chats...
 		skip_message &= !(other_participant_id == gAgentID);	// You are your best friend... Don't skip yourself
@@ -2654,7 +2654,7 @@ void LLIMMgr::addMessage(
     {
         LLFloaterReg::showInstance("im_container");
 	    LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->
-	    		flashConversationItemWidget(session_id, true);
+	    		flashConversationItemWidget(new_session_id, true);
     }
 }
 
-- 
cgit v1.2.3


From ee4fbb8e37ca20ebfbf85845dbb67941b7abfd29 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Fri, 15 Mar 2013 12:33:46 +0200
Subject: CHUI-830 FIXED Button for collapsing torn-off floater(to a single
 input line) is added. Show toasts for new messages for that conversation,
 regardless of other prefs.

---
 indra/newview/app_settings/settings.xml            |  11 ++
 indra/newview/llfloaterimnearbychat.cpp            |   1 +
 indra/newview/llfloaterimnearbychathandler.cpp     |  10 +-
 indra/newview/llfloaterimsession.cpp               |   2 +-
 indra/newview/llfloaterimsessiontab.cpp            |  82 +++++++++++++-
 indra/newview/llfloaterimsessiontab.h              |  15 +++
 indra/newview/llimview.cpp                         |   7 +-
 indra/newview/skins/default/textures/textures.xml  |   2 +
 .../skins/default/xui/en/floater_im_session.xml    | 123 ++++++++++++++++++---
 9 files changed, 227 insertions(+), 26 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index e216c7865d..ca6b9843fd 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4281,6 +4281,17 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>1</integer>
+    </map>
+     <key>IMShowContentPanel</key>
+    <map>
+      <key>Comment</key>
+      <string>Show Toolbar and Body Panels</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
     </map>
     <key>IgnoreAllNotifications</key>
     <map>
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index eb1a1f54ed..148f6a0609 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -290,6 +290,7 @@ void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
 void LLFloaterIMNearbyChat::onClose(bool app_quitting)
 {
 	// Override LLFloaterIMSessionTab::onClose() so that Nearby Chat is not removed from the conversation floater
+	LLFloaterIMSessionTab::restoreFloater();
 	onClickCloseBtn();
 }
 
diff --git a/indra/newview/llfloaterimnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
index 8870d54cd2..7afcf288ce 100644
--- a/indra/newview/llfloaterimnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -559,12 +559,14 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
 
     LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
 
-	if( nearby_chat->hasFocus() 
+	if(( nearby_chat->hasFocus()
         || im_box->hasFocus()
 		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") )
 		|| mChannel.isDead()
-		|| !mChannel.get()->getShowToasts() ) // to prevent toasts in Do Not Disturb mode
+		|| !mChannel.get()->getShowToasts() )
+		&& nearby_chat->isMessagePaneExpanded())
+		// to prevent toasts in Do Not Disturb mode
 		return;//no need in toast if chat is visible or if bubble chat is enabled
 
 	// arrange a channel on a screen
@@ -606,7 +608,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
 
 		//Don't show nearby toast, if conversation is visible but not focused
 		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(LLUUID());
-		if (session_floater
+		if (session_floater && session_floater->isMessagePaneExpanded()
 		    && session_floater->isInVisibleChain() && !session_floater->isMinimized()
 		    && !(session_floater->getHost() && session_floater->getHost()->isMinimized()))
 		{
@@ -614,7 +616,7 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
 		}
 
         //Will show toast when chat preference is set        
-        if(gSavedSettings.getString("NotificationNearbyChatOptions") == "toast")
+        if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !session_floater->isMessagePaneExpanded())
         {
             // Add a nearby chat toast.
             LLUUID id;
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 50b2ed8c51..733678364e 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -618,7 +618,7 @@ void LLFloaterIMSession::onClose(bool app_quitting)
 	// Last change:
 	// EXT-3516 X Button should end IM session, _ button should hide
 	gIMMgr->leaveSession(mSessionID);
-
+	LLFloaterIMSessionTab::restoreFloater();
 	// Clean up the conversation *after* the session has been ended
 	LLFloaterIMSessionTab::onClose(app_quitting);
 }
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 9fd22b1537..c744350dc6 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -194,19 +194,28 @@ BOOL LLFloaterIMSessionTab::postBuild()
 {
 	BOOL result;
 
+	mBodyStack = getChild<LLLayoutStack>("main_stack");
+
+
 	mCloseBtn = getChild<LLButton>("close_btn");
 	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
 
 	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
 	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onSlide, this));
 
+	mExpandCollapseLineBtn = getChild<LLButton>("minz_btn");
+	mExpandCollapseLineBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onCollapseToLine, this));
+
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
 
 	mGearBtn = getChild<LLButton>("gear_btn");
 
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
-	
+	mToolbarPanel = getChild<LLLayoutPanel>("toolbar_panel");
+	mContentPanel = getChild<LLLayoutPanel>("body_panel");
+	mInputButtonPanel = getChild<LLLayoutPanel>("input_button_layout_panel");
+	mInputButtonPanel->setVisible(false);
 	// Add a scroller for the folder (participant) view
 	LLRect scroller_view_rect = mParticipantListPanel->getRect();
 	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
@@ -264,6 +273,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mConversationsRoot->setFollowsAll();
 	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
 
+	setMessagePaneExpanded(true);
+
 	buildConversationViewParticipant();
 	refreshConversation();
 
@@ -651,6 +662,7 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 
 	mParticipantListPanel->setVisible(is_participant_list_visible);
 
+
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
 	bool is_expanded = is_not_torn_off || is_participant_list_visible;
@@ -674,6 +686,7 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 	mTearOffBtn->setImageOverlay(getString(is_not_torn_off? "tear_off_icon" : "return_icon"));
 	mTearOffBtn->setToolTip(getString(is_not_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
 
+
 	mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat);
 
 	enableDisableCallBtn();
@@ -784,6 +797,65 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
 	}
 }
 
+void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)
+{
+	LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost());
+	if (!host_floater)
+	{
+		if(self->mParticipantListPanel->getVisible())
+		{
+			onSlide(self);
+		}
+
+		bool expand = self->isMessagePaneExpanded();
+		self->mExpandCollapseLineBtn->setImageOverlay(self->getString(expand ? "collapseline_icon" : "expandline_icon"));
+		self->mContentPanel->setVisible(!expand);
+		self->mToolbarPanel->setVisible(!expand);
+		self->reshapeFloater(expand);
+		self->setMessagePaneExpanded(!expand);
+
+	}
+}
+
+void LLFloaterIMSessionTab::reshapeFloater(bool collapse)
+{
+	LLRect floater_rect = getRect();
+
+	if(collapse)
+	{
+		mFloaterHeight = floater_rect.getHeight();
+		S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight();
+		floater_rect.mTop -= height;
+		enableResizeCtrls(true, true, false);
+	}
+	else
+	{
+		floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
+		enableResizeCtrls(true, true, true);
+
+	}
+
+	setShape(floater_rect, true);
+	mBodyStack->updateLayout();
+
+}
+
+void LLFloaterIMSessionTab::restoreFloater()
+{
+	if(!isMessagePaneExpanded())
+	{
+		mContentPanel->setVisible(true);
+		mToolbarPanel->setVisible(true);
+		LLRect floater_rect = getRect();
+		floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
+		setShape(floater_rect, true);
+		mBodyStack->updateLayout();
+		mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));
+		setMessagePaneExpanded(true);
+		enableResizeCtrls(true, true, true);
+	}
+}
+
 /*virtual*/
 void LLFloaterIMSessionTab::onOpen(const LLSD& key)
 {
@@ -793,12 +865,15 @@ void LLFloaterIMSessionTab::onOpen(const LLSD& key)
 		// Show the messages pane when opening a floater hosted in the Conversations
 		host_floater->collapseMessagesPane(false);
 	}
+
+	mInputButtonPanel->setVisible(isTornOff());
 }
 
 
 void LLFloaterIMSessionTab::onTearOffClicked()
 {
-    setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
+	restoreFloater();
+	setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
     mSaveRect = isTornOff();
     initRectControl();
 	LLFloater::onClickTearOff(this);
@@ -813,7 +888,10 @@ void LLFloaterIMSessionTab::onTearOffClicked()
 	else
 	{
 		container->selectConversation(mSessionID);
+
 	}
+	mInputButtonPanel->setVisible(isTornOff());
+
 	refreshConversation();
 	updateGearBtn();
 }
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index e8ae557412..e41f639037 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -98,6 +98,8 @@ public:
 	LLConversationItem* getCurSelectedViewModelItem();
 	void forceReshape();
 	virtual BOOL handleKeyHere( KEY key, MASK mask );
+	bool isMessagePaneExpanded(){return mMessagePaneExpanded;}
+	void setMessagePaneExpanded(bool expanded){mMessagePaneExpanded = expanded;}
 
 protected:
 
@@ -111,6 +113,9 @@ protected:
 	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
 	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
 	static void onSlide(LLFloaterIMSessionTab *self);
+	static void onCollapseToLine(LLFloaterIMSessionTab *self);
+	void reshapeFloater(bool collapse);
+	void restoreFloater();
 
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
@@ -138,15 +143,22 @@ protected:
 
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
+
+	bool mMessagePaneExpanded;
 	bool mIsParticipantListExpanded;
 
+
 	LLIMModel::LLIMSession* mSession;
 
 	// Participants list: model and view
 	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
 	
 	LLUUID mSessionID; 
+	LLLayoutStack* mBodyStack;
 	LLLayoutPanel* mParticipantListPanel;	// add the widgets to that see mConversationsListPanel
+	LLLayoutPanel* mContentPanel;
+	LLLayoutPanel* mToolbarPanel;
+	LLLayoutPanel* mInputButtonPanel;
 	LLParticipantList* getParticipantList();
 	conversations_widgets_map mConversationsWidgets;
 	LLConversationViewModel mConversationViewModel;
@@ -158,11 +170,14 @@ protected:
 	LLChatEntry* mInputEditor;
 	int mInputEditorTopPad; // padding between input field and chat history
 
+	LLButton* mExpandCollapseLineBtn;
 	LLButton* mExpandCollapseBtn;
 	LLButton* mTearOffBtn;
 	LLButton* mCloseBtn;
 	LLButton* mGearBtn;
 
+	S32 mFloaterHeight;
+
 
 private:
 	// Handling selection and contextual menu
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 1d62a32fc2..d04e76c0b3 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -226,17 +226,18 @@ void on_new_message(const LLSD& msg)
             && !session_floater->isMinimized()
             && !(session_floater->getHost() && session_floater->getHost()->isMinimized());
 
-    if ("toast" == action && !session_floater_is_open)
+    bool conversation_floater_collapsed = !session_floater->isMessagePaneExpanded();
+    if (("toast" == action && !session_floater_is_open) || conversation_floater_collapsed)
     {
         //User is not focused on conversation containing the message
-        if(session_floater_not_focused)
+        if(session_floater_not_focused || conversation_floater_collapsed)
         {
         	if(!LLMuteList::getInstance()->isMuted(participant_id))
         	{
         		im_box->flashConversationItemWidget(session_id, true);
         	}
             //The conversation floater isn't focused/open
-            if(conversation_floater_not_focused)
+            if(conversation_floater_not_focused || conversation_floater_collapsed)
             {
             	if(!LLMuteList::getInstance()->isMuted(participant_id) 
                     && !gAgent.isDoNotDisturb())
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a07d7e4855..93c9cb02cb 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -171,6 +171,8 @@ with the same filename but different name
   <texture name="Conv_toolbar_call_log" file_name="icons/Conv_toolbar_call_log.png" preload="false" />
   <texture name="Conv_toolbar_close" file_name="icons/Conv_toolbar_close.png" preload="false" />
   <texture name="Conv_toolbar_collapse" file_name="icons/Conv_toolbar_collapse.png" preload="false" />
+  <texture name="Conv_collapse_to_one_line" file_name="icons/collapse_to_one_line.png" preload="false" />
+  <texture name="Conv_expand_one_line" file_name="icons/expand_one_liner.png" preload="false" />
   <texture name="Conv_toolbar_expand" file_name="icons/Conv_toolbar_expand.png" preload="false" />
   <texture name="Conv_toolbar_hang_up" file_name="icons/Conv_toolbar_hang_up.png" preload="false" />
   <texture name="Conv_toolbar_open_call" file_name="icons/Conv_toolbar_open_call.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 8f0574177f..1a9199f9e7 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -19,6 +19,12 @@
  positioning="relative">
     <floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string>
     <floater.string name="call_btn_stop">Conv_toolbar_hang_up</floater.string>
+    <floater.string
+     name="collapseline_icon"
+     value="Conv_collapse_to_one_line"/>
+    <floater.string
+     name="expandline_icon"
+     value="Conv_expand_one_line"/>
     <floater.string
      name="collapse_icon"
      value="Conv_toolbar_collapse"/>
@@ -65,14 +71,28 @@
         top="0"
         left="0"
         height="355"
-        width="394"> 
-     <panel
+        width="394">
+   <layout_stack
+   animate="true" 
+   default_tab_group="2"
+   follows="all"
+  height="355"
+  width="394"
+  layout="topleft"
+  orientation="vertical"
+   name="main_stack"
+  tab_group="1"
+  top="0"
+  left="0">
+  
+     <layout_panel
          follows="left|top|right"
          layout="topleft"
          name="toolbar_panel"
          top="0"
          left="0"
          height="35"
+         min_height="35"
          width="394">         
              <menu_button
                  menu_filename="menu_im_session_showmodes.xml"
@@ -180,12 +200,19 @@
                  left_pad="5"
                  name="tear_off_btn"
                  width="31" />
-     </panel>
+     </layout_panel>
+     <layout_panel
+      name="body_panel"
+      follows="all"
+      width="394" 
+      height="235" 
+      user_resize="false"
+      auto_resize="true">
   <layout_stack
    animate="true" 
    default_tab_group="2"
   follows="all"
-  height="310"
+  height="275"
   width="394"
   layout="topleft"
   orientation="horizontal"
@@ -198,7 +225,7 @@
       follows="all"
       min_width="115"
       width="150" 
-      height="310" 
+      height="275" 
       user_resize="true"
       auto_resize="true">
       </layout_panel>
@@ -208,7 +235,7 @@
        tab_group="2"
        follows="all"
        top="0"
-       height="310"
+       height="275"
 	   width="244"
        layout="topleft"
        user_resize="true"
@@ -221,13 +248,13 @@
          follows="all"
          layout="topleft"
          visible="true"
-         height="275"
+         height="240"
          width="244">
          <layout_stack
           animate="true" 
           default_tab_group="2"
           follows="all"
-          height="275"
+          height="240"
           width="244"
           layout="topleft"
           visible="true"
@@ -258,7 +285,7 @@
                  width="230" />
             </layout_panel>
             <layout_panel
-             height="248"
+             height="233"
              width="210"
              layout="topleft"
              follows="all"
@@ -273,7 +300,7 @@
                 font="SansSerifSmall"
                 follows="all"
                 visible="true"
-                height="240"
+                height="225"
                 name="chat_history"
                 parse_highlights="true"
                 parse_urls="true"
@@ -283,26 +310,90 @@
             </layout_panel>
            </layout_stack>
            </panel>
-            <chat_editor
+    </layout_panel>
+  </layout_stack>
+  </layout_panel>
+  <layout_panel
+             height="35"
+             layout="topleft"
+             follows="left|right|bottom"
+             left_delta="0"
+             right="0"
+             top_delta="0"
              bottom="0"
+             visible="true"
+             user_resize="false"
+             auto_resize="false"
+             name="chat_layout_panel">
+   <layout_stack
+   animate="true" 
+   default_tab_group="2"
+   follows="all"
+   height="35"
+   right="0"
+   layout="topleft"
+   orientation="horizontal"
+   name="input_panels"
+   top_pad="0"
+   left="0">
+     <layout_panel
+             height="35"
+             layout="topleft"
+             follows="left|right|bottom"
+             left_delta="0"
+             top_delta="0"
+             bottom="0"
+             visible="true"
+             user_resize="false"
+             auto_resize="true"
+             name="input_editor_layout_panel">
+              <chat_editor
+             top="6"
              expand_lines_count="5"
              follows="left|right|bottom"
-	           font="SansSerifSmall"
+               font="SansSerifSmall"
              visible="true"
              height="20"
              is_expandable="true"
              label="To"
              text_tentative_color="TextFgTentativeColor"
-             layout="bottomleft"
+             layout="topleft"
              name="chat_editor"
              max_length="1023"
              spellcheck="true"
              tab_group="3"
-             width="220"
-             left="10"
+             width="160"
+             left="5"
+             right="-5"
              wrap="true">
             </chat_editor>
-    </layout_panel>
+            </layout_panel>
+            <layout_panel             
+             height="35"
+             layout="topleft"
+             follows="left|right|bottom"
+             left_delta="0"
+             top_delta="0"
+             bottom="0"
+             width="35"
+             visible="true"
+             user_resize="false"
+             auto_resize="false"
+             name="input_button_layout_panel">
+            <button
+                 follows="left|right|bottom"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_expand_one_line"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 name="minz_btn"
+                 tool_tip="Shows/hides message panel"
+                 width="28"/>
+           </layout_panel>
+  </layout_stack>
+  </layout_panel>
   </layout_stack>
     </view>
 </floater>
-- 
cgit v1.2.3


From a5a9bd791c910314888b8dad84cd711993c60a40 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 15 Mar 2013 16:04:09 +0200
Subject: CHUI-816 [CHUIBUG]CHUI does not remember undocked state and position
 of Nearby Chat

---
 indra/newview/app_settings/settings.xml             | 11 -----------
 indra/newview/app_settings/settings_per_account.xml | 11 +++++++++++
 indra/newview/llfloaterimnearbychat.cpp             |  4 ++--
 indra/newview/llfloaterimsessiontab.cpp             |  4 ++--
 4 files changed, 15 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ca6b9843fd..4c305e1d60 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1716,17 +1716,6 @@
       <key>Value</key>
       <integer>131073</integer>
     </map>
-    <key>NearbyChatIsNotTornOff</key>
-    <map>
-      <key>Comment</key>
-      <string>saving torn-off state of the nearby chat between sessions</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
     <key>CloseChatOnReturn</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 363713f2f4..47137c8de9 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -281,6 +281,17 @@
       	<key>Value</key>
       		<integer>2</integer>
     	</map>    
+    <key>NearbyChatIsNotTornOff</key>
+    <map>
+      <key>Comment</key>
+      <string>saving torn-off state of the nearby chat between sessions</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>ShowFavoritesOnLogin</key>
         <map>
         <key>Comment</key>
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 148f6a0609..a593fd4732 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -275,7 +275,7 @@ void LLFloaterIMNearbyChat::onTearOffClicked()
 
 	// see CHUI-170: Save torn-off state of the nearby chat between sessions
 	BOOL in_the_multifloater = (BOOL)getHost();
-	gSavedSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
+	gSavedPerAccountSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
 }
 
 
@@ -337,7 +337,7 @@ bool LLFloaterIMNearbyChat::isChatVisible() const
 	if (im_box != NULL)
 	{
 		isVisible =
-				isChatMultiTab() && gSavedSettings.getBOOL("NearbyChatIsNotTornOff")?
+				isChatMultiTab() && gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff")?
 						im_box->getVisible() && !im_box->isMinimized() :
 						getVisible() && !isMinimized();
 	}
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index c744350dc6..cfd239c22f 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -170,7 +170,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 			conversp->setHostAttached(true);
 
 			if (!conversp->isNearbyChat()
-					|| gSavedSettings.getBOOL("NearbyChatIsNotTornOff"))
+					|| gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff"))
 			{
 				floater_container->addFloater(conversp, false, LLTabContainer::RIGHT_OF_CURRENT);
 			}
@@ -242,7 +242,7 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 
 	mSaveRect = isNearbyChat()
-					&&  !gSavedSettings.getBOOL("NearbyChatIsNotTornOff");
+					&&  !gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff");
 	initRectControl();
 
 	if (isChatMultiTab())
-- 
cgit v1.2.3


From bd8b0de8970387d2660af10220bbe53901c4aaed Mon Sep 17 00:00:00 2001
From: alexanderpproductengine <alexanderpproductengine@lindenlab.com>
Date: Wed, 13 Mar 2013 22:18:41 +0200
Subject: CHUI-831 ADD FIX Minimized conversation floater is not opened with
 Open Conversation Window preference if conversation receiving message is
 selected

---
 indra/newview/llimview.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d04e76c0b3..a266f06a20 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -199,13 +199,13 @@ void on_new_message(const LLSD& msg)
     // execution of the action
 
     LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
-
-	if (im_box->isFrontmost() && im_box->getSelectedSession() == session_id)
+	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+	
+	if (im_box->isFrontmost() && im_box->getSelectedSession() == session_id
+		&& !(session_floater->getHost() ? im_box->isMinimized() : session_floater->isMinimized()))
 	{
 		return;
 	}
-
-	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 	
     //session floater not focused (visible or not)
     bool session_floater_not_focused = session_floater && !session_floater->hasFocus();
-- 
cgit v1.2.3


From d37b3ca62ea5d1f2d3cd57909d77c42227024c0f Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Wed, 13 Mar 2013 13:40:26 -0700
Subject: CHUI-839 : Fixed! Make the LLLineEditor in chat preferences read-only
 but selectable

---
 indra/newview/llfloaterpreference.cpp                         | 3 ++-
 indra/newview/skins/default/xui/en/panel_preferences_chat.xml | 1 -
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index b308a820b2..a28af2101b 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -443,6 +443,8 @@ BOOL LLFloaterPreference::postBuild()
 	std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
 	setCacheLocation(cache_location);
 
+	getChild<LLUICtrl>("log_path_string")->setEnabled(FALSE); // make it read-only but selectable
+
 	getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
 
 	getChild<LLComboBox>("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions"));
@@ -1572,7 +1574,6 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	getChildView("send_im_to_email")->setEnabled(TRUE);
 	getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
 	getChildView("favorites_on_login_check")->setEnabled(TRUE);
-	getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
 	getChildView("log_path_button")->setEnabled(TRUE);
 	getChildView("chat_font_size")->setEnabled(TRUE);
 }
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 9db3816c92..bd096ebb88 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -429,7 +429,6 @@
     </text>
   
     <line_editor
-    	enabled="false"
         control_name="InstantMessageLogPath"
         border_style="line"
         border_thickness="1"
-- 
cgit v1.2.3


From 8904f32ba48b49ec216a3ca3b1508d5f3f633e78 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 13 Mar 2013 23:01:10 +0200
Subject: CHUI-796 FIXED User doesn't get all messages in 'do not disturb' mode

---
 indra/newview/llviewermessage.cpp | 113 ++++++++++++++++++++++++--------------
 1 file changed, 71 insertions(+), 42 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 2340436a01..a13c793899 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2382,7 +2382,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	    LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
 		break;
 
-	case IM_NOTHING_SPECIAL: 
+	case IM_NOTHING_SPECIAL:	// p2p IM
 		// Don't show dialog, just do IM
 		if (!gAgent.isGodlike()
 				&& gAgent.getRegion()->isPrelude() 
@@ -2783,47 +2783,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	}
 	break;
 	
-	case IM_SESSION_SEND:
-	{
-		if (is_do_not_disturb)
-		{
-			return;
-		}
-
-		// Only show messages if we have a session open (which
-		// should happen after you get an "invitation"
-		if ( !gIMMgr->hasSession(session_id) )
-		{
-			return;
-		}
-
-		// standard message, not from system
-		std::string saved;
-		if(offline == IM_OFFLINE)
-		{
-			saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
-		}
-		buffer = saved + message;
-		BOOL is_this_agent = FALSE;
-		if(from_id == gAgentID)
-		{
-			is_this_agent = TRUE;
-		}
-		gIMMgr->addMessage(
-			session_id,
-			from_id,
-			name,
-			buffer,
-			IM_OFFLINE == offline,
-			ll_safe_string((char*)binary_bucket),
-			IM_SESSION_INVITE,
-			parent_estate_id,
-			region_id,
-			position,
-			true);
-	}
-	break;
-
 	case IM_FROM_TASK:
 		{
 			if (is_do_not_disturb && !is_owned_by_me)
@@ -2922,6 +2881,76 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			LLPostponedNotification::add<LLPostponedServerObjectNotification>(params, from_id, from_group);
 		}
 		break;
+
+	case IM_SESSION_SEND:		// ad-hoc or group IMs
+
+		// Only show messages if we have a session open (which
+		// should happen after you get an "invitation"
+		if ( !gIMMgr->hasSession(session_id) )
+		{
+			return;
+		}
+
+		else if (offline == IM_ONLINE && is_do_not_disturb)
+		{
+
+			// return a standard "do not disturb" message, but only do it to online IM 
+			// (i.e. not other auto responses and not store-and-forward IM)
+			if (!gIMMgr->hasSession(session_id))
+			{
+				// if there is not a panel for this conversation (i.e. it is a new IM conversation
+				// initiated by the other party) then...
+				send_do_not_disturb_message(msg, from_id, session_id);
+			}
+
+			// now store incoming IM in chat history
+
+			buffer = message;
+	
+			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+			// add to IM panel, but do not bother the user
+			gIMMgr->addMessage(
+				session_id,
+				from_id,
+				name,
+				buffer,
+				IM_OFFLINE == offline,
+				ll_safe_string((char*)binary_bucket),
+				IM_SESSION_INVITE,
+				parent_estate_id,
+				region_id,
+				position,
+				true);
+		}
+		else
+		{
+			// standard message, not from system
+			std::string saved;
+			if(offline == IM_OFFLINE)
+			{
+				saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
+			}
+
+			buffer = saved + message;
+
+			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+			gIMMgr->addMessage(
+				session_id,
+				from_id,
+				name,
+				buffer,
+				IM_OFFLINE == offline,
+				ll_safe_string((char*)binary_bucket),
+				IM_SESSION_INVITE,
+				parent_estate_id,
+				region_id,
+				position,
+				true);
+		}
+		break;
+
 	case IM_FROM_TASK_AS_ALERT:
 		if (is_do_not_disturb && !is_owned_by_me)
 		{
-- 
cgit v1.2.3


From 8b388922434e431c49b9e7f2c9d1e8d90d15ed21 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Thu, 14 Mar 2013 01:28:40 +0100
Subject: CHUI-700 FIX [CHUIBUG]"Zoom in" feature for avatars has disappeared
 Added "Zoom In" context menu item to Nearby Chat list in People floater and
 Conversation floater

---
 indra/newview/llconversationloglist.cpp            |   2 +-
 indra/newview/llconversationmodel.cpp              |   2 +
 indra/newview/llfloaterimcontainer.cpp             |   6 +-
 indra/newview/llpanelpeople.cpp                    |  13 ++-
 indra/newview/llpanelpeoplemenus.cpp               | 114 ++++++++++++++++++---
 indra/newview/llpanelpeoplemenus.h                 |  20 +++-
 .../skins/default/xui/en/menu_conversation.xml     |   9 +-
 .../skins/default/xui/en/menu_im_conversation.xml  |   7 ++
 .../skins/default/xui/en/menu_people_nearby.xml    |  40 +++++---
 .../xui/en/menu_people_nearby_multiselect.xml      |  14 +--
 10 files changed, 178 insertions(+), 49 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
index b202cfc9d3..5ab108b39f 100644
--- a/indra/newview/llconversationloglist.cpp
+++ b/indra/newview/llconversationloglist.cpp
@@ -390,7 +390,7 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
 	{
 		return is_p2p && LLAvatarActions::canOfferTeleport(selected_id);
 	}
-	else if ("can_show_on_map")
+	else if ("can_show_on_map" == command_name)
 	{
 		return is_p2p && ((LLAvatarTracker::instance().isBuddyOnline(selected_id) && is_agent_mappable(selected_id)) || gAgent.isGodlike());
 	}
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 009fce0a92..c74ce24872 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -139,6 +139,8 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32
 		items.push_back(std::string("remove_friend"));
 		items.push_back(std::string("invite_to_group"));
 		items.push_back(std::string("separator_invite_to_group"));
+		if (static_cast<LLConversationItem*>(mParent)->getType() == CONV_SESSION_NEARBY)
+			items.push_back(std::string("zoom_in"));
 		items.push_back(std::string("map"));
 		items.push_back(std::string("share"));
 		items.push_back(std::string("pay"));
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 7437dd8cda..53daaabe3d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1036,6 +1036,10 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec
 		{
 			LLAvatarActions::inviteToGroup(userID);
 		}
+		else if ("zoom_in" == command)
+		{
+			handle_zoom_to_object(userID);
+		}
 		else if ("map" == command)
 		{
 			LLAvatarActions::showOnMap(userID);
@@ -1227,7 +1231,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
 	}
 
 	// Handle all other options
-	if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+	if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item) || ("can_zoom_in" == item))
 	{
 		// Those menu items are enable only if a single avatar is selected
 		return is_single_select;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index c5283404f1..4138558bad 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -611,10 +611,10 @@ BOOL LLPanelPeople::postBuild()
 	mGroupList->setNoItemsMsg(getString("no_groups_msg"));
 	mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg"));
 
-	mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
-	mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
-	mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
-	mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
+	mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyPeopleContextMenu);
+	mRecentList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
+	mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
+	mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
 
 	setSortOrder(mRecentList,		(ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"),	false);
 	setSortOrder(mAllFriendList,	(ESortOrder)gSavedSettings.getU32("FriendsSortOrder"),		false);
@@ -1143,7 +1143,10 @@ void LLPanelPeople::onGearButtonClicked(LLUICtrl* btn)
 	uuid_vec_t selected_uuids;
 	getCurrentItemIDs(selected_uuids);
 	// Spawn at bottom left corner of the button.
-	LLPanelPeopleMenus::gNearbyMenu.show(btn, selected_uuids, 0, 0);
+	if (getActiveTabName() == NEARBY_TAB_NAME)
+		LLPanelPeopleMenus::gNearbyPeopleContextMenu.show(btn, selected_uuids, 0, 0);
+	else
+		LLPanelPeopleMenus::gPeopleContextMenu.show(btn, selected_uuids, 0, 0);
 }
 
 void LLPanelPeople::onImButtonClicked()
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 47d6b49a50..aa14b74869 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -39,15 +39,17 @@
 #include "llcallingcard.h"			// for LLAvatarTracker
 #include "lllogchat.h"
 #include "llviewermenu.h"			// for gMenuHolder
+#include "llconversationmodel.h"
 
 namespace LLPanelPeopleMenus
 {
 
-NearbyMenu gNearbyMenu;
+PeopleContextMenu gPeopleContextMenu;
+NearbyPeopleContextMenu gNearbyPeopleContextMenu;
 
-//== NearbyMenu ===============================================================
+//== PeopleContextMenu ===============================================================
 
-LLContextMenu* NearbyMenu::createMenu()
+LLContextMenu* PeopleContextMenu::createMenu()
 {
 	// set up the callbacks for all of the avatar menu items
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
@@ -64,7 +66,8 @@ LLContextMenu* NearbyMenu::createMenu()
 		registrar.add("Avatar.RemoveFriend",	boost::bind(&LLAvatarActions::removeFriendDialog, 		id));
 		registrar.add("Avatar.IM",				boost::bind(&LLAvatarActions::startIM,					id));
 		registrar.add("Avatar.Call",			boost::bind(&LLAvatarActions::startCall,				id));
-		registrar.add("Avatar.OfferTeleport",	boost::bind(&NearbyMenu::offerTeleport,					this));
+		registrar.add("Avatar.OfferTeleport",	boost::bind(&PeopleContextMenu::offerTeleport,			this));
+		registrar.add("Avatar.ZoomIn",			boost::bind(&handle_zoom_to_object,						id));
 		registrar.add("Avatar.ShowOnMap",		boost::bind(&LLAvatarActions::showOnMap,				id));
 		registrar.add("Avatar.Share",			boost::bind(&LLAvatarActions::share,					id));
 		registrar.add("Avatar.Pay",				boost::bind(&LLAvatarActions::pay,						id));
@@ -72,33 +75,72 @@ LLContextMenu* NearbyMenu::createMenu()
 		registrar.add("Avatar.InviteToGroup",	boost::bind(&LLAvatarActions::inviteToGroup,			id));
 		registrar.add("Avatar.Calllog",			boost::bind(&LLAvatarActions::viewChatHistory,			id));
 
-		enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem,	this, _2));
-		enable_registrar.add("Avatar.CheckItem",  boost::bind(&NearbyMenu::checkContextMenuItem,	this, _2));
+		enable_registrar.add("Avatar.EnableItem", boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2));
+		enable_registrar.add("Avatar.CheckItem",  boost::bind(&PeopleContextMenu::checkContextMenuItem,	this, _2));
 
 		// create the context menu from the XUI
 		menu = createFromFile("menu_people_nearby.xml");
+		buildContextMenu(*menu, 0x0);
 	}
 	else
 	{
 		// Set up for multi-selected People
 
 		// registrar.add("Avatar.AddFriend",	boost::bind(&LLAvatarActions::requestFriendshipDialog,	mUUIDs)); // *TODO: unimplemented
-		registrar.add("Avatar.IM",			boost::bind(&LLAvatarActions::startConference,			mUUIDs, LLUUID::null));
-		registrar.add("Avatar.Call",		boost::bind(&LLAvatarActions::startAdhocCall,			mUUIDs, LLUUID::null));
-		registrar.add("Avatar.OfferTeleport",	boost::bind(&NearbyMenu::offerTeleport,					this));
-		registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog,		mUUIDs));
+		registrar.add("Avatar.IM",				boost::bind(&LLAvatarActions::startConference,			mUUIDs, LLUUID::null));
+		registrar.add("Avatar.Call",			boost::bind(&LLAvatarActions::startAdhocCall,			mUUIDs, LLUUID::null));
+		registrar.add("Avatar.OfferTeleport",	boost::bind(&PeopleContextMenu::offerTeleport,			this));
+		registrar.add("Avatar.RemoveFriend",	boost::bind(&LLAvatarActions::removeFriendsDialog,		mUUIDs));
 		// registrar.add("Avatar.Share",		boost::bind(&LLAvatarActions::startIM,					mUUIDs)); // *TODO: unimplemented
-		// registrar.add("Avatar.Pay",		boost::bind(&LLAvatarActions::pay,						mUUIDs)); // *TODO: unimplemented
-		enable_registrar.add("Avatar.EnableItem",	boost::bind(&NearbyMenu::enableContextMenuItem,	this, _2));
+		// registrar.add("Avatar.Pay",			boost::bind(&LLAvatarActions::pay,						mUUIDs)); // *TODO: unimplemented
+		
+		enable_registrar.add("Avatar.EnableItem",	boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2));
 
 		// create the context menu from the XUI
 		menu = createFromFile("menu_people_nearby_multiselect.xml");
+		buildContextMenu(*menu, ITEM_IN_MULTI_SELECTION);
 	}
 
     return menu;
 }
 
-bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
+void PeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
+{
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+	
+	if (flags & ITEM_IN_MULTI_SELECTION)
+	{
+		items.push_back(std::string("add_friends"));
+		items.push_back(std::string("remove_friends"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("call"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("offer_teleport"));
+	}
+	else 
+	{
+		items.push_back(std::string("view_profile"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("chat_history"));
+		items.push_back(std::string("separator_chat_history"));
+		items.push_back(std::string("add_friend"));
+		items.push_back(std::string("remove_friend"));
+		items.push_back(std::string("invite_to_group"));
+		items.push_back(std::string("separator_invite_to_group"));
+		items.push_back(std::string("map"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("block_unblock"));
+	}
+
+    hide_context_entries(menu, items, disabled_items);
+}
+
+bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata)
 {
 	if(gAgent.getID() == mUUIDs.front())
 	{
@@ -186,14 +228,15 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
 		return LLLogChat::isTranscriptExist(mUUIDs.front());
 	}
 	else if (item == std::string("can_im") || item == std::string("can_invite") ||
-	         item == std::string("can_share") || item == std::string("can_pay"))
+	         item == std::string("can_share") || item == std::string("can_pay") ||
+			 item == std::string("can_zoom_in"))
 	{
 		return true;
 	}
 	return false;
 }
 
-bool NearbyMenu::checkContextMenuItem(const LLSD& userdata)
+bool PeopleContextMenu::checkContextMenuItem(const LLSD& userdata)
 {
 	std::string item = userdata.asString();
 	const LLUUID& id = mUUIDs.front();
@@ -206,11 +249,50 @@ bool NearbyMenu::checkContextMenuItem(const LLSD& userdata)
 	return false;
 }
 
-void NearbyMenu::offerTeleport()
+void PeopleContextMenu::offerTeleport()
 {
 	// boost::bind cannot recognize overloaded method LLAvatarActions::offerTeleport(),
 	// so we have to use a wrapper.
 	LLAvatarActions::offerTeleport(mUUIDs);
 }
 
+//== NearbyPeopleContextMenu ===============================================================
+
+void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
+{
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+	
+	if (flags & ITEM_IN_MULTI_SELECTION)
+	{
+		items.push_back(std::string("add_friends"));
+		items.push_back(std::string("remove_friends"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("call"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("offer_teleport"));
+	}
+	else 
+	{
+		items.push_back(std::string("view_profile"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("chat_history"));
+		items.push_back(std::string("separator_chat_history"));
+		items.push_back(std::string("add_friend"));
+		items.push_back(std::string("remove_friend"));
+		items.push_back(std::string("invite_to_group"));
+		items.push_back(std::string("separator_invite_to_group"));
+		items.push_back(std::string("zoom_in"));
+		items.push_back(std::string("map"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("block_unblock"));
+	}
+
+    hide_context_entries(menu, items, disabled_items);
+}
+
 } // namespace LLPanelPeopleMenus
diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h
index d51eaec716..0a1dcef303 100644
--- a/indra/newview/llpanelpeoplemenus.h
+++ b/indra/newview/llpanelpeoplemenus.h
@@ -33,19 +33,33 @@ namespace LLPanelPeopleMenus
 {
 
 /**
- * Menu used in the nearby people list.
+ * Menu used in the people lists.
  */
-class NearbyMenu : public LLListContextMenu
+class PeopleContextMenu : public LLListContextMenu
 {
 public:
 	/*virtual*/ LLContextMenu* createMenu();
+
+protected:
+	virtual void buildContextMenu(class LLMenuGL& menu, U32 flags);
+
 private:
 	bool enableContextMenuItem(const LLSD& userdata);
 	bool checkContextMenuItem(const LLSD& userdata);
 	void offerTeleport();
 };
 
-extern NearbyMenu gNearbyMenu;
+/**
+ * Menu used in the nearby people list.
+ */
+class NearbyPeopleContextMenu : public PeopleContextMenu
+{
+protected:
+	/*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
+};
+
+extern PeopleContextMenu gPeopleContextMenu;
+extern NearbyPeopleContextMenu gNearbyPeopleContextMenu;
 
 } // namespace LLPanelPeopleMenus
 
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index fd5c86b3ca..5a13ef0a59 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -89,7 +89,14 @@
         <on_click function="Avatar.DoToSelected" parameter="invite_to_group" />
         <on_enable function="Avatar.EnableItem" parameter="can_invite" />
     </menu_item_call>
-    <menu_item_separator layout="topleft" name="separator_invite_to_group"/>		
+    <menu_item_separator layout="topleft" name="separator_invite_to_group"/>
+    <menu_item_call
+     label="Zoom In"
+     layout="topleft"
+     name="zoom_in">
+      <on_click function="Avatar.DoToSelected" parameter="zoom_in" />
+      <on_enable function="Avatar.EnableItem" parameter="can_zoom_in" />
+    </menu_item_call>
     <menu_item_call
      label="Map"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
index 8882d0a7d8..43287c6ec3 100644
--- a/indra/newview/skins/default/xui/en/menu_im_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -49,6 +49,13 @@
     </menu_item_call>
     <menu_item_separator
      layout="topleft"/>
+    <menu_item_call
+       label="Zoom In"
+       layout="topleft"
+       name="zoom_in">
+      <on_click function="Avatar.DoToSelected" parameter="zoom_in" />
+      <on_enable function="Avatar.EnableItem" parameter="can_zoom_in" />
+    </menu_item_call>
     <menu_item_call
      label="Map"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
index 60a6c98514..3abb5f7bc8 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -1,18 +1,18 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <context_menu
  layout="topleft"
- name="Avatar Context Menu">
+ name="Nearby People Context Menu">
     <menu_item_call
      label="View Profile"
      layout="topleft"
-     name="View Profile">
+     name="view_profile">
         <menu_item_call.on_click
          function="Avatar.Profile" />
     </menu_item_call>
     <menu_item_call
      label="IM"
      layout="topleft"
-     name="IM">
+     name="im">
         <menu_item_call.on_click
          function="Avatar.IM" />
         <menu_item_call.on_enable
@@ -21,7 +21,7 @@
     </menu_item_call>
     <menu_item_call
     label="Offer Teleport"
-    name="teleport">
+    name="offer_teleport">
       <menu_item_call.on_click
        function="Avatar.OfferTeleport"/>
       <menu_item_call.on_enable
@@ -31,7 +31,7 @@
     <menu_item_call
      label="Voice call"
      layout="topleft"
-     name="Call">
+     name="voice_call">
         <menu_item_call.on_click
          function="Avatar.Call" />
         <menu_item_call.on_enable
@@ -42,18 +42,18 @@
     <menu_item_call
      label="View chat history..."
      layout="topleft"
-     name="Chat history">
+     name="chat_history">
         <menu_item_call.on_click
          function="Avatar.Calllog" />
         <menu_item_call.on_enable
       	 function="Avatar.EnableItem"
          parameter="can_callog"/>
     </menu_item_call>
-    <menu_item_separator />
+    <menu_item_separator name="separator_chat_history"/>
     <menu_item_call
      label="Add Friend"
      layout="topleft"
-     name="Add Friend">
+     name="add_friend">
         <menu_item_call.on_click
          function="Avatar.AddFriend" />
         <menu_item_call.on_visible
@@ -63,7 +63,7 @@
     <menu_item_call
      label="Remove Friend"
      layout="topleft"
-     name="Remove Friend">
+     name="remove_friend">
         <menu_item_call.on_click
          function="Avatar.RemoveFriend" />
         <menu_item_call.on_enable
@@ -73,18 +73,28 @@
     <menu_item_call
      label="Invite to group..."
      layout="topleft"
-     name="Invite">
+     name="invite_to_group">
         <menu_item_call.on_click
          function="Avatar.InviteToGroup" />
         <menu_item_call.on_enable
       	 function="Avatar.EnableItem"
          parameter="can_invite"/>
     </menu_item_call>
-    <menu_item_separator />
+    <menu_item_separator name="separator_invite_to_group"/>
+    <menu_item_call
+     label="Zoom In"
+     layout="topleft"
+     name="zoom_in">
+      <menu_item_call.on_click
+       function="Avatar.ZoomIn" />
+      <menu_item_call.on_enable
+       function="Avatar.EnableItem"
+       parameter="can_zoom_in"/>
+    </menu_item_call>
     <menu_item_call
      label="Map"
      layout="topleft"
-     name="Map">
+     name="map">
         <menu_item_call.on_click
          function="Avatar.ShowOnMap" />
         <menu_item_call.on_enable
@@ -94,7 +104,7 @@
     <menu_item_call
      label="Share"
      layout="topleft"
-     name="Share">
+     name="share">
         <menu_item_call.on_click
          function="Avatar.Share" />
         <menu_item_call.on_enable
@@ -104,7 +114,7 @@
     <menu_item_call
      label="Pay"
      layout="topleft"
-     name="Pay">
+     name="pay">
         <menu_item_call.on_click
          function="Avatar.Pay" />
         <menu_item_call.on_enable
@@ -114,7 +124,7 @@
     <menu_item_check
      label="Block/Unblock"
      layout="topleft"
-     name="Block/Unblock">
+     name="block_unblock">
         <menu_item_check.on_click
          function="Avatar.BlockUnblock" />
         <menu_item_check.on_check
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
index 5d58a9d289..5f973088fd 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
@@ -6,7 +6,7 @@
      enabled="false"
      label="Add Friends"
      layout="topleft"
-     name="Add Friends">
+     name="add_friends">
         <on_click
          function="Avatar.AddFriends" />
         <on_enable
@@ -16,7 +16,7 @@
     <menu_item_call
      label="Remove Friends"
      layout="topleft"
-     name="Remove Friend">
+     name="remove_friends">
         <menu_item_call.on_click
          function="Avatar.RemoveFriend" />
         <menu_item_call.on_enable
@@ -26,7 +26,7 @@
     <menu_item_call
      label="IM"
      layout="topleft"
-     name="IM">
+     name="im">
         <on_click
          function="Avatar.IM" />
     </menu_item_call>
@@ -34,7 +34,7 @@
      enabled="false"
      label="Call"
      layout="topleft"
-     name="Call">
+     name="call">
         <on_click
          function="Avatar.Call" />
         <on_enable
@@ -45,7 +45,7 @@
      enabled="false"
      label="Share"
      layout="topleft"
-     name="Share">
+     name="share">
         <on_click
          function="Avatar.Share" />
     </menu_item_call>
@@ -53,13 +53,13 @@
      enabled="false"
      label="Pay"
      layout="topleft"
-     name="Pay">
+     name="pay">
         <on_click
          function="Avatar.Pay" />
     </menu_item_call>
     <menu_item_call
     label="Offer Teleport"
-    name="teleport">
+    name="offer_teleport">
       <menu_item_call.on_click
        function="Avatar.OfferTeleport"/>
       <menu_item_call.on_enable
-- 
cgit v1.2.3


From 3ee18d8b29caa612ee7656aa1ac69e3c1edce4cc Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Thu, 14 Mar 2013 11:28:56 +0200
Subject: CHUI-844 (Collapsed conversation panel auto expands when a new IM
 conversation starts) CHUI-713 ("Conversations" floater size doesn't persist
 between sessions)

---
 indra/newview/llfloaterimcontainer.cpp | 12 +-----------
 indra/newview/llfloaterimcontainer.h   |  1 -
 indra/newview/llimview.cpp             |  1 +
 3 files changed, 2 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 7437dd8cda..5f1b3dcfb1 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -62,8 +62,7 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param
 	mExpandCollapseBtn(NULL),
 	mConversationsRoot(NULL),
 	mConversationsEventStream("ConversationsEvents"),
-	mInitialized(false),
-	mIsFirstLaunch(false)
+	mInitialized(false)
 {
     mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
 	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction,  this, _2));
@@ -245,7 +244,6 @@ BOOL LLFloaterIMContainer::postBuild()
 	mGeneralTitle = getTitle();
 	
 	mInitialized = true;
-	mIsFirstLaunch = true;
 
 	// Add callbacks:
 	// We'll take care of view updates on idle
@@ -280,12 +278,6 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
 
 	LLUUID session_id = floaterp->getKey();
 	
-	// Make sure the message panel is open when adding a floater or it stays mysteriously hidden
-	if (!mIsFirstLaunch)
-	{
-		collapseMessagesPane(false);
-	}
-
 	// Add the floater
 	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
 
@@ -646,8 +638,6 @@ void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 		return;
 	}
 
-	mIsFirstLaunch = false;
-
 	// Save current width of panels before collapsing/expanding right pane.
 	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
     S32 msg_pane_width = mMessagesPane->getRect().getWidth();
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 5139651d8d..2cbc1e99f9 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -174,7 +174,6 @@ private:
 	LLLayoutStack* mConversationsStack;
 	
 	bool mInitialized;
-	bool mIsFirstLaunch;
 
 	LLUUID mSelectedSession;
 	std::string mGeneralTitle;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 8f3f5145a9..699e36db4f 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -285,6 +285,7 @@ void on_new_message(const LLSD& msg)
             {
 				//Surface conversations floater
 				LLFloaterReg::showInstance("im_container");
+				im_box->collapseMessagesPane(false);
 			}
 
             //If in DND mode, allow notification to be stored so upon DND exit 
-- 
cgit v1.2.3


From 780fe4e37fe5df4120ef4de09e6fc69f6184e4d3 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Fri, 15 Mar 2013 17:39:09 +0200
Subject: CHUI-831 ADD FIX Minimized conversation floater is not opened with
 Open Conversation Window preference if conversation receiving message is
 selected

---
 indra/newview/llimview.cpp | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a266f06a20..aadc61c4f5 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -287,9 +287,22 @@ void on_new_message(const LLSD& msg)
 				//Surface conversations floater
 				LLFloaterReg::showInstance("im_container");
 				im_box->collapseMessagesPane(false);
-				if (session_floater && session_floater->isMinimized())
+				if (session_floater)
 				{
-					LLFloater::onClickMinimize(session_floater);
+					if (session_floater->getHost())
+					{
+						if (NULL != im_box && im_box->isMinimized())
+						{
+							LLFloater::onClickMinimize(im_box);
+						}
+					}
+					else
+					{
+						if (session_floater->isMinimized())
+						{
+							LLFloater::onClickMinimize(session_floater);
+						}
+					}
 				}
 			}
 
-- 
cgit v1.2.3


From 242c39f24bc38ee306f1a9b4a173fd095fdab49d Mon Sep 17 00:00:00 2001
From: Merov Linden <merov@lindenlab.com>
Date: Fri, 15 Mar 2013 17:54:16 -0700
Subject: CHUI-807 : More defensive code. Don't assume anything while iterating
 through panels.

---
 indra/llui/lltabcontainer.cpp | 27 ++++++++++++++++-----------
 indra/newview/llimview.cpp    |  5 ++---
 2 files changed, 18 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 0c43a571b8..6f895ed939 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1483,16 +1483,22 @@ BOOL LLTabContainer::setTab(S32 which)
 		for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
 		{
 			LLTabTuple* tuple = *iter;
-			if (!tuple)
-				continue;
 			BOOL is_selected = ( tuple == selected_tuple );
-			tuple->mButton->setUseEllipses(mUseTabEllipses);
-			tuple->mButton->setHAlign(mFontHalign);
-			tuple->mTabPanel->setVisible( is_selected );
-// 			tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
-			tuple->mButton->setToggleState( is_selected );
-			// RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
-			tuple->mButton->setTabStop( is_selected );
+            
+            // Although the selected tab must be complete, we may have hollow LLTabTuple tucked in the list
+            if (tuple->mButton)
+            {
+                tuple->mButton->setUseEllipses(mUseTabEllipses);
+                tuple->mButton->setHAlign(mFontHalign);
+                tuple->mButton->setToggleState( is_selected );
+                // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
+                tuple->mButton->setTabStop( is_selected );
+            }
+            if (tuple->mTabPanel)
+            {
+                tuple->mTabPanel->setVisible( is_selected );
+                //tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
+            }
 			
 			if (is_selected)
 			{
@@ -1563,8 +1569,7 @@ BOOL LLTabContainer::selectTabByName(const std::string& name)
 	LLPanel* panel = getPanelByName(name);
 	if (!panel)
 	{
-		llwarns << "LLTabContainer::selectTabByName("
-			<< name << ") failed" << llendl;
+		llwarns << "LLTabContainer::selectTabByName(" << name << ") failed" << llendl;
 		return FALSE;
 	}
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index cd47a0c171..fbb3bd4a8e 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -641,8 +641,7 @@ void LLIMModel::LLIMSession::loadHistory()
 
 LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
 {
-	return get_if_there(mId2SessionMap, session_id,
-		(LLIMModel::LLIMSession*) NULL);
+	return get_if_there(mId2SessionMap, session_id, (LLIMModel::LLIMSession*) NULL);
 }
 
 //*TODO consider switching to using std::set instead of std::list for holding LLUUIDs across the whole code
@@ -2809,7 +2808,7 @@ LLUUID LLIMMgr::addSession(
 		}
 	}
 
-	bool new_session = !LLIMModel::getInstance()->findIMSession(session_id);
+	bool new_session = (LLIMModel::getInstance()->findIMSession(session_id) == NULL);
 
 	//works only for outgoing ad-hoc sessions
 	if (new_session && IM_SESSION_CONFERENCE_START == dialog && ids.size())
-- 
cgit v1.2.3


From 0a0ba068bf5bc6d829440a12946174c6ed961843 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Fri, 15 Mar 2013 18:16:44 -0700
Subject: CHUI-852 ([crashhunters] crash in
 LLNotificationsUI::LLScreenChannel::addToast): Crash is due to a gesture not
 loading while the user is shutting down the app. A notification saying that
 the gesture couldn't load is trying to display while the app is shutting
 down, which causes a crash.

---
 indra/newview/lldelayedgestureerror.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldelayedgestureerror.cpp b/indra/newview/lldelayedgestureerror.cpp
index 80e7c9f1b2..ef1b644ad4 100644
--- a/indra/newview/lldelayedgestureerror.cpp
+++ b/indra/newview/lldelayedgestureerror.cpp
@@ -113,9 +113,11 @@ bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
 		}
 	}
 	 
-
-	LLNotificationsUtil::add(ent.mNotifyName, args);
-
+	if(!LLApp::isQuitting())
+	{
+		LLNotificationsUtil::add(ent.mNotifyName, args);
+	}
+	
 	return true;
 }
 
-- 
cgit v1.2.3


From c294c7c4740e41c43b2b04f136cc909e37b28f7d Mon Sep 17 00:00:00 2001
From: merov <none@none>
Date: Sat, 16 Mar 2013 16:09:50 -0700
Subject: CHUI-863 : Clean up dead code that's creating failures on gcc-4.6
 builds on Linux

---
 indra/llrender/llgl.cpp           | 9 +--------
 indra/llui/lltextbase.cpp         | 1 -
 indra/newview/llchiclet.cpp       | 3 +++
 indra/newview/llviewerdisplay.cpp | 1 -
 indra/newview/llviewerwindow.cpp  | 2 --
 indra/newview/llworldmapview.cpp  | 3 ---
 6 files changed, 4 insertions(+), 15 deletions(-)

(limited to 'indra')

diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 9e4857b6bc..c8cf3713ab 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -597,11 +597,6 @@ bool LLGLManager::initGL()
 	if (mGLVendor.substr(0,4) == "ATI ")
 	{
 		mGLVendorShort = "ATI";
-		BOOL mobile = FALSE;
-		if (mGLRenderer.find("MOBILITY") != std::string::npos)
-		{
-			mobile = TRUE;
-		}
 		mIsATI = TRUE;
 
 #if LL_WINDOWS && !LL_MESA_HEADLESS
@@ -1489,9 +1484,7 @@ void assert_glerror()
 
 void clear_glerror()
 {
-	//  Create or update texture to be used with this data 
-	GLenum error;
-	error = glGetError();
+	glGetError();
 }
 
 ///////////////////////////////////////////////////////////////
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c4ec1edc73..ebc9ee244e 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -359,7 +359,6 @@ void LLTextBase::drawSelectionBackground()
 
 		S32 selection_left		= llmin( mSelectionStart, mSelectionEnd );
 		S32 selection_right		= llmax( mSelectionStart, mSelectionEnd );
-		LLRect selection_rect = mVisibleTextRect;
 
 		// Skip through the lines we aren't drawing.
 		LLRect content_display_rect = getVisibleDocumentRect();
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 3dbb43c657..b221daf936 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -427,6 +427,8 @@ LLChicletPanel::~LLChicletPanel()
 
 void LLChicletPanel::onMessageCountChanged(const LLSD& data)
 {
+    // *TODO : we either suppress this method or return a value. Right now, it servers no purpose.
+    /*
 	LLUUID session_id = data["session_id"].asUUID();
 	S32 unread = data["participant_unread"].asInteger();
 
@@ -435,6 +437,7 @@ void LLChicletPanel::onMessageCountChanged(const LLSD& data)
 	{
 		unread = 0;
 	}
+    */
 }
 
 void LLChicletPanel::objectChicletCallback(const LLSD& data)
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index ffeea2f4df..40577118ba 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1038,7 +1038,6 @@ void render_hud_attachments()
 	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
 	{
 		LLCamera hud_cam = *LLViewerCamera::getInstance();
-		LLVector3 origin = hud_cam.getOrigin();
 		hud_cam.setOrigin(-1.f,0,0);
 		hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
 		LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e44a2cc4df..4afd90b44c 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2827,7 +2827,6 @@ void LLViewerWindow::updateUI()
 
 	BOOL handled = FALSE;
 
-	BOOL handled_by_top_ctrl = FALSE;
 	LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
 	LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
 	LLView* captor_view = dynamic_cast<LLView*>(mouse_captor);
@@ -3012,7 +3011,6 @@ void LLViewerWindow::updateUI()
 				S32 local_x, local_y;
 				top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
 				handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask);
-				handled_by_top_ctrl = TRUE;
 			}
 
 			if ( !handled )
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index ccc513b80d..11b2770ec0 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -965,8 +965,6 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
 	S32 text_x = x;
 	S32 text_y = (S32)(y - sTrackCircleImage->getHeight()/2 - font->getLineHeight());
 
-	BOOL is_in_window = true;
-
 	if(    x < 0 
 		|| y < 0 
 		|| x >= getRect().getWidth() 
@@ -979,7 +977,6 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
 			text_x = sTrackingArrowX;
 			text_y = sTrackingArrowY;
 		}
-		is_in_window = false;
 	}
 	else if (LLTracker::getTrackingStatus() == LLTracker::TRACKING_LOCATION &&
 		LLTracker::getTrackedLocationType() != LLTracker::LOCATION_NOTHING)
-- 
cgit v1.2.3


From bc8ac5854f8b1eb9995139bb43cdf3b944030076 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 18 Mar 2013 14:37:21 +0200
Subject: CHUI-620 FIXED Clear the highlight when auto-selecting new
 conversation or when text is entered into the message panel.

---
 indra/newview/llfloaterimcontainer.cpp  | 2 +-
 indra/newview/llfloaterimnearbychat.cpp | 6 ++++++
 indra/newview/llfloaterimsession.cpp    | 5 +++++
 3 files changed, 12 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 1954f098b6..2fd8901d9e 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1418,7 +1418,7 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 			session_floater->setMinimized(is_minimized);
 		}
 	}
-
+	flashConversationItemWidget(session_id,false);
     return handled;
 }
 
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index a593fd4732..7c552f98e0 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -420,6 +420,12 @@ BOOL LLFloaterIMNearbyChat::matchChatTypeTrigger(const std::string& in_str, std:
 
 void LLFloaterIMNearbyChat::onChatBoxKeystroke()
 {
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->flashConversationItemWidget(mSessionID,false);
+	}
+
 	LLFirstUse::otherAvatarChatFirst(false);
 
 	LLWString raw_text = mInputEditor->getWText();
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 733678364e..73adfd0eda 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -892,6 +892,11 @@ void LLFloaterIMSession::onInputEditorFocusLost(LLFocusableElement* caller, void
 void LLFloaterIMSession::onInputEditorKeystroke(LLTextEditor* caller, void* userdata)
 {
 	LLFloaterIMSession* self = (LLFloaterIMSession*)userdata;
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->flashConversationItemWidget(self->mSessionID,false);
+	}
 	std::string text = self->mInputEditor->getText();
 
 		// Deleting all text counts as stopping typing.
-- 
cgit v1.2.3


From 8e1c21bf702c357528101c2073c2717a9b26880b Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 18 Mar 2013 14:51:38 +0200
Subject: CHUI-830 Icons uploaded

---
 .../skins/default/textures/icons/collapse_to_one_line.png | Bin 0 -> 538 bytes
 .../skins/default/textures/icons/expand_one_liner.png     | Bin 0 -> 545 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 indra/newview/skins/default/textures/icons/collapse_to_one_line.png
 create mode 100644 indra/newview/skins/default/textures/icons/expand_one_liner.png

(limited to 'indra')

diff --git a/indra/newview/skins/default/textures/icons/collapse_to_one_line.png b/indra/newview/skins/default/textures/icons/collapse_to_one_line.png
new file mode 100644
index 0000000000..d57144a645
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/collapse_to_one_line.png differ
diff --git a/indra/newview/skins/default/textures/icons/expand_one_liner.png b/indra/newview/skins/default/textures/icons/expand_one_liner.png
new file mode 100644
index 0000000000..58b7d90131
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/expand_one_liner.png differ
-- 
cgit v1.2.3


From a079acf1aa3b7cfe8ee35bb7afdbae83df0df5ca Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Mon, 18 Mar 2013 16:02:09 +0200
Subject: CHUI-861 FIXED "Animate" param is set false.

---
 indra/newview/skins/default/xui/en/floater_im_session.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 1a9199f9e7..6862788c65 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -73,7 +73,7 @@
         height="355"
         width="394">
    <layout_stack
-   animate="true" 
+   animate="false" 
    default_tab_group="2"
    follows="all"
   height="355"
-- 
cgit v1.2.3


From 22203b43db851a611adbaa2413bc92a14dd7f951 Mon Sep 17 00:00:00 2001
From: Cho <cho@lindenlab.com>
Date: Mon, 18 Mar 2013 20:06:25 +0100
Subject: CHUI-826 FIX [CHUIBUG]User nametags (nametag floaters) intermittently
 disappear in CHUI builds. Added check in LLVOAvatar::idleUpdateNameTagText()
 to account for case where mNameString is literally "" (two quotes)

---
 indra/newview/llvoavatar.cpp | 1 +
 1 file changed, 1 insertion(+)

(limited to 'indra')

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index c74d9f1292..d295fc60cd 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3097,6 +3097,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 
 	// Rebuild name tag if state change detected
 	if (mNameString.empty()
+		|| (mNameString.size() == 2 && mNameString[0] == 10 && mNameString[1] == 10) // *TODO : find out why mNameString is sometimes ""
 		|| new_name
 		|| (!title && !mTitle.empty())
 		|| (title && mTitle != title->getString())
-- 
cgit v1.2.3


From 73f68342f657984d6ab3447f3f9dbc44f35b1982 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Mon, 18 Mar 2013 15:56:50 -0700
Subject: CHUI-864 ([crashhunters] crash in LLConversationLog): Found a
 probable cause. It is likely that the user was missing the user settings
 variable called 'KeepConversationLogTranscripts.' If this variable doesn't
 exist or is deleted then the CHUI viewer would try to extract data from this
 non-existent variable. Resolution, now perform a check to make sure the
 'KeepConversationLogTranscripts' settings variable exists before extracting
 data.

---
 indra/newview/llconversationlog.cpp | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index dd20ca15ae..7883e4cb89 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -194,14 +194,17 @@ LLConversationLog::LLConversationLog() :
 	mAvatarNameCacheConnection(),
 	mLoggingEnabled(false)
 {
-	LLControlVariable * keep_log_ctrlp = gSavedPerAccountSettings.getControl("KeepConversationLogTranscripts").get();
-	S32 log_mode = keep_log_ctrlp->getValue();
-	keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
-	if (log_mode > 0)
+	if(gSavedPerAccountSettings.controlExists("KeepConversationLogTranscripts"))
 	{
-		loadFromFile(getFileName());
+		LLControlVariable * keep_log_ctrlp = gSavedPerAccountSettings.getControl("KeepConversationLogTranscripts").get();
+		S32 log_mode = keep_log_ctrlp->getValue();
+		keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+		if (log_mode > 0)
+		{
+			loadFromFile(getFileName());
 
-		enableLogging(log_mode);
+			enableLogging(log_mode);
+		}
 	}
 }
 
-- 
cgit v1.2.3


From 0c5ff7eb4870ac2ec933bd624e6969dbea862dbb Mon Sep 17 00:00:00 2001
From: mberezhnoy <mberezhnoy@productengine.com>
Date: Tue, 19 Mar 2013 10:57:38 +0200
Subject: CHUI-812 ([CHUIBUG]Resizing "Nearby chat" window creates confusing
 layout)

---
 indra/newview/skins/default/xui/en/floater_im_session.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 6862788c65..c42e58a9f4 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -227,7 +227,7 @@
       width="150" 
       height="275" 
       user_resize="true"
-      auto_resize="true">
+      auto_resize="false">
       </layout_panel>
     <layout_panel
        default_tab_group="3"
-- 
cgit v1.2.3


From c4f283334c9ee6abff7253d8024f3b1870b342f3 Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 19 Mar 2013 11:34:13 -0700
Subject: CHUI 796 (User doesn't get all messages in 'do not disturb' mode):
 Now IM DND notifications will be stored as p2p, ad-hoc or group. When loading
 these notifications upon app start ad-hoc/group notifications will launch the
 conversation log and play a sound.

---
 .../newview/lldonotdisturbnotificationstorage.cpp  | 25 ++++++++++++++++++++--
 indra/newview/llimview.cpp                         |  2 ++
 2 files changed, 25 insertions(+), 2 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 22f35752bd..be20adeb8a 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -33,6 +33,7 @@
 #include "lldir.h"
 #include "llerror.h"
 #include "llfloaterreg.h"
+#include "llimview.h"
 #include "llnotifications.h"
 #include "llnotificationhandler.h"
 #include "llnotificationstorage.h"
@@ -145,6 +146,8 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 	
 	LLNotifications& instance = LLNotifications::instance();
     bool imToastExists = false;
+	bool group_ad_hoc_toast_exists = false;
+	S32 toastSessionType;
     bool offerExists = false;
 	
 	for (LLSD::array_const_iterator notification_it = data.beginArray();
@@ -158,7 +161,20 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
 
         if(notificationName == toastName)
         {
-            imToastExists = true;
+			toastSessionType = notification_params["payload"]["SESSION_TYPE"];
+			if(toastSessionType == LLIMModel::LLIMSession::P2P_SESSION)
+			{
+				imToastExists = true;
+			}
+			//Don't add group/ad-hoc messages to the notification system because
+			//this means the group/ad-hoc session has to be re-created
+			else if(toastSessionType == LLIMModel::LLIMSession::GROUP_SESSION 
+					|| toastSessionType == LLIMModel::LLIMSession::ADHOC_SESSION)
+			{
+				//Just allows opening the conversation log for group/ad-hoc messages upon startup
+				group_ad_hoc_toast_exists = true;
+				continue;
+			}
         }
         else if(notificationName == offerName)
         {
@@ -197,7 +213,12 @@ void LLDoNotDisturbNotificationStorage::loadNotifications()
         LLFloaterReg::showInstance("im_container");
     }
 
-    if(imToastExists || offerExists)
+	if(group_ad_hoc_toast_exists)
+	{
+		LLFloaterReg::showInstance("conversation");
+	}
+
+    if(imToastExists || group_ad_hoc_toast_exists || offerExists)
     {
 		make_ui_sound_deferred("UISndNewIncomingIMSession");
     }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 10e214bc90..8c862548bb 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -154,6 +154,7 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	args["FROM"] = av_name.getCompleteName();
 	args["FROM_ID"] = msg["from_id"];
 	args["SESSION_ID"] = msg["session_id"];
+	args["SESSION_TYPE"] = msg["session_type"];
 	LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
@@ -1008,6 +1009,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
 	arg["from"] = from;
 	arg["from_id"] = from_id;
 	arg["time"] = LLLogChat::timestamp(false);
+	arg["session_type"] = session->mSessionType;
 	mNewMsgSignal(arg);
 
 	return true;
-- 
cgit v1.2.3


From 2a8baeed3a2dc67abff131249aa23538e76fb05d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Tue, 19 Mar 2013 16:46:04 -0700
Subject: CHUI-843 ([CHUIBUG]Suggested alteration to toolbar_panel in
 floater_im_container in CHUI): Adjusted button layout in conversation
 floater.

---
 indra/newview/skins/default/xui/en/floater_im_container.xml | 10 +++++-----
 indra/newview/skins/default/xui/en/floater_im_session.xml   | 12 ++++++------
 2 files changed, 11 insertions(+), 11 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 12c1676127..65f623a47e 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -61,7 +61,7 @@
                      image_unselected="Toolbar_Middle_Off"
                      menu_filename="menu_participant_view.xml"
                      layout="topleft"
-                     left="10"
+                     left="5"
                      name="sort_btn"
                      tool_tip="View/sort options"
                      top="5"
@@ -75,7 +75,7 @@
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
                      top="5"
-                     left_pad="4"
+                     left_pad="2"
                      name="add_btn"
                      tool_tip="Start a new conversation"
                      width="31"/>
@@ -88,7 +88,7 @@
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
                      top="5"
-                     left_pad="4"
+                     left_pad="2"
                      name="speak_btn"
                      tool_tip="Speak with people using your microphone"
                      width="31"/>	
@@ -114,7 +114,7 @@
                 </layout_panel>
             </layout_stack>
             <panel
-             bottom="-5"
+             bottom="-1"
              follows="all"
              layout="topleft"
              name="conversations_list_panel"
@@ -129,7 +129,7 @@
          name="messages_layout_panel"
          expanded_min_dim="222">
             <panel_container
-             bottom="-5"
+             bottom="-1"
              follows="all"
              layout="topleft"
              left="0"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 6862788c65..56a1b35caf 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -118,7 +118,7 @@
 				 image_unselected="Toolbar_Middle_Off"
 				 layout="topleft"
 			 	 top="5"
-			 	 left_pad="4"
+			 	 left_pad="2"
 				 name="gear_btn"
 				 visible="false"
 				 tool_tip="Actions on selected person"
@@ -133,7 +133,7 @@
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  top="5"
-                 left_pad="4"
+                 left_pad="2"
                  name="add_btn"
                  tool_tip="Add someone to this conversation"
                  width="31"/>
@@ -146,7 +146,7 @@
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  top="5"
-                 left_pad="4"
+                 left_pad="2"
                  name="voice_call_btn"
                  tool_tip="Open voice connection"
                  width="31"/>
@@ -171,7 +171,7 @@
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  top="5"
-                 left="283"
+                 left="292"
                  name="close_btn"
                  tool_tip="End this conversation"
                  width="31" />
@@ -184,7 +184,7 @@
              	 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  top="5"
-                 left_pad="5"
+                 left_pad="2"
                  name="expand_collapse_btn"
                  tool_tip="Collapse/Expand this pane"
                  width="31" />
@@ -197,7 +197,7 @@
              	 image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  top="5"
-                 left_pad="5"
+                 left_pad="2"
                  name="tear_off_btn"
                  width="31" />
      </layout_panel>
-- 
cgit v1.2.3


From 5187f5b41f8b748dd7f092d97e69f24a4c43f4ee Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 20 Mar 2013 15:08:02 +0200
Subject: CHUI-869 FIXED Clicking on toast will restore Message pane.

---
 indra/newview/llfloaterimnearbychat.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 7c552f98e0..3af3c65045 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -348,6 +348,11 @@ bool LLFloaterIMNearbyChat::isChatVisible() const
 void LLFloaterIMNearbyChat::showHistory()
 {
 	openFloater();
+	if(!isMessagePaneExpanded())
+	{
+		restoreFloater();
+		setFocus(true);
+	}
 	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
 }
 
-- 
cgit v1.2.3


From 78e0dc5aa3650c74aade364b7be4669d58fe8316 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 20 Mar 2013 15:30:27 +0200
Subject: CHUI-860 FIXED Don't call onSlide() to change Participant list's
 state

---
 indra/newview/llfloaterimsessiontab.cpp | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index cfd239c22f..4ae00fcd5f 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -802,18 +802,12 @@ void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)
 	LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost());
 	if (!host_floater)
 	{
-		if(self->mParticipantListPanel->getVisible())
-		{
-			onSlide(self);
-		}
-
 		bool expand = self->isMessagePaneExpanded();
 		self->mExpandCollapseLineBtn->setImageOverlay(self->getString(expand ? "collapseline_icon" : "expandline_icon"));
 		self->mContentPanel->setVisible(!expand);
 		self->mToolbarPanel->setVisible(!expand);
 		self->reshapeFloater(expand);
 		self->setMessagePaneExpanded(!expand);
-
 	}
 }
 
-- 
cgit v1.2.3


From cee1a311ad218c6d5ed8ae9924624d959b6be6a0 Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 20 Mar 2013 15:41:57 +0200
Subject: CHUI-870 FIXED Expand Message panel after clicking toast.

---
 indra/newview/llfloaterimcontainer.cpp  | 3 +++
 indra/newview/llfloaterimsessiontab.cpp | 4 ++++
 indra/newview/llfloaterimsessiontab.h   | 2 +-
 3 files changed, 8 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2fd8901d9e..5e0cd8ef78 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1329,6 +1329,9 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
 {
     setVisibleAndFrontmost(false);
     selectConversationPair(session_id, true);
+
+    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+    session_floater->restoreFloater();
 }
 
 void LLFloaterIMContainer::clearAllFlashStates()
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 4ae00fcd5f..5df1a382cd 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -838,6 +838,10 @@ void LLFloaterIMSessionTab::restoreFloater()
 {
 	if(!isMessagePaneExpanded())
 	{
+		if(isMinimized())
+		{
+			setMinimized(false);
+		}
 		mContentPanel->setVisible(true);
 		mToolbarPanel->setVisible(true);
 		LLRect floater_rect = getRect();
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index e41f639037..f22e2b5744 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -100,6 +100,7 @@ public:
 	virtual BOOL handleKeyHere( KEY key, MASK mask );
 	bool isMessagePaneExpanded(){return mMessagePaneExpanded;}
 	void setMessagePaneExpanded(bool expanded){mMessagePaneExpanded = expanded;}
+	void restoreFloater();
 
 protected:
 
@@ -115,7 +116,6 @@ protected:
 	static void onSlide(LLFloaterIMSessionTab *self);
 	static void onCollapseToLine(LLFloaterIMSessionTab *self);
 	void reshapeFloater(bool collapse);
-	void restoreFloater();
 
 	// refresh a visual state of the Call button
 	void updateCallBtnState(bool callIsActive);
-- 
cgit v1.2.3


From a48cd164a20734722e25592f5cf22c8344dd4860 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Wed, 20 Mar 2013 21:51:36 +0200
Subject: CHUI-857 Nearby chat opens as torn off on first login: changed
 initial setting for nearby chat docked state

---
 indra/newview/app_settings/settings_per_account.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 47137c8de9..ada374f892 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -290,7 +290,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>ShowFavoritesOnLogin</key>
         <map>
-- 
cgit v1.2.3


From 4a2fb4c64f2079089b78202e53bbe1dbe8ac09c7 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Wed, 20 Mar 2013 22:27:16 +0200
Subject: CHUI-873 FIXED [CHUIBUG]Torn off nearby chat with message panel
 hidden has huge bottom padding when opening in mouselook mode

---
 indra/newview/llfloaterimnearbychat.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 3af3c65045..b287950c21 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -739,7 +739,14 @@ void LLFloaterIMNearbyChat::startChat(const char* line)
 	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 	if (nearby_chat)
 	{
-		nearby_chat->show();
+		if(!nearby_chat->isTornOff())
+		{
+			nearby_chat->show();
+		}
+		if(nearby_chat->isMinimized())
+		{
+			nearby_chat->setMinimized(false);
+		}
 		nearby_chat->setVisible(TRUE);
 		nearby_chat->setFocus(TRUE);
 		nearby_chat->mInputEditor->setFocus(TRUE);
-- 
cgit v1.2.3


From 1df1ce7a31df77743675899d4a15458ac84a281a Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 21 Mar 2013 15:57:44 +0200
Subject: CHUI-858 FIXED Text can be clipped by text input bar in message panel

---
 indra/newview/skins/default/xui/en/floater_im_session.xml | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index e081ea8e74..1ad54bdb6b 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -266,6 +266,7 @@
           left="0">
             <layout_panel
              auto_resize="false"
+             user_resize="false"
              height="26"
              layout="topleft"
              left_delta="0"
@@ -285,7 +286,6 @@
                  width="230" />
             </layout_panel>
             <layout_panel
-             height="233"
              width="210"
              layout="topleft"
              follows="all"
@@ -293,19 +293,21 @@
              top_delta="0"
              bottom="0"
              visible="true"
-             user_resize="true"
+             user_resize="false"
              auto_resize="true"
              name="chat_holder">      
                <chat_history
                 font="SansSerifSmall"
                 follows="all"
                 visible="true"
-                height="225"
                 name="chat_history"
                 parse_highlights="true"
                 parse_urls="true"
+                layout="topleft"
                 right="-5"
-                left="5">
+                left="5"
+                top="0"
+                bottom="1">
                </chat_history>
             </layout_panel>
            </layout_stack>
@@ -348,7 +350,6 @@
              auto_resize="true"
              name="input_editor_layout_panel">
               <chat_editor
-             top="6"
              expand_lines_count="5"
              follows="left|right|bottom"
                font="SansSerifSmall"
@@ -363,6 +364,7 @@
              spellcheck="true"
              tab_group="3"
              width="160"
+             top="6"
              left="5"
              right="-5"
              wrap="true">
-- 
cgit v1.2.3


From 9887daa3e3224b00ffc46ce69604b3227b14637c Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Thu, 21 Mar 2013 18:04:10 +0200
Subject: CHUI-880 FIXED Show Button panel if floater is torned off. Don't show
 Conversation floater in Mouselook, if Nearby chat is torned off.

---
 indra/newview/llfloaterimsessiontab.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 5df1a382cd..7b50ce5ae2 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -30,6 +30,7 @@
 #include "llfloaterimsessiontab.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llavataractions.h"
 #include "llchatentry.h"
 #include "llchathistory.h"
@@ -125,8 +126,12 @@ void LLFloaterIMSessionTab::setVisible(BOOL visible)
 	if(visible && !mHasVisibleBeenInitialized)
 	{
 		mHasVisibleBeenInitialized = true;
-		LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);
+		if(!gAgentCamera.cameraMouselook())
+		{
+			LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);
+		}
 		LLFloaterIMSessionTab::addToHost(mSessionID);
+		mInputButtonPanel->setVisible(isTornOff());
 	}
 
 	LLTransientDockableFloater::setVisible(visible);
-- 
cgit v1.2.3


From 4d9e3e159e63a0317a069c9d74c6904d5b222537 Mon Sep 17 00:00:00 2001
From: maksymsproductengine <maksymsproductengine@lindenlab.com>
Date: Thu, 21 Mar 2013 18:29:18 +0200
Subject: CHUI-855 FIXED Text entry bar auto expand does not resize

---
 indra/newview/llfloaterimsessiontab.cpp | 20 ++++++++++----------
 indra/newview/llfloaterimsessiontab.h   |  5 +++--
 2 files changed, 13 insertions(+), 12 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 7b50ce5ae2..0dd61568f9 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -58,11 +58,12 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
   , mSpeakingIndicator(NULL)
   , mChatHistory(NULL)
   , mInputEditor(NULL)
-  , mInputEditorTopPad(0)
+  , mInputEditorPad(0)
   , mRefreshTimer(new LLTimer())
   , mIsHostAttached(false)
   , mHasVisibleBeenInitialized(false)
   , mIsParticipantListExpanded(true)
+  , mChatLayoutPanel(NULL)
 {
     setAutoFocus(FALSE);
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
@@ -237,12 +238,15 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
 	mInputEditor = getChild<LLChatEntry>("chat_editor");
-	mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatHistory, this));
+
+	mChatLayoutPanel = getChild<LLLayoutPanel>("chat_layout_panel");
+	
+	mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatLayoutPanel, this));
 	mInputEditor->setCommitOnFocusLost( FALSE );
 	mInputEditor->setPassDelete(TRUE);
 	mInputEditor->setFont(LLViewerChat::getChatFont());
 
-	mInputEditorTopPad = mChatHistory->getRect().mBottom - mInputEditor->getRect().mTop;
+	mInputEditorPad = mChatLayoutPanel->getRect().getHeight() - mInputEditor->getRect().getHeight();
 
 	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 
@@ -708,15 +712,11 @@ void LLFloaterIMSessionTab::forceReshape()
 }
 
 
-void LLFloaterIMSessionTab::reshapeChatHistory()
+void LLFloaterIMSessionTab::reshapeChatLayoutPanel()
 {
-	LLRect chat_rect  = mChatHistory->getRect();
+	LLRect chat_layout_panel_rect = mChatLayoutPanel->getRect();
 	LLRect input_rect = mInputEditor->getRect();
-
-	int delta_height = chat_rect.mBottom - (input_rect.mTop + mInputEditorTopPad);
-
-	chat_rect.setLeftTopAndSize(chat_rect.mLeft, chat_rect.mTop, chat_rect.getWidth(), chat_rect.getHeight() + delta_height);
-	mChatHistory->setShape(chat_rect);
+	mChatLayoutPanel->reshape(chat_layout_panel_rect.getWidth(), input_rect.getHeight() + mInputEditorPad, FALSE);
 }
 
 void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index f22e2b5744..e9393c5336 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -168,7 +168,8 @@ protected:
     LLOutputMonitorCtrl* mSpeakingIndicator;
 	LLChatHistory* mChatHistory;
 	LLChatEntry* mInputEditor;
-	int mInputEditorTopPad; // padding between input field and chat history
+	LLLayoutPanel * mChatLayoutPanel;
+	int mInputEditorPad; // padding between input field and chat history
 
 	LLButton* mExpandCollapseLineBtn;
 	LLButton* mExpandCollapseBtn;
@@ -195,7 +196,7 @@ private:
 	 * and avoid overlapping, since input chat field can be vertically expanded.
 	 * Implementation: chat history bottom "follows" top+top_pad of input chat field
 	 */
-	void reshapeChatHistory();
+	void reshapeChatLayoutPanel();
 
 	bool checkIfTornOff();
     bool mIsHostAttached;
-- 
cgit v1.2.3


From bbfd1c0f2d89de50c0c0e026208036e2bc963104 Mon Sep 17 00:00:00 2001
From: AlexanderP ProductEngine <apaschenko@productengine.com>
Date: Thu, 21 Mar 2013 18:44:01 +0200
Subject: CHUI-878 FIXED Torn off conversation window width can be reduced and
 lose vertical scroll bar: manually setting of the floater's minimal size

---
 indra/newview/llfloaterimsessiontab.cpp            | 50 +++++++++++++++++-----
 indra/newview/llfloaterimsessiontab.h              |  5 +++
 .../skins/default/xui/en/floater_im_session.xml    |  8 ++--
 3 files changed, 49 insertions(+), 14 deletions(-)

(limited to 'indra')

diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 0dd61568f9..eab2ce7798 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -196,12 +196,29 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 	}
 }
 
+void LLFloaterIMSessionTab::assignResizeLimits()
+{
+	bool is_participants_pane_collapsed = mParticipantListPanel->isCollapsed();
+
+    // disable a layoutstack's functionality when participant list panel is collapsed
+	mRightPartPanel->setIgnoreReshape(is_participants_pane_collapsed);
+
+    S32 participants_pane_target_width = is_participants_pane_collapsed?
+    		0 : (mParticipantListPanel->getRect().getWidth() + LLPANEL_BORDER_WIDTH);
+
+    S32 new_min_width = participants_pane_target_width + mRightPartPanel->getExpandedMinDim() + mFloaterExtraWidth;
+
+	setResizeLimits(new_min_width, getMinHeight());
+
+	this->mParticipantListAndHistoryStack->updateLayout();
+}
+
 BOOL LLFloaterIMSessionTab::postBuild()
 {
 	BOOL result;
 
 	mBodyStack = getChild<LLLayoutStack>("main_stack");
-
+    mParticipantListAndHistoryStack = getChild<LLLayoutStack>("im_panels");
 
 	mCloseBtn = getChild<LLButton>("close_btn");
 	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
@@ -218,6 +235,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mGearBtn = getChild<LLButton>("gear_btn");
 
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
+	mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder");
+
 	mToolbarPanel = getChild<LLLayoutPanel>("toolbar_panel");
 	mContentPanel = getChild<LLLayoutPanel>("body_panel");
 	mInputButtonPanel = getChild<LLLayoutPanel>("input_button_layout_panel");
@@ -297,6 +316,15 @@ BOOL LLFloaterIMSessionTab::postBuild()
 		LLFloaterIMSessionTab::onSlide(this);
 	}
 
+	// The resize limits for LLFloaterIMSessionTab should be updated, based on current values of width of conversation and message panels
+	mParticipantListPanel->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMSessionTab::assignResizeLimits, this));
+	mFloaterExtraWidth =
+			getRect().getWidth()
+			- mParticipantListAndHistoryStack->getRect().getWidth()
+			- (mParticipantListPanel->isCollapsed()? 0 : LLPANEL_BORDER_WIDTH);
+
+	assignResizeLimits();
+
 	return result;
 }
 
@@ -669,8 +697,7 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 			&& mIsParticipantListExpanded
 			&& !mIsP2PChat;
 
-	mParticipantListPanel->setVisible(is_participant_list_visible);
-
+	mParticipantListAndHistoryStack->collapsePanel(mParticipantListPanel, !is_participant_list_visible);
 
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
@@ -791,15 +818,18 @@ void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
 	{
 		if (!self->mIsP2PChat)
 		{
-			bool expand = !self->mParticipantListPanel->getVisible();
-
-			// Expand/collapse the IM control panel
-			self->mParticipantListPanel->setVisible(expand);
-            gSavedSettings.setBOOL("IMShowControlPanel", expand);
-            self->mIsParticipantListExpanded = expand;
-			self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon"));
+            bool should_be_expanded = self->mParticipantListPanel->isCollapsed();
+
+			// Expand/collapse the participant list panel
+            self->mParticipantListAndHistoryStack->collapsePanel(self->mParticipantListPanel, !should_be_expanded);
+            self->mParticipantListPanel->setVisible(should_be_expanded);
+            gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);
+            self->mIsParticipantListExpanded = should_be_expanded;
+			self->mExpandCollapseBtn->setImageOverlay(self->getString(should_be_expanded ? "collapse_icon" : "expand_icon"));
 		}
 	}
+
+	self->assignResizeLimits();
 }
 
 void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index e9393c5336..f0899a3c09 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -140,6 +140,9 @@ protected:
 	void appendMessage(const LLChat& chat, const LLSD &args = 0);
 
 	std::string appendTime();
+	void assignResizeLimits();
+
+	S32  mFloaterExtraWidth;
 
 	bool mIsNearbyChat;
 	bool mIsP2PChat;
@@ -155,7 +158,9 @@ protected:
 	
 	LLUUID mSessionID; 
 	LLLayoutStack* mBodyStack;
+	LLLayoutStack* mParticipantListAndHistoryStack;
 	LLLayoutPanel* mParticipantListPanel;	// add the widgets to that see mConversationsListPanel
+	LLLayoutPanel* mRightPartPanel;
 	LLLayoutPanel* mContentPanel;
 	LLLayoutPanel* mToolbarPanel;
 	LLLayoutPanel* mInputButtonPanel;
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 1ad54bdb6b..d8b085063f 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -14,7 +14,6 @@
  width="394"
  can_resize="true"
  can_tear_off="false"
- min_width="340"
  min_height="190"
  positioning="relative">
     <floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string>
@@ -223,9 +222,10 @@
     <layout_panel
       name="speakers_list_panel"
       follows="all"
-      min_width="115"
+      expanded_min_dim="115"
+      min_dim="0"
       width="150" 
-      height="275" 
+      height="275"
       user_resize="true"
       auto_resize="false">
       </layout_panel>
@@ -241,7 +241,7 @@
        user_resize="true"
        auto_resize="true"
        visible="true"
-       name="left_part_holder"
+       name="right_part_holder"
        min_width="221">
         <panel
          name="trnsAndChat_panel"
-- 
cgit v1.2.3


From abf1bf79f2d45ba42389397f9013d5552f7d672d Mon Sep 17 00:00:00 2001
From: Gilbert Gonzales <gilbert@lindenlab.com>
Date: Thu, 21 Mar 2013 16:16:54 -0700
Subject: CHUI-881 ([CHUIBUG]Viewer crashes when user drag and drop the
 participant from the people floater to the one of the tool bars): Problem was
 that the item dragged from the people list was not of type inventoryitem.
 Instead of casting to an inventoryitem and checking if the item being dragged
 is a widgit, instead look at the cargo type (which also specifies that the
 dragged item is a widgit but doesn't need to typecast).

---
 indra/llui/lltoolbar.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

(limited to 'indra')

diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index b9256dd890..1c74395c66 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -1059,10 +1059,9 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	// Convert drag position into insert position and rank 
 	if (!isReadOnly() && handled && !drop)
 	{
-		LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
-		LLAssetType::EType type = inv_item->getType();
-		if (type == LLAssetType::AT_WIDGET)
+		if (cargo_type == DAD_WIDGET)
 		{
+			LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
 			LLCommandId dragged_command(inv_item->getUUID());
 			int orig_rank = getRankFromPosition(dragged_command);
 			mDragRank = getRankFromPosition(x, y);
-- 
cgit v1.2.3